October 29, 2020
On 10/28/20 6:28 PM, IGotD- wrote:
> On Wednesday, 28 October 2020 at 21:54:19 UTC, Jan Hönig wrote:
>>
>> shared immutable x = 1;
>>
> 
> Is there a point to add shared to an immutable? Aren't immutable implicitly also shared?

You are correct:

pragma(msg, typeof(x)); // immutable(int)

D frequently allows no-op attributes.

-Steve
October 29, 2020
On Thu, Oct 29, 2020 at 09:50:28AM -0400, Steven Schveighoffer via Digitalmars-d-learn wrote: [...]
> D frequently allows no-op attributes.
[...]

I find that to be a bad smell in terms of language design, actually. Either something should be allowed and have a definite effect, or it should not be allowed.  Not this murky grey area where you can write something and it seems to be allowed, but doesn't actually have any effect.


T

-- 
One reason that few people are aware there are programs running the internet is that they never crash in any significant way: the free software underlying the internet is reliable to the point of invisibility. -- Glyn Moody, from the article "Giving it all away"
October 29, 2020
On 10/29/20 10:39 AM, H. S. Teoh wrote:
> On Thu, Oct 29, 2020 at 09:50:28AM -0400, Steven Schveighoffer via Digitalmars-d-learn wrote:
> [...]
>> D frequently allows no-op attributes.
> [...]
> 
> I find that to be a bad smell in terms of language design, actually.
> Either something should be allowed and have a definite effect, or it
> should not be allowed.  Not this murky grey area where you can write
> something and it seems to be allowed, but doesn't actually have any
> effect.

I think it's to aid in things like:

@safe:

// lots of things, but only functions are tagged as @safe

-Steve

October 29, 2020
On Thu, Oct 29, 2020 at 11:00:42AM -0400, Steven Schveighoffer via Digitalmars-d-learn wrote:
> On 10/29/20 10:39 AM, H. S. Teoh wrote:
> > On Thu, Oct 29, 2020 at 09:50:28AM -0400, Steven Schveighoffer via Digitalmars-d-learn wrote: [...]
> > > D frequently allows no-op attributes.
> > [...]
> > 
> > I find that to be a bad smell in terms of language design, actually. Either something should be allowed and have a definite effect, or it should not be allowed.  Not this murky grey area where you can write something and it seems to be allowed, but doesn't actually have any effect.
> 
> I think it's to aid in things like:
> 
> @safe:
> 
> // lots of things, but only functions are tagged as @safe
[...]

But why can't that be treated differently from explicitly writing @safe on a declaration?  I mean, yeah, it's easier to implement the compiler that way, but ease of implementation shouldn't count against proper language design!


T

-- 
Doubt is a self-fulfilling prophecy.
October 29, 2020
On 10/28/20 5:55 PM, matheus wrote:
> On Wednesday, 28 October 2020 at 22:07:06 UTC, H. S. Teoh wrote:
>> ... (This is why it's a bad idea to use enum with an array literal, because every time it's referenced you get a new copy of the array.)
>> ...
> 
> Could you please give an example (Snippet) about this?
> 
> Matheus.

An amusing proof:


void main() {
  enum arr = [ 1 ];
  assert(arr.ptr != arr.ptr); // Passes :)
}

Ali
October 29, 2020
On 10/28/20 3:07 PM, H. S. Teoh wrote:

> A shared immutable is initialized at compile-time,

To prevent a misunderstanding, immutable can be initialized at run time as well. On the other hand, immutable initialized at compile time was surprising to me when I learned it recently:

import std;

immutable string p;

shared static this() {
  p = environment["PATH"];  // <-- Run time
}

// Ali learned this relatively recently
// (immutable at compile time):
immutable lines = import("myfile.txt").splitter('\n').array;
pragma(msg, lines);

void main() {
}

Ali
October 29, 2020
On Thursday, 29 October 2020 at 16:45:51 UTC, Ali Çehreli wrote:
>
> import std;
>
> immutable string p;
>
> shared static this() {
>   p = environment["PATH"];  // <-- Run time
> }
>

Just to clarify, immutable is allowed to be initialized in ctors but not anything later than that? Moving p = environment["PATH"] to main would generate an error.

October 29, 2020
On Thu, Oct 29, 2020 at 04:56:46PM +0000, IGotD- via Digitalmars-d-learn wrote:
> On Thursday, 29 October 2020 at 16:45:51 UTC, Ali Çehreli wrote:
> > 
> > import std;
> > 
> > immutable string p;
> > 
> > shared static this() {
> >   p = environment["PATH"];  // <-- Run time
> > }
> > 
> 
> Just to clarify, immutable is allowed to be initialized in ctors but not anything later than that? Moving p = environment["PATH"] to main would generate an error.

1) Module-level immutable can be initialized either as part of the declaration:

	immutable int x = 1;

2) Or from inside a shared static this():

	immutable int x;
	shared static this() {
		x = 2;
	}

Note that initialization from ctor must be done from `shared static this()`, which is global; initialization from `static this` is currently accepted but deprecated, because that's a TLS ctor, and immutables are implicitly shared so you could potentially break immutability by having the TLS ctor set it to a different value per thread.  Eventually this will become a hard error.

The following are errors:

3)
	immutable int x = 1;
	shared static this() {
		x = 2; // NG: cannot modify immutable
	}

4)
	immutable int x;
	void main() {
		x = 3; // NG: cannot modify immutable
	}


T

-- 
Lottery: tax on the stupid. -- Slashdotter
October 29, 2020
On Thursday, 29 October 2020 at 16:31:41 UTC, Ali Çehreli wrote:
> On 10/28/20 5:55 PM, matheus wrote:
>> On Wednesday, 28 October 2020 at 22:07:06 UTC, H. S. Teoh wrote:
>>> ... (This is why it's a bad idea to use enum with an array literal, because every time it's referenced you get a new copy of the array.)
>>> ...
>> 
>> Could you please give an example (Snippet) about this?
>> 
>> Matheus.
>
> An amusing proof:
>
>
> void main() {
>   enum arr = [ 1 ];
>   assert(arr.ptr != arr.ptr); // Passes :)
> }
>
> Ali

Did you just violate the law of identity 👍
October 29, 2020
On 10/29/20 10:16 AM, H. S. Teoh wrote:

> Module-level immutable can be initialized either as part of the
> declaration:
>
> 	immutable int x = 1;

To add, the expression can be a call to a function that need not return immutable, as long as it is pure, which can be inferred by the compiler for templates. Phew! :)

pure char[] makeMutableString() {
  return "hello".dup;
}

// This works because makeMutableString() is 'pure', i.e. 'i' cannot
// share mutable data.
immutable i = makeMutableString();

void main() {
}

So, instead of adding 'pure' to makeMutableString() like above, one can add another set of parethesis to make it a template. (Two characters instead of four! Win! :p)

char[] makeMutableString()() {
  return "hello".dup;
}

Ali