On 11/16/2011 02:22 PM, Steven Schveighoffer wrote:
On Tue, 15 Nov 2011 13:45:02 -0500, Timon Gehr <timon.g...@gmx.ch> wrote:

On 11/15/2011 04:53 PM, Steven Schveighoffer wrote:

Yes, but this is spelled out because copying a static array requires
moving data. However, this does *not* require a hidden allocation (even
though it does do a hidden allocation currently).

I'm not worried about copying data as much as I am about hidden
allocations. Hidden allocations are a huge drag on performance. Every
time you allocate, you need to take a global GC lock, and it's an
unbounded operation (doing one allocation could run a collection cycle).

You don't actually _need_ a global GC lock. It is just how it is
implemented in this case.

This is all fine in theory. I haven't seen any implementations. But
memory allocations are not cheap, even without a GC lock.

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.


That is the idea. Get rid of the hidden allocation. Writeln *is* const
correct, it can certainly print immutable(int)[].

Well, there is a function called writeln that can do that. That is a
different function. But the one that gets actually called is not const
correct as well.


This is writeln:

// Most general instance
void writeln(T...)(T args)
if (T.length > 1 || T.length == 1 && !is(typeof(args[0]) :
const(char)[]))
{
stdout.write(args, '\n');
}


=>
writeln([1,2,3]);
// modulo IFTY:
writeln!(int[])([1,2,3]);
// const correct?
writeln!(int[])([1,2,3].idup); // nope!

Error: cannot implicitly convert expression (_adDupT(&
_D11TypeInfo_Ai6__initZ,[1,2,3])) of type immutable(int)[] to int[]

I'm not sure what this means. If [1, 2, 3] is typed as immtuable(int)[],
it will compile.

Simple test:

immutable(int)[] a = [1, 2, 3];
writeln(a);

works with 2.056.

That is like saying

void foo(int[] a){...}             // prints a
void bar(immutable(int)[] a){...}  // prints a

int[] a = [1,2,3];
immutable(int)[] b = [1, 2, 3];
foo(a);
bar(b);

"=> Oh, bar is const correct because I can call foo with mutable data and bar with immutable data."

foo is writeln!(int[])
bar is writeln!(immutable(int)[])

in effect, if you do:

writeln("hello".dup);

The compiler cannot assume that the IFTI'd writeln!(char[]) will not change the argument, ergo it cannot optimize away the .dup, even though it would be a valid transformation as long as the programmer does not make the program semantics depend on the identity relation on immutable references (doing so defeats the purpose of immutability).



The issue is not
writeln, it's what the type of the array literal/enum is.


Technically, an array literal is equivalent to an enum, and should
follow the same rules.


Remember that immutable is transitive. That can really get in your way
in this case.

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.






Reply via email to