Mutable enums

Steven Schveighoffer schveiguy at yahoo.com
Wed Nov 16 13:56:21 PST 2011


On Wed, 16 Nov 2011 16:16:48 -0500, Timon Gehr <timon.gehr at gmx.ch> wrote:

> On 11/16/2011 09:00 PM, Steven Schveighoffer wrote:
>> On Wed, 16 Nov 2011 14:26:57 -0500, Timon Gehr <timon.gehr at gmx.ch>  
>> wrote:
>>
>>> On 11/16/2011 02:22 PM, Steven Schveighoffer wrote:
>>>> On Tue, 15 Nov 2011 13:45:02 -0500, Timon Gehr <timon.gehr at gmx.ch>
>>>> wrote:
>>>>
>>>>> Note that this is an explicit allocation:
>>>>>
>>>>> int[] a = [1,2,3]; // just as explicit as a NewExpression
>>>>>
>>>>> Only the enums "hide" it sometimes, but actually you should know the
>>>>> involved types.
>>>>
>>>> As I've said, there are already ways to explicitly allocate memory. A
>>>> suggested replacement for this is:
>>>>
>>>> int[] a = array(1, 2, 3);
>>>>
>>>> And you could always do:
>>>>
>>>> int[] a = [1, 2, 3].dup;
>>>>
>>>> Nobody complains about having to do:
>>>>
>>>> char[] a = "hello".dup;
>>>>
>>>> I don't see why we couldn't do the same for all array literals.
>>>>
>>>
>>> Because 'immutable' behaves nicely on built-in value types, but not on
>>> arbitrary reference types.
>>
>> string is a reference type. We hear no complaints about strings being
>> stored in ROM and the type of literals being immutable.
>>
>
> string is not an immutable type. It is immutable(char)[] and char is a  
> built-in value type.
>
> static assert(isMutable!string);

It fits my definition of a valid enum reference type (immutable or  
implicitly castable to immutable).  The point is that the data referenced  
is stored in ROM and therefore a) immutable and b) fully defined at  
compile-time.

>> Make no mistake, this doesn't cover every current instance array
>> literals, such as ones which contain necessarily-heap-allocated
>> entities. Those would be covered by a library function (e.g.
>> array(...)). But those are not array literals anyways, they are
>> constructors.
>>
>
> It is true that they are constructors, but they are currently also  
> called array literals.

I'm looking to redefine what a literal means in D.

>>
>> writeln is not contractually const correct, but that's only because most
>> of D is not const correct either. For example, Object.toString is not
>> const, so if you const-ified all writeln args, you couldn't print
>> objects. But writeln itself does not change any data (a rogue toString
>> might change data, but that is not common practice).
>>
>> Once D becomes const correct, writeln *can* apply const to all it's
>> parameters.
>
> Ok, I see. writeln still could be const-correct in principle. It would  
> need to apply const to the parameters that have a const toString method.  
> But the language is not powerful enough to do that. There is no way to  
> intercept IFTI... I am commonly missing that feature.

I have an enhancement request in for intercepting IFTI (not sure if it  
applies here): http://d.puremagic.com/issues/show_bug.cgi?id=4998

>>
>>>> If the data is stored in ROM, it should be typed as immutable. If it's
>>>> not, then it could be modified. The only other option is heap  
>>>> allocation
>>>> and construction on use, which I've already said is undesirable.
>>>>
>>>> If we start from "all array literals and enums that contain references
>>>> store the referenced data in ROM," then we will find ways to deal with
>>>> any inconveniences. It's all a matter of what's more important in a
>>>> system language, performance or convenience.
>>>
>>> Both are more important. It is D.
>>> Everything you need to do is make the enum static immutable instead.
>>> D is also a scripting language and an application programming language.
>>>
>>> auto a = [new Foo, new Bar, new Qux]; // I want that to work.
>>
>> auto a = array(new Foo, new Bar, new Qux);
>>
>
> Requiring that works modulo template bloat and breakage of existing  
> code. Also, it does not really buy us anything imho.

I think the bloat is a wash.  Every time I use an array literal, there is  
a complete instantiation of what would be in an array template inline in  
the calling function.

Yes, it breaks code.  It's worth it.  To avoid a heap allocation for [1,  
2, 3] is worth breaking code that uses runtime data in an array literal.   
The compiler can be helpful in the error message:

Error somefile.d(345): array literals cannot contain runtime data.  Maybe  
you meant:
  array(new Foo, new Bar, new Qux);

I want to point out that currently there is *NO* way to make an immutable  
array literal that lives in ROM.  This is unacceptable.

-Steve


More information about the Digitalmars-d-learn mailing list