Re: Array literals' default type

2009-10-14 Thread Don

Ellery Newcomer wrote:

Bill Baxter wrote:

foo((1,2)); // um, what?

You see that kind of thing in Python all the time, with NumPy at
least.  Array dimensions for example are set with a tuple.  So
   x = array((1,2), dtype=int)
And very common to see things like numpy.zeros((10,20)).


This is one place [of many] where you can't say, Oh, leave off the
parens and it's a comma exp. That leaves me in the lurch.


When offered semantic ambiguity, just say no.

You didn't really show any examples of ambiguity that I could see.
Some of those examples may have a legal meaning in C, so that's an
issue if so.



If you try to add tuple expressions AND keep comma expressions, you
either can't recurse from paren exp to comma exp (or any exp, really) or
you have semantic ambiguity. If you can't recurse comma exps, they're
nothing more than semicolons. Worthless, so you might as well remove them.

Or you have to introduce a new syntax.

aside

Actually, making comma exp a little uglier might be an appealing
solution. something like

CommaExp - , CommaExp
CommaExp - AsgExp

gives you

auto a = (,1,2); // a = 2
auto a = (1,2); // a = (1,2)

You still have the problem of ( nonCommaExp ), though. And
user-friendliness issues.

I'm sure others could think of better ideas.


You do NOT need to keep the comma operator. What you do need to do, 
though, is make sure that any use of , doesn't silently produce 
different behaviour to what it would do in C.


Re: Array literals' default type

2009-10-13 Thread Ellery Newcomer
Bill Baxter wrote:
 foo((1,2)); // um, what?
 
 You see that kind of thing in Python all the time, with NumPy at
 least.  Array dimensions for example are set with a tuple.  So
x = array((1,2), dtype=int)
 And very common to see things like numpy.zeros((10,20)).

This is one place [of many] where you can't say, Oh, leave off the
parens and it's a comma exp. That leaves me in the lurch.

 
 When offered semantic ambiguity, just say no.
 
 You didn't really show any examples of ambiguity that I could see.
 Some of those examples may have a legal meaning in C, so that's an
 issue if so.
 

If you try to add tuple expressions AND keep comma expressions, you
either can't recurse from paren exp to comma exp (or any exp, really) or
you have semantic ambiguity. If you can't recurse comma exps, they're
nothing more than semicolons. Worthless, so you might as well remove them.

Or you have to introduce a new syntax.

aside

Actually, making comma exp a little uglier might be an appealing
solution. something like

CommaExp - , CommaExp
CommaExp - AsgExp

gives you

auto a = (,1,2); // a = 2
auto a = (1,2); // a = (1,2)

You still have the problem of ( nonCommaExp ), though. And
user-friendliness issues.

I'm sure others could think of better ideas.


Re: Array literals' default type

2009-10-12 Thread Don

language_fan wrote:

Sat, 10 Oct 2009 17:15:55 +0200, Yigal Chripun thusly wrote:


Now, wouldn't it be wonderful if D had provided real tuple support
without all the Tuple!() nonsense?


'D has full built-in tuple support' has been the answer each time I've 
asked. It seems not to be advisable to ask more about this specific 
feature since the language creators easily get annoyed when asked about 
this. They see more value in reserving the syntax for the C style 
sequencing operator which is rarely used. Also they have apparently 
scientifically proven that the auto-flattening semantics of tuples 
somehow works better than real product types, and have no intention to 
make it an explicit controllable operation, which is also easily 
implementable.


Not so, Andrei has said that he thinks auto-flattening was a bad idea. 
And AFAIK, Walter doesn't disagree.


Andrei and I, and almost everyone else, have tried to persuade Walter to 
remove the comma operator, but without success. But I doubt you'd be 
able to use it for tuples, because   x, y = foo(); already has meaning 
in C and tuples would give it a different meaning. I'd LOVE to be proved 
wrong.


It is very difficult to change Walter's mind about many things, but 
despite what people say, it is not impossible.


Re: Array literals' default type

2009-10-12 Thread grauzone

Don wrote:
Not so, Andrei has said that he thinks auto-flattening was a bad idea. 
And AFAIK, Walter doesn't disagree.


You should try harder, because if you don't change it soon, it will be 
there forever due to compatibility requirements.


Andrei and I, and almost everyone else, have tried to persuade Walter to 
remove the comma operator, but without success. But I doubt you'd be 
able to use it for tuples, because   x, y = foo(); already has meaning 
in C and tuples would give it a different meaning. I'd LOVE to be proved 
wrong.


Wasn't the comma operator to be supposed to be important for automatic 
code generation?


Even if it is, you could just pick a different token to implement this 
operator. It doesn't have to be a comma, does it?


It is very difficult to change Walter's mind about many things, but 
despite what people say, it is not impossible.


Re: Array literals' default type

2009-10-12 Thread Don

grauzone wrote:

Don wrote:
Not so, Andrei has said that he thinks auto-flattening was a bad idea. 
And AFAIK, Walter doesn't disagree.


You should try harder, because if you don't change it soon, it will be 
there forever due to compatibility requirements.


The TODO list is very long.

Andrei and I, and almost everyone else, have tried to persuade Walter 
to remove the comma operator, but without success. But I doubt you'd 
be able to use it for tuples, because   x, y = foo(); already has 
meaning in C and tuples would give it a different meaning. I'd LOVE to 
be proved wrong.


Wasn't the comma operator to be supposed to be important for automatic 
code generation?


It's used frequently in in the compiler internals. EG, given

int foo(X x = default_value) { return 0; }
then foo(); becomes:   (X tmp = default_value, foo(tmp));

I don't think it sees much use outside of compilers. There are other 
ways to get the same effect in user code.


Even if it is, you could just pick a different token to implement this 
operator. It doesn't have to be a comma, does it?


It doesn't need any syntax at all, when it's inside the compiler.
But the problem is, that comma has that meaning in C.

(OTOH I wonder how much extant C++ code uses the comma operator. I bet 
there's not much of it. (But more than code than uses octal!)).



BTW as an asm programmer, I'm completely baffled as to why the concept 
of 'single return value from a function' became dominant in programming 
languages. It's a very unnatural restriction from a machine point of view.


Re: Array literals' default type

2009-10-12 Thread Phil Deets

On Mon, 12 Oct 2009 09:47:34 -0500, Don nos...@nospam.com wrote:

(OTOH I wonder how much extant C++ code uses the comma operator. I bet  
there's not much of it. (But more than code than uses octal!)).


Boost Assign uses the comma operator.  
http://www.boost.org/doc/libs/1_40_0/libs/assign/doc/index.html#operator+=


However, the C++ code

vectorint values;
values += 1,2,3,4,5,6,7,8,9;

could be translated to

int[] values;
values ~= [1,2,3,4,5,6,7,8,9];

in D so no comma operator would be needed there.


--
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/


Re: Array literals' default type

2009-10-12 Thread Bill Baxter
On Mon, Oct 12, 2009 at 9:42 AM, Phil Deets pjdee...@gmail.com wrote:
 On Mon, 12 Oct 2009 09:47:34 -0500, Don nos...@nospam.com wrote:

 (OTOH I wonder how much extant C++ code uses the comma operator. I bet
 there's not much of it. (But more than code than uses octal!)).

There are quite a few uses out there if you count for-loop clauses and
stuff hidden in macros.

I think it probably isn't possible to have
  a, b  = foo();
be valid D syntax with the Don't re-interpret valid C constraint.
But perhaps a slight variation like this could work:
  (a, b)  = foo();

--bb


Re: Array literals' default type

2009-10-12 Thread Jarrett Billingsley
On Mon, Oct 12, 2009 at 10:47 AM, Don nos...@nospam.com wrote:

 Wasn't the comma operator to be supposed to be important for automatic
 code generation?

 It's used frequently in in the compiler internals. EG, given

 int foo(X x = default_value) { return 0; }
 then foo(); becomes:   (X tmp = default_value, foo(tmp));

There doesn't need to be any *syntactic* reservation for something
that's used internally by the compiler. I mean, we don't have to
explicitly mark which brace blocks introduce scopes, but
ScopeStatements are alive and well inside the compiler. CommaExp could
just become SequenceExp or something and it would have the exact
same effect. I really don't think there will be a lot of moaning if
comma expressions disappeared. And yes, for loop increments can be
special-cased, geez..


Re: Array literals' default type

2009-10-12 Thread language_fan
Mon, 12 Oct 2009 13:04:03 -0400, Jarrett Billingsley thusly wrote:

 On Mon, Oct 12, 2009 at 10:47 AM, Don nos...@nospam.com wrote:
 
 Wasn't the comma operator to be supposed to be important for automatic
 code generation?

 It's used frequently in in the compiler internals. EG, given

 int foo(X x = default_value) { return 0; } then foo(); becomes:   (X
 tmp = default_value, foo(tmp));
 
 There doesn't need to be any *syntactic* reservation for something
 that's used internally by the compiler. I mean, we don't have to
 explicitly mark which brace blocks introduce scopes, but ScopeStatements
 are alive and well inside the compiler. CommaExp could just become
 SequenceExp or something and it would have the exact same effect. I
 really don't think there will be a lot of moaning if comma expressions
 disappeared. And yes, for loop increments can be special-cased, geez..

But it breaks the holy C compatibility. When a C veteran with 40+ years 
of C development experience under their belt studies D by porting a 1 
MLOC library to D 2.0, his code will fail as the precious old comma does 
not compute sequencing, but instead will produce a nasty compile error. 
Porting the code in a single go will not be possible anymore and reddit 
commentators will literally crush D.


Re: Array literals' default type

2009-10-12 Thread Jarrett Billingsley
On Mon, Oct 12, 2009 at 1:21 PM, language_fan f...@bar.com.invalid wrote:
 Mon, 12 Oct 2009 13:04:03 -0400, Jarrett Billingsley thusly wrote:

 On Mon, Oct 12, 2009 at 10:47 AM, Don nos...@nospam.com wrote:

 Wasn't the comma operator to be supposed to be important for automatic
 code generation?

 It's used frequently in in the compiler internals. EG, given

 int foo(X x = default_value) { return 0; } then foo(); becomes:   (X
 tmp = default_value, foo(tmp));

 There doesn't need to be any *syntactic* reservation for something
 that's used internally by the compiler. I mean, we don't have to
 explicitly mark which brace blocks introduce scopes, but ScopeStatements
 are alive and well inside the compiler. CommaExp could just become
 SequenceExp or something and it would have the exact same effect. I
 really don't think there will be a lot of moaning if comma expressions
 disappeared. And yes, for loop increments can be special-cased, geez..

 But it breaks the holy C compatibility. When a C veteran with 40+ years
 of C development experience under their belt studies D by porting a 1
 MLOC library to D 2.0, his code will fail as the precious old comma does
 not compute sequencing, but instead will produce a nasty compile error.
 Porting the code in a single go will not be possible anymore and reddit
 commentators will literally crush D.


Fuck C.


Re: Array literals' default type

2009-10-12 Thread Ary Borenszweig

language_fan wrote:

Mon, 12 Oct 2009 13:04:03 -0400, Jarrett Billingsley thusly wrote:


On Mon, Oct 12, 2009 at 10:47 AM, Don nos...@nospam.com wrote:


Wasn't the comma operator to be supposed to be important for automatic
code generation?

It's used frequently in in the compiler internals. EG, given

int foo(X x = default_value) { return 0; } then foo(); becomes:   (X
tmp = default_value, foo(tmp));

There doesn't need to be any *syntactic* reservation for something
that's used internally by the compiler. I mean, we don't have to
explicitly mark which brace blocks introduce scopes, but ScopeStatements
are alive and well inside the compiler. CommaExp could just become
SequenceExp or something and it would have the exact same effect. I
really don't think there will be a lot of moaning if comma expressions
disappeared. And yes, for loop increments can be special-cased, geez..


But it breaks the holy C compatibility. When a C veteran with 40+ years 
of C development experience under their belt studies D by porting a 1 
MLOC library to D 2.0, his code will fail as the precious old comma does 
not compute sequencing, but instead will produce a nasty compile error. 
Porting the code in a single go will not be possible anymore and reddit 
commentators will literally crush D.


What is it with C compatibility? Can't you link C functions and you are 
done? What's the compulsive need to port everything written in C or C++ 
to D?


Re: Array literals' default type

2009-10-12 Thread Yigal Chripun

On 12/10/2009 15:43, Don wrote:

language_fan wrote:

Sat, 10 Oct 2009 17:15:55 +0200, Yigal Chripun thusly wrote:


Now, wouldn't it be wonderful if D had provided real tuple support
without all the Tuple!() nonsense?


'D has full built-in tuple support' has been the answer each time I've
asked. It seems not to be advisable to ask more about this specific
feature since the language creators easily get annoyed when asked
about this. They see more value in reserving the syntax for the C
style sequencing operator which is rarely used. Also they have
apparently scientifically proven that the auto-flattening semantics of
tuples somehow works better than real product types, and have no
intention to make it an explicit controllable operation, which is also
easily implementable.


Not so, Andrei has said that he thinks auto-flattening was a bad idea.
And AFAIK, Walter doesn't disagree.

Andrei and I, and almost everyone else, have tried to persuade Walter to
remove the comma operator, but without success. But I doubt you'd be
able to use it for tuples, because x, y = foo(); already has meaning in
C and tuples would give it a different meaning. I'd LOVE to be proved
wrong.

It is very difficult to change Walter's mind about many things, but
despite what people say, it is not impossible.


what's wrong with enclosing tuples in parenthesis?
(x, y) = foo();

int foo();
int bar();

int a = foo(), bar(); // sequence
int b, c;
(b, c) = (foo(), bar()); // tuples
b, c = foo(), bar(); // sequence
(b, c) = foo(), bar(); // error assigning int to (int, int)
b, c = (foo(), bar()); // error assigning (int, int) to int




Re: Array literals' default type

2009-10-12 Thread Lars T. Kyllingstad

Don wrote:
BTW as an asm programmer, I'm completely baffled as to why the concept 
of 'single return value from a function' became dominant in programming 
languages. It's a very unnatural restriction from a machine point of view.



I'd guess it is because of the close relationship between programming 
and mathematics.


-Lars


Re: Array literals' default type

2009-10-12 Thread Yigal Chripun

On 12/10/2009 23:00, Yigal Chripun wrote:

On 12/10/2009 15:43, Don wrote:

language_fan wrote:

Sat, 10 Oct 2009 17:15:55 +0200, Yigal Chripun thusly wrote:


Now, wouldn't it be wonderful if D had provided real tuple support
without all the Tuple!() nonsense?


'D has full built-in tuple support' has been the answer each time I've
asked. It seems not to be advisable to ask more about this specific
feature since the language creators easily get annoyed when asked
about this. They see more value in reserving the syntax for the C
style sequencing operator which is rarely used. Also they have
apparently scientifically proven that the auto-flattening semantics of
tuples somehow works better than real product types, and have no
intention to make it an explicit controllable operation, which is also
easily implementable.


Not so, Andrei has said that he thinks auto-flattening was a bad idea.
And AFAIK, Walter doesn't disagree.

Andrei and I, and almost everyone else, have tried to persuade Walter to
remove the comma operator, but without success. But I doubt you'd be
able to use it for tuples, because x, y = foo(); already has meaning in
C and tuples would give it a different meaning. I'd LOVE to be proved
wrong.

It is very difficult to change Walter's mind about many things, but
despite what people say, it is not impossible.


what's wrong with enclosing tuples in parenthesis?
(x, y) = foo();

int foo();
int bar();

int a = foo(), bar(); // sequence
int b, c;
(b, c) = (foo(), bar()); // tuples
b, c = foo(), bar(); // sequence
(b, c) = foo(), bar(); // error assigning int to (int, int)
b, c = (foo(), bar()); // error assigning (int, int) to int




one more note:

there's no need to special case the for loop.

for (int i = 0, j = 0; someCondition; i++, j--) {...}
  ~~~^
the above will continue to work whether it's a tuple or a C sequence.





Re: Array literals' default type

2009-10-12 Thread Steven Schveighoffer
On Mon, 12 Oct 2009 14:27:21 -0400, Jarrett Billingsley  
jarrett.billings...@gmail.com wrote:


On Mon, Oct 12, 2009 at 1:21 PM, language_fan f...@bar.com.invalid  
wrote:

Mon, 12 Oct 2009 13:04:03 -0400, Jarrett Billingsley thusly wrote:


On Mon, Oct 12, 2009 at 10:47 AM, Don nos...@nospam.com wrote:

Wasn't the comma operator to be supposed to be important for  
automatic

code generation?


It's used frequently in in the compiler internals. EG, given

int foo(X x = default_value) { return 0; } then foo(); becomes:   (X
tmp = default_value, foo(tmp));


There doesn't need to be any *syntactic* reservation for something
that's used internally by the compiler. I mean, we don't have to
explicitly mark which brace blocks introduce scopes, but  
ScopeStatements

are alive and well inside the compiler. CommaExp could just become
SequenceExp or something and it would have the exact same effect. I
really don't think there will be a lot of moaning if comma expressions
disappeared. And yes, for loop increments can be special-cased, geez..


But it breaks the holy C compatibility. When a C veteran with 40+ years
of C development experience under their belt studies D by porting a 1
MLOC library to D 2.0, his code will fail as the precious old comma does
not compute sequencing, but instead will produce a nasty compile error.
Porting the code in a single go will not be possible anymore and reddit
commentators will literally crush D.



Fuck C.


Jarrett, I think you lost the sarcasm in his post :)

-Steve


Re: Array literals' default type

2009-10-12 Thread Ellery Newcomer
Yigal Chripun wrote:

 what's wrong with enclosing tuples in parenthesis?
 (x, y) = foo();

I'm guessing you'd end up with some weird rules

z = foo(); // what is z, a tuple, or y?

auto (a,b) = ((1,2),(3,4)); // eh, what is this?

foo((1,2)); // um, what?

When offered semantic ambiguity, just say no.


 int foo();
 int bar();

 int a = foo(), bar(); // sequence
 int b, c;
 (b, c) = (foo(), bar()); // tuples
 b, c = foo(), bar(); // sequence
 (b, c) = foo(), bar(); // error assigning int to (int, int)
 b, c = (foo(), bar()); // error assigning (int, int) to int


 
 one more note:
 
 there's no need to special case the for loop.
 
 for (int i = 0, j = 0; someCondition; i++, j--) {...}
   ~~~^
 the above will continue to work whether it's a tuple or a C sequence.
 
 
 

How about this?

OtherTypeIwant foo(out bool flag){...}

...

while(guardflag  (x=foo(f), f)){
...
}


Just checked, still have something like this in my code.


Re: Array literals' default type

2009-10-12 Thread Bill Baxter
On Mon, Oct 12, 2009 at 5:20 PM, Ellery Newcomer
ellery-newco...@utulsa.edu wrote:
 Yigal Chripun wrote:

 what's wrong with enclosing tuples in parenthesis?
 (x, y) = foo();

 I'm guessing you'd end up with some weird rules

 z = foo(); // what is z, a tuple, or y?

What's weird there?  z is whatever type it was declared to be.

 auto (a,b) = ((1,2),(3,4)); // eh, what is this?

That's pretty easy to figure out.  Why would it be anything other than
a=(1,2)  b=(3,4) ?

 foo((1,2)); // um, what?

You see that kind of thing in Python all the time, with NumPy at
least.  Array dimensions for example are set with a tuple.  So
   x = array((1,2), dtype=int)
And very common to see things like numpy.zeros((10,20)).

 When offered semantic ambiguity, just say no.

You didn't really show any examples of ambiguity that I could see.
Some of those examples may have a legal meaning in C, so that's an
issue if so.


 int foo();
 int bar();

 int a = foo(), bar(); // sequence
 int b, c;
 (b, c) = (foo(), bar()); // tuples
 b, c = foo(), bar(); // sequence
 (b, c) = foo(), bar(); // error assigning int to (int, int)
 b, c = (foo(), bar()); // error assigning (int, int) to int



 one more note:

 there's no need to special case the for loop.

 for (int i = 0, j = 0; someCondition; i++, j--) {...}
                                       ~~~^
 the above will continue to work whether it's a tuple or a C sequence.




 How about this?

 OtherTypeIwant foo(out bool flag){...}

 ...

 while(guardflag  (x=foo(f), f)){
 ...
 }


 Just checked, still have something like this in my code.

That actual code would still be ok because I don't think it wouldn't
be legal to do  on a tuple.  Or if so then the result would be a
tuple, and then the while would barf.   So it wouldn't compile and
you'd find the porting error.

--bb


Re: Array literals' default type

2009-10-10 Thread Don

Christopher Wright wrote:

Don wrote:

I don't understand why runtime-determined array literals even exist.
They're not literals!!!
They cause no end of trouble. IMHO we'd be *much* better off without 
them.


You don't see the use. I do. I would go on a murderous rampage if that 
feature were removed from the language.


For example, one thing I recently wrote involved creating a process with 
a large number of arguments. The invocation looked like:
exec(description, [procName, arg1, arg2] ~ generatedArgs ~ [arg3, 
arg4] ~ moreGeneratedArgs);


There were about ten or fifteen lines like that.

You'd suggest I rewrite that how?
char[][] args;
args ~= procName;
args ~= arg1;
args ~= arg2;
args ~= generatedArgs;
args ~= arg3;


Of course not. These runtime 'array literals' are just syntax sugar for 
a constructor call. Really, they are nothing more.

At worst, it would be something like:

exec(description, createArray(procName, arg1, arg2) ~ generatedArgs ~ 
createArray(arg3, arg4) ~ moreGeneratedArgs);


Depending on what the 'exec' signature is, it could be simpler than 
that. But that's the absolute worst case.


The language pays a heavy price for that little bit of syntax sugar.



Re: Array literals' default type

2009-10-10 Thread Yigal Chripun

On 10/10/2009 10:11, Don wrote:

Christopher Wright wrote:

Don wrote:

I don't understand why runtime-determined array literals even exist.
They're not literals!!!
They cause no end of trouble. IMHO we'd be *much* better off without
them.


You don't see the use. I do. I would go on a murderous rampage if that
feature were removed from the language.

For example, one thing I recently wrote involved creating a process
with a large number of arguments. The invocation looked like:
exec(description, [procName, arg1, arg2] ~ generatedArgs ~ [arg3,
arg4] ~ moreGeneratedArgs);

There were about ten or fifteen lines like that.

You'd suggest I rewrite that how?
char[][] args;
args ~= procName;
args ~= arg1;
args ~= arg2;
args ~= generatedArgs;
args ~= arg3;


Of course not. These runtime 'array literals' are just syntax sugar for
a constructor call. Really, they are nothing more.
At worst, it would be something like:

exec(description, createArray(procName, arg1, arg2) ~ generatedArgs ~
createArray(arg3, arg4) ~ moreGeneratedArgs);

Depending on what the 'exec' signature is, it could be simpler than
that. But that's the absolute worst case.

The language pays a heavy price for that little bit of syntax sugar.



You keep calling these literals constructor calls' and I agree that 
that's what they are. My question is then why not make them real 
constructors?


auto a = new int[](x, y, z);
auto b = new int[3](x, y, z);
auto c = new int[]; // empty array
auto d = new int[3]; // use default ctor: d == [0,0,0]

for arrays of class instances this could be extended to call a 
constructor for each index, something like:


// tuples would be very handy here..
auto e = new Class[2](Tuple!(args1), Tuple!(args2));



Re: Array literals' default type

2009-10-10 Thread Christopher Wright

Don wrote:

Christopher Wright wrote:

Don wrote:

I don't understand why runtime-determined array literals even exist.
They're not literals!!!
They cause no end of trouble. IMHO we'd be *much* better off without 
them.


You don't see the use. I do. I would go on a murderous rampage if that 
feature were removed from the language.


For example, one thing I recently wrote involved creating a process 
with a large number of arguments. The invocation looked like:
exec(description, [procName, arg1, arg2] ~ generatedArgs ~ [arg3, 
arg4] ~ moreGeneratedArgs);


There were about ten or fifteen lines like that.

You'd suggest I rewrite that how?
char[][] args;
args ~= procName;
args ~= arg1;
args ~= arg2;
args ~= generatedArgs;
args ~= arg3;


Of course not. These runtime 'array literals' are just syntax sugar for 
a constructor call. Really, they are nothing more.


I'm quite surprised that there is a runtime function for this. I would 
expect codegen to emit something like:


array = __d_newarray(nBytes)
array[0] = exp0
array[1] = exp1
...


At worst, it would be something like:

exec(description, createArray(procName, arg1, arg2) ~ generatedArgs ~ 
createArray(arg3, arg4) ~ moreGeneratedArgs);


PHP does this. I haven't used PHP enough to hate it.

Depending on what the 'exec' signature is, it could be simpler than 
that. But that's the absolute worst case.


The language pays a heavy price for that little bit of syntax sugar.


The price being occasional heap allocation where it's unnecessary? The 
compiler should be able to detect this in many cases and allocate on the 
stack instead. Your createArray() suggestion doesn't have that advantage.


Or parsing difficulties? It's not an insanely difficult thing to parse, 
and people writing parsers for D comprise an extremely small segment of 
your audience.


Or just having another construct to know? Except in PHP, you can't use 
arrays without knowing about the array() function, and in D, you can't 
easily use arrays without knowing about array literals. So it's the same 
mental load.


You could say array() is more self-documenting, but that's only when you 
want someone who has no clue what D is to read your code. I think it's 
reasonable to require people to know what an array literal is.


What is the price?


Re: Array literals' default type

2009-10-10 Thread Jarrett Billingsley
On Sat, Oct 10, 2009 at 7:33 AM, Yigal Chripun yigal...@gmail.com wrote:

 You keep calling these literals constructor calls' and I agree that that's
 what they are. My question is then why not make them real constructors?

 auto a = new int[](x, y, z);

Teehee, that syntax already has meaning in D. Well, that right there
would give you a semantic error, but new int[][][](x, y, z) creates
a 3-D array with dimensions x, y, and z.

That brings up another point. If you *did* use a class-style ctor
syntax, how would you list the arguments for a multidimensional array?
That is, what would be the equivalent of [[1, 2], [3, 4]]?


Re: Array literals' default type

2009-10-10 Thread Lars T. Kyllingstad

Christopher Wright wrote:

Don wrote:

Christopher Wright wrote:

Don wrote:

I don't understand why runtime-determined array literals even exist.
They're not literals!!!
They cause no end of trouble. IMHO we'd be *much* better off without 
them.


You don't see the use. I do. I would go on a murderous rampage if 
that feature were removed from the language.


For example, one thing I recently wrote involved creating a process 
with a large number of arguments. The invocation looked like:
exec(description, [procName, arg1, arg2] ~ generatedArgs ~ [arg3, 
arg4] ~ moreGeneratedArgs);


There were about ten or fifteen lines like that.

You'd suggest I rewrite that how?
char[][] args;
args ~= procName;
args ~= arg1;
args ~= arg2;
args ~= generatedArgs;
args ~= arg3;


Of course not. These runtime 'array literals' are just syntax sugar 
for a constructor call. Really, they are nothing more.


I'm quite surprised that there is a runtime function for this. I would 
expect codegen to emit something like:


array = __d_newarray(nBytes)
array[0] = exp0
array[1] = exp1
...


At worst, it would be something like:

exec(description, createArray(procName, arg1, arg2) ~ generatedArgs 
~ createArray(arg3, arg4) ~ moreGeneratedArgs);


PHP does this. I haven't used PHP enough to hate it.



I've used PHP a fair bit, and I don't hate its array syntax at all. 
(There are plenty of other things in PHP to hate, though.) It's easily 
readable, and not much of a hassle to write. But array() in PHP isn't a 
function, it's a language construct with special syntax. To create an 
AA, for instance, you'd write


  $colours = array(apple = red, pear = green);

I'm not sure what the D equivalent of that one should be.

-Lars


Re: Array literals' default type

2009-10-10 Thread Michel Fortin
On 2009-10-10 12:12:27 -0400, Lars T. Kyllingstad 
pub...@kyllingen.nospamnet said:



Christopher Wright wrote:

Don wrote:

At worst, it would be something like:

exec(description, createArray(procName, arg1, arg2) ~ generatedArgs ~ 
createArray(arg3, arg4) ~ moreGeneratedArgs);


PHP does this. I haven't used PHP enough to hate it.



I've used PHP a fair bit, and I don't hate its array syntax at all. 
(There are plenty of other things in PHP to hate, though.) It's easily 
readable, and not much of a hassle to write. But array() in PHP isn't a 
function, it's a language construct with special syntax. To create an 
AA, for instance, you'd write


   $colours = array(apple = red, pear = green);

I'm not sure what the D equivalent of that one should be.


Associative array literals:

string[string] s = [hello: world, foo: bar];

Note that an array in PHP is always a double-linked list indexed by a 
hash-table. Writing `array(1, 2, 3)` is the same as writing `array(0 = 
1, 1 = 2, 2 = 3)`: what gets constructed is identical. That's quite 
nice as a generic container.




--
Michel Fortin
michel.for...@michelf.com
http://michelf.com/



Re: Array literals' default type

2009-10-10 Thread Lars T. Kyllingstad

Michel Fortin wrote:
On 2009-10-10 12:12:27 -0400, Lars T. Kyllingstad 
pub...@kyllingen.nospamnet said:



Christopher Wright wrote:

Don wrote:

At worst, it would be something like:

exec(description, createArray(procName, arg1, arg2) ~ 
generatedArgs ~ createArray(arg3, arg4) ~ moreGeneratedArgs);


PHP does this. I haven't used PHP enough to hate it.



I've used PHP a fair bit, and I don't hate its array syntax at all. 
(There are plenty of other things in PHP to hate, though.) It's easily 
readable, and not much of a hassle to write. But array() in PHP isn't 
a function, it's a language construct with special syntax. To create 
an AA, for instance, you'd write


   $colours = array(apple = red, pear = green);

I'm not sure what the D equivalent of that one should be.


Associative array literals:

string[string] s = [hello: world, foo: bar];



I know that. :) I was just wondering what the equivalent function call 
should look like if we replaced array literals with functions, cf. the 
createArray() function above.


-Lars


Re: Array literals' default type

2009-10-09 Thread Don

Andrei Alexandrescu wrote:

Consider:

auto c = [ 2.71, 3.14, 6.023e22 ];
c ~= 2.21953167;

Should this work? Currently it doesn't because c's type is deduced as 
double[3].


The literal can initialize either double[3] or double[], so the question 
is only what the default should be when auto is used.



Thoughts?

Andrei


I agree with the others who say immutable(double)[].
Also, I don't understand why type inference is determined only by the 
first member. When patching your ICE bug 3374 just now I was struck by 
how simple it would be to determine the tightest type in the array.

auto c = [0, 2.5, 5, 7.5, 10];
-- should be immutable(double)[].
I guess Walter was just worried about how complicated the rules would 
become? There's clearly no implementation difficulty.


Re: Array literals' default type

2009-10-09 Thread Steven Schveighoffer

On Fri, 09 Oct 2009 06:11:50 -0400, grauzone n...@example.net wrote:


Steven Schveighoffer wrote:
immutable(double)[] - The compiler stores a copy of this array  
somewhere in ROM and initializes the stack variable with the immutable  
pointer to the data.



And what about

void foo(int x) {
auto a = [1, x, 2];

?

Should it create an immutable array on the heap? And if the user happens  
to need a mutable one, he has to dup it? (Causing one unnecessary memory  
allocation.)


This is an interesting question.  This literal obviously cannot be  
ROM-allocated, so it must be heap allocated.  But do we want heap  
allocated literals forced into being immutable?


I think array literals need to go through a major overhaul.  The type of  
the literal is highly dependent on both how you want to use it, and the  
values given to it.  Similar to how a 1 can be interpreted as a byte,  
maybe an array literal needs to generate different code depending on how  
you assign it.


Here's a stab at some rules I'd like to see implemented (when I say  
assigned to variable, I mean assigned, or casted, or passed as argument,  
etc):


1. If an array literal is assigned to a variable of type immutable(T)[] or  
const(T)[]:
   a. If any of the elements of the array are runtime-decided, then the  
array is allocated on the heap.
   b. Otherwise, the array is set in ROM, and an alias to the array is  
returned.
2. If an array literal is assigned to a variable of type T[] where T is  
not immutable or const, it is *always* allocated on the heap.
3. If an array literal is assigned to a variable of type T[], and all of  
the elements can be either interpreted as type T or implicitly casted to  
type T, the literal shall be interpreted as if it were written [cast(T)e1,  
cast(T)e2, ...]
4. If an array literal is assigned to a variable with the auto specifier,  
the type is immutable(T) where T is the most basic type that all the  
elements can be interpreted as.  Then rule 1 is followed.
5. If an array literal is assigned to a variable that is a static array,  
no heap allocation shall occur.
6. If an array literal is .dup'd, it will be treated as if it were  
assigned to a T[] where T is mutable.  If it's assigned to an auto, then T  
is the most basic type that all elements can be interpreted as.
7. If an array literal is .idup'd, it will be treated as if it were  
assigned to an immutable(T)[].  If it's assigned to an auto, then T is the  
most basic type that all elements can be interpreted as.


I suck at writing rules :)  Here are some examples of what I think should  
happen, and the types interpreted:


int[] x = [1,2,3]; // type: int[], on heap.
auto x = [1,2,3]; // type: immutable(int)[], ROM.

int y = 2;

auto x = [1,y,3]; // type: immutable(int)[], heap.
int[] x = [1,y,3]; // type: int[], heap.

auto x = [1,y,3].dup; // type int[], heap, only one allocation.
auto x = [1,2,3].dup; // type: int[], heap, only one allocation.

auto x = [1,y,3].idup; // type: immutable(int)[], heap, only one  
allocation.

auto x = [1,2,3].idup; // type: immutable(int)[], ROM.

auto x = [1,2.2,3]; // type: immutable(double)[], ROM.
immutable(double) x = [1,2,3]; // type: immutable(double)[], ROM.

int[3] x = [1,2,3]; // type int[3u], on stack, no heap allocation.

auto x = hello; // type immutable(char)[], ROM.
char[] x = hello; // type char[], on heap.

This is all principal of least surprise.  Do people think this is a good  
idea?


(Wait, is .dup even enough to get a mutable array, or will it return  
just another immutable one?)


.dup always returns a mutable array, regardless of the immutability of the  
source.  .idup returns an array of immutable data.



int[3] a = [1, x, 2];

Ideally, the line of code above would not cause a heap allocation.


I agree.  Automatic heap allocations for array literals that don't need to  
be heap allocated is crappy.


-Steve


Re: Array literals' default type

2009-10-09 Thread Don

Steven Schveighoffer wrote:

On Fri, 09 Oct 2009 06:11:50 -0400, grauzone n...@example.net wrote:


Steven Schveighoffer wrote:
immutable(double)[] - The compiler stores a copy of this array 
somewhere in ROM and initializes the stack variable with the 
immutable pointer to the data.



And what about

void foo(int x) {
auto a = [1, x, 2];

?

Should it create an immutable array on the heap? And if the user 
happens to need a mutable one, he has to dup it? (Causing one 
unnecessary memory allocation.)


This is an interesting question.  This literal obviously cannot be 
ROM-allocated, so it must be heap allocated.  But do we want heap 
allocated literals forced into being immutable?


I think array literals need to go through a major overhaul.  The type of 
the literal is highly dependent on both how you want to use it, and the 
values given to it.  Similar to how a 1 can be interpreted as a byte, 
maybe an array literal needs to generate different code depending on how 
you assign it.


Here's a stab at some rules I'd like to see implemented (when I say 
assigned to variable, I mean assigned, or casted, or passed as argument, 
etc):


1. If an array literal is assigned to a variable of type immutable(T)[] 
or const(T)[]:
   a. If any of the elements of the array are runtime-decided, then the 
array is allocated on the heap.
   b. Otherwise, the array is set in ROM, and an alias to the array is 
returned.
2. If an array literal is assigned to a variable of type T[] where T is 
not immutable or const, it is *always* allocated on the heap.
3. If an array literal is assigned to a variable of type T[], and all of 
the elements can be either interpreted as type T or implicitly casted to 
type T, the literal shall be interpreted as if it were written 
[cast(T)e1, cast(T)e2, ...]
4. If an array literal is assigned to a variable with the auto 
specifier, the type is immutable(T) where T is the most basic type that 
all the elements can be interpreted as.  Then rule 1 is followed.
5. If an array literal is assigned to a variable that is a static array, 
no heap allocation shall occur.
6. If an array literal is .dup'd, it will be treated as if it were 
assigned to a T[] where T is mutable.  If it's assigned to an auto, then 
T is the most basic type that all elements can be interpreted as.
7. If an array literal is .idup'd, it will be treated as if it were 
assigned to an immutable(T)[].  If it's assigned to an auto, then T is 
the most basic type that all elements can be interpreted as.


I suck at writing rules :)  Here are some examples of what I think 
should happen, and the types interpreted:


int[] x = [1,2,3]; // type: int[], on heap.
auto x = [1,2,3]; // type: immutable(int)[], ROM.

int y = 2;

auto x = [1,y,3]; // type: immutable(int)[], heap.
int[] x = [1,y,3]; // type: int[], heap.

auto x = [1,y,3].dup; // type int[], heap, only one allocation.
auto x = [1,2,3].dup; // type: int[], heap, only one allocation.

auto x = [1,y,3].idup; // type: immutable(int)[], heap, only one 
allocation.

auto x = [1,2,3].idup; // type: immutable(int)[], ROM.

auto x = [1,2.2,3]; // type: immutable(double)[], ROM.
immutable(double) x = [1,2,3]; // type: immutable(double)[], ROM.

int[3] x = [1,2,3]; // type int[3u], on stack, no heap allocation.

auto x = hello; // type immutable(char)[], ROM.
char[] x = hello; // type char[], on heap.

This is all principal of least surprise.  Do people think this is a good 
idea?


(Wait, is .dup even enough to get a mutable array, or will it return 
just another immutable one?)


.dup always returns a mutable array, regardless of the immutability of 
the source.  .idup returns an array of immutable data.



int[3] a = [1, x, 2];

Ideally, the line of code above would not cause a heap allocation.


I agree.  Automatic heap allocations for array literals that don't need 
to be heap allocated is crappy.


-Steve


I don't understand why runtime-determined array literals even exist.
They're not literals!!!
They cause no end of trouble. IMHO we'd be *much* better off without them.




Re: Array literals' default type

2009-10-09 Thread Steven Schveighoffer

On Fri, 09 Oct 2009 08:34:31 -0400, Don nos...@nospam.com wrote:



I don't understand why runtime-determined array literals even exist.
They're not literals!!!
They cause no end of trouble. IMHO we'd be *much* better off without  
them.


I don't agree.  Here is a runtime decided array literal:

void foo(int a, int b, int c)
{
auto x = [a, b, c];
}

The alternatives are:

// manual construction and assignment

auto x = new int[3]; // unnecessary initialization to 0!
x[0] = a;
x[1] = b;
x[2] = c;

// template function

auto x = createArray(a, b, c);

// mixin?

Although the template function looks nice, it adds bloat.  The mixin is  
probably ugly (I don't write them much, so I'm not sure how it would be  
done).  Why shouldn't the compiler just do what you want it to do?  I  
don't see a  lot of ambiguity in the statement above, I want an array of  
a, b, and c together please.  It's obvious what to do, and the code looks  
clean.


On top of that, what if a, b, and c are runtime decide, then during  
development, or with a new compiler, they can now be CTFE decided?  Now  
you are calling some function when they *could* be in a literal.


It's the same thing in my opinion with range detection.  It used to be  
that:


byte b = 1 + 1;

generated an error, now, it works because the compiler realizes that 1+1  
doesn't overflow a byte.  Why can't we add that same type of smarts into  
array literals?


-Steve


Re: Array literals' default type

2009-10-09 Thread Max Samukha
On Fri, 09 Oct 2009 14:34:31 +0200, Don nos...@nospam.com wrote:


I don't understand why runtime-determined array literals even exist.
They're not literals!!!
They cause no end of trouble. IMHO we'd be *much* better off without them.


I agree. They are an endless source of confusion. The same applies to
struct literals.



Re: Array literals' default type

2009-10-09 Thread Steven Schveighoffer

On Fri, 09 Oct 2009 09:27:01 -0400, Don nos...@nospam.com wrote:


Steven Schveighoffer wrote:

On Fri, 09 Oct 2009 08:34:31 -0400, Don nos...@nospam.com wrote:



I don't understand why runtime-determined array literals even exist.
They're not literals!!!
They cause no end of trouble. IMHO we'd be *much* better off without  
them.

 I don't agree.  Here is a runtime decided array literal:
 void foo(int a, int b, int c)
{
auto x = [a, b, c];
}
 The alternatives are:



// template function
 auto x = createArray(a, b, c);
 // mixin?
 Although the template function looks nice, it adds bloat.


There's no bloat. You just need a type-safe variadic.
T[] createArray(T)(T[] args...);

One function per type. That's the best you're ever going to do with  
run-time construction anyway.
Actually, there's horrific bloat present right now. Look at the code  
generated when you use an array literal.


If you have a function that takes a typesafe variadic array, what is the  
compiler going to do to pass that data into the function?  Push it on the  
stack, call a function, and then the function is going to do the same  
thing a literal would do, reading the data off the stack?  How is that not  
worse than an array literal generating code to build an array?  Not to  
mention the added symbol bloat.


Generated code isn't bloat if it's the minimal work that has to be done to  
get what you want.


 On top of that, what if a, b, and c are runtime decide, then during  
development, or with a new compiler, they can now be CTFE decided?  Now  
you are calling some function when they *could* be in a literal.


This is exactly the problem.
They should ALWAYS require CTFE evaluation.

EG:
immutable(double)[] tableOfSines = [ sin(0.0), sin(PI/4), sin(PI/2),  
sin(3*PI/4), sin(1)];


Obviously, these values should be be compile-time evaluated. But how  
does the compiler know that? It can't.

Right now, this is done at run-time.


I'm not extremely well-versed in what triggers CTFE, but it seems logical  
to me that the compiler can determine that it can be evaluated at  
compile-time, assuming sin is marked as pure (or maybe even if it isn't).   
What am I missing?




Runtime array creation is a prime candidate for moving from language to  
libraries.


It is a solution, but I think the better solution is you just write what  
you want and the compiler figures out the best move.  Whether it's heap  
allocated or not, created at runtime or not, is an implementation detail I  
don't think the user needs to worry about.


Come to think of it, the same thing goes for static initializers.  What a  
pain it is to do:


int x;

static this()
{
  x = foo();
}

instead of just

int x = foo();

-Steve


Re: Array literals' default type

2009-10-09 Thread Bill Baxter
On Fri, Oct 9, 2009 at 8:06 AM, Don nos...@nospam.com wrote:
 Steven Schveighoffer wrote:

 On Fri, 09 Oct 2009 09:27:01 -0400, Don nos...@nospam.com wrote:

 Steven Schveighoffer wrote:

 On Fri, 09 Oct 2009 08:34:31 -0400, Don nos...@nospam.com wrote:


 I don't understand why runtime-determined array literals even exist.
 They're not literals!!!
 They cause no end of trouble. IMHO we'd be *much* better off without
 them.

  I don't agree.  Here is a runtime decided array literal:
  void foo(int a, int b, int c)
 {
 auto x = [a, b, c];
 }
  The alternatives are:

 // template function
  auto x = createArray(a, b, c);
  // mixin?
  Although the template function looks nice, it adds bloat.

 There's no bloat. You just need a type-safe variadic.
 T[] createArray(T)(T[] args...);

 One function per type. That's the best you're ever going to do with
 run-time construction anyway.
 Actually, there's horrific bloat present right now. Look at the code
 generated when you use an array literal.

 If you have a function that takes a typesafe variadic array, what is the
 compiler going to do to pass that data into the function?  Push it on the
 stack, call a function, and then the function is going to do the same thing
 a literal would do, reading the data off the stack?  How is that not worse
 than an array literal generating code to build an array?

 That's exactly what the compiler does right now. It pushes all the values
 onto the stack, then calls a function to create a literal g.

 Not to mention the added symbol bloat.

 That's the only kind of bloat the template solution could give you.

 Generated code isn't bloat if it's the minimal work that has to be done to
 get what you want.

 Yes, but at present it always generating code for the worst case.


  On top of that, what if a, b, and c are runtime decide, then during
 development, or with a new compiler, they can now be CTFE decided?  Now you
 are calling some function when they *could* be in a literal.

 This is exactly the problem.
 They should ALWAYS require CTFE evaluation.

 EG:
 immutable(double)[] tableOfSines = [ sin(0.0), sin(PI/4), sin(PI/2),
 sin(3*PI/4), sin(1)];

 Obviously, these values should be be compile-time evaluated. But how does
 the compiler know that? It can't.
 Right now, this is done at run-time.

 I'm not extremely well-versed in what triggers CTFE, but it seems logical
 to me that the compiler can determine that it can be evaluated at
 compile-time, assuming sin is marked as pure (or maybe even if it isn't).
  What am I missing?

 A function can be pure even if it does a huge calculation that takes days.
 CTFE is only triggered if used in a situation where a compile-time constant
 is _mandatory_. You have to explicitly ask for CTFE somehow.

 Runtime array creation is a prime candidate for moving from language to
 libraries.

 It is a solution, but I think the better solution is you just write what
 you want and the compiler figures out the best move.  Whether it's heap
 allocated or not, created at runtime or not, is an implementation detail I
 don't think the user needs to worry about.

 I think it's really misleading to have an expensive operation masqueriding
 as a free one. Suppose you have a 2 element array literal, all
 constants, and then you change one element to 'x+2' where x is a local
 variable. Suddenly, instead of just getting a pointer to statically-loaded
 data, you're pushing 2 things onto the stack!

 Creating an array at run-time seems to be a kind of constructor call to me.
 Using array literal syntax for runtime initialization gives the same
 problems Andrei discussed in the 'new' thread. Eg, it's not polymorphic.

 I suspect that uses of run-time array literals are really rare. My code is
 full of compile-time array literals, but I've never seen a run-time usage.

The only place I can think of that I use them is when I'm trying to
make some set of actions on several different things loop-able.

Like
float a = [x-2, x*2, y];
foreach(i,v; a) {
   // do something
}

Not a very compelling example, but sometimes you have a small set of
computed values and you need to do the same thing to all of them, or
access them by number.   (So you can use a[i] and a[(i+1)%a.length]
for example).

I wouldn't mind having to call some sort of constructor in those cases.

--bb


Re: Array literals' default type

2009-10-09 Thread Steven Schveighoffer

On Fri, 09 Oct 2009 11:06:18 -0400, Don nos...@nospam.com wrote:


Steven Schveighoffer wrote:

On Fri, 09 Oct 2009 09:27:01 -0400, Don nos...@nospam.com wrote:


Steven Schveighoffer wrote:

On Fri, 09 Oct 2009 08:34:31 -0400, Don nos...@nospam.com wrote:



I don't understand why runtime-determined array literals even exist.
They're not literals!!!
They cause no end of trouble. IMHO we'd be *much* better off without  
them.

 I don't agree.  Here is a runtime decided array literal:
 void foo(int a, int b, int c)
{
auto x = [a, b, c];
}
 The alternatives are:



// template function
 auto x = createArray(a, b, c);
 // mixin?
 Although the template function looks nice, it adds bloat.


There's no bloat. You just need a type-safe variadic.
T[] createArray(T)(T[] args...);

One function per type. That's the best you're ever going to do with  
run-time construction anyway.
Actually, there's horrific bloat present right now. Look at the code  
generated when you use an array literal.
 If you have a function that takes a typesafe variadic array, what is  
the compiler going to do to pass that data into the function?  Push it  
on the stack, call a function, and then the function is going to do the  
same thing a literal would do, reading the data off the stack?  How is  
that not worse than an array literal generating code to build an array?


That's exactly what the compiler does right now. It pushes all the  
values onto the stack, then calls a function to create a literal g.


Actually, that makes sense :)  I stand corrected.  The only case it  
doesn't make sense is for static arrays.


Generated code isn't bloat if it's the minimal work that has to be done  
to get what you want.


Yes, but at present it always generating code for the worst case.


I'm not arguing for the present situation (always heap allocate mutable  
data).




 On top of that, what if a, b, and c are runtime decide, then during  
development, or with a new compiler, they can now be CTFE decided?   
Now you are calling some function when they *could* be in a literal.


This is exactly the problem.
They should ALWAYS require CTFE evaluation.

EG:
immutable(double)[] tableOfSines = [ sin(0.0), sin(PI/4), sin(PI/2),  
sin(3*PI/4), sin(1)];


Obviously, these values should be be compile-time evaluated. But how  
does the compiler know that? It can't.

Right now, this is done at run-time.
 I'm not extremely well-versed in what triggers CTFE, but it seems  
logical to me that the compiler can determine that it can be evaluated  
at compile-time, assuming sin is marked as pure (or maybe even if it  
isn't).  What am I missing?


A function can be pure even if it does a huge calculation that takes  
days. CTFE is only triggered if used in a situation where a compile-time  
constant is _mandatory_. You have to explicitly ask for CTFE somehow.


Yes, you are right.  I didn't think about that.

It seems like whether a function call should be evaluated via CTFE is  
really an orthogonal problem (one which probably needs solving also).




Runtime array creation is a prime candidate for moving from language  
to libraries.
 It is a solution, but I think the better solution is you just write  
what you want and the compiler figures out the best move.  Whether it's  
heap allocated or not, created at runtime or not, is an implementation  
detail I don't think the user needs to worry about.


I think it's really misleading to have an expensive operation  
masqueriding as a free one. Suppose you have a 2 element array  
literal, all constants, and then you change one element to 'x+2' where x  
is a local variable. Suddenly, instead of just getting a pointer to  
statically-loaded data, you're pushing 2 things onto the stack!


I'm not sure we should cater to preventing cases like this.  I've never  
seen anything like this in real code.


Creating an array at run-time seems to be a kind of constructor call to  
me. Using array literal syntax for runtime initialization gives the same  
problems Andrei discussed in the 'new' thread. Eg, it's not polymorphic.


Arrays aren't polymorphic.  I don't think that applies.

However, the allocation argument is valid.  For example:

int[] x = new int[3];

x[] = [a,b,c];

Should this construct a heap allocated array, then copy it to x?  What a  
waste.  I guess that's another special case that would need to be handled  
by the compiler, but the rules are getting quite complicated.


I suspect that uses of run-time array literals are really rare. My code  
is full of compile-time array literals, but I've never seen a run-time  
usage.


I think you are right that they are not as common, but I wouldn't call  
them really rare.  Building an array via the same syntax whether you are  
using literals or variables seems like the most natural thing to me.  If  
we can't do that, a library call is probably the next best solution.


But I think a library solution will be very difficult to implement,  
especially 

Re: Array literals' default type

2009-10-09 Thread Andrei Alexandrescu

Christopher Wright wrote:

Don wrote:

I don't understand why runtime-determined array literals even exist.
They're not literals!!!
They cause no end of trouble. IMHO we'd be *much* better off without 
them.


You don't see the use. I do. I would go on a murderous rampage if that 
feature were removed from the language.


For example, one thing I recently wrote involved creating a process with 
a large number of arguments. The invocation looked like:
exec(description, [procName, arg1, arg2] ~ generatedArgs ~ [arg3, 
arg4] ~ moreGeneratedArgs);


There were about ten or fifteen lines like that.

You'd suggest I rewrite that how?
char[][] args;
args ~= procName;
args ~= arg1;
args ~= arg2;
args ~= generatedArgs;
args ~= arg3;

Just fucking shoot me. Or better yet, whoever removed array literals 
with non-constant elements from the language.


Relax. It's a condition known as literalitis. :o)

Literals only have you write [ a, b, c ] instead of toArray(a, b, c). I 
wouldn't see it a big deal one way or another, but the issue is that the 
former is a one-time decision that pretty much can't be changed, whereas 
toArray can benefit of the hindsight of experience.



Andrei


Re: Array literals' default type

2009-10-09 Thread Denis Koroskin
On Sat, 10 Oct 2009 02:28:42 +0400, Andrei Alexandrescu  
seewebsiteforem...@erdani.org wrote:



Christopher Wright wrote:

Don wrote:

I don't understand why runtime-determined array literals even exist.
They're not literals!!!
They cause no end of trouble. IMHO we'd be *much* better off without  
them.
 You don't see the use. I do. I would go on a murderous rampage if that  
feature were removed from the language.
 For example, one thing I recently wrote involved creating a process  
with a large number of arguments. The invocation looked like:
exec(description, [procName, arg1, arg2] ~ generatedArgs ~ [arg3,  
arg4] ~ moreGeneratedArgs);

 There were about ten or fifteen lines like that.
 You'd suggest I rewrite that how?
char[][] args;
args ~= procName;
args ~= arg1;
args ~= arg2;
args ~= generatedArgs;
args ~= arg3;
 Just fucking shoot me. Or better yet, whoever removed array literals  
with non-constant elements from the language.


Relax. It's a condition known as literalitis. :o)

Literals only have you write [ a, b, c ] instead of toArray(a, b, c). I  
wouldn't see it a big deal one way or another, but the issue is that the  
former is a one-time decision that pretty much can't be changed, whereas  
toArray can benefit of the hindsight of experience.



Andrei


I believe it's okay, but compiler should be able to return static arrays  
from a function (I'll call it array, but feel free to substitute any  
other function name):


foreach (i; [a, b, c]) {  ---   foreach (i, array(a, b,c )) {
// ...   // ...
}}

int[3] x = [a, b, c]; ---   int[3] x = array(a, b, c);

The first example could work with any range returned, but can you  
initialize a static array with a range?


Well, some language feature could allow that and translate the latter case  
into something like this:


int[3] x = void;
foreach (index, value; array(a, b, c)) {
x[index] = value;
}

But then, what would you do with an array overflow? Disallow it? I.e.,  
make it impossible to create a static array and initialize it at the same  
time?


If range design is essential in D, perhaps the following could be allowed:

int[] someArray = ...;
someArray[] = someRange(); // initializes an array with elements of a  
range. Throws an exception if boundaries don't match


And then,

int[3] x = array(a, b, c);

could be translated into

int[3] x = void;
x[] = array(a, b, c);

(unless array doesn't meet range criteria, of course).

You loose compile-time boundaries checking, but that's the best you can do  
if you drop [a, b, c] feature, I'm affraid.


Array literals' default type

2009-10-08 Thread Andrei Alexandrescu

Consider:

auto c = [ 2.71, 3.14, 6.023e22 ];
c ~= 2.21953167;

Should this work? Currently it doesn't because c's type is deduced as 
double[3].


The literal can initialize either double[3] or double[], so the question 
is only what the default should be when auto is used.



Thoughts?

Andrei


Re: Array literals' default type

2009-10-08 Thread bearophile
Andrei Alexandrescu:

 auto c = [ 2.71, 3.14, 6.023e22 ];
 c ~= 2.21953167;
 Should this work? Currently it doesn't because c's type is deduced as 
 double[3].
 The literal can initialize either double[3] or double[], so the question 
 is only what the default should be when auto is used.

double[] is safer and more flexible, so I think that has to be the default. The 
double[3] is a (very useful) optimization.

auto c = [2, 3.14, 6.023e22];
= double[]

double[$] c = [2, 3.14, 6.023e22];
= double[3]

Bye,
bearophile


Re: Array literals' default type

2009-10-08 Thread Denis Koroskin
On Thu, 08 Oct 2009 22:07:32 +0400, Andrei Alexandrescu  
seewebsiteforem...@erdani.org wrote:



Consider:

auto c = [ 2.71, 3.14, 6.023e22 ];
c ~= 2.21953167;

Should this work? Currently it doesn't because c's type is deduced as  
double[3].


The literal can initialize either double[3] or double[], so the question  
is only what the default should be when auto is used.



Thoughts?

Andrei


I was just about to bump a similar topic.

I strongly believe typeof(c) must be immutable(double)[3].

There are 2 problems in D with current design:

1) The following code:

auto c = [ 2.71, 3.14, 6.023e22 ];

always allocates memory from a heap. In many cases, a read-only view of  
that array would suffice. In case a mutation is needed, no one stops you  
from dup'ing that array:


auto c = [ 2.71, 3.14, 6.023e22 ].dup;

2) There is an inconsistency with strings:

auto c1 = Hello; // immutable
auto c2 = ['H', 'e', 'l', 'l', 'o']; // mutable

I don't like hidden allocations like this to present in D. I believe this  
is not what most users expect to happen.


Back to your question, I believe it should be fixed-size and immutable.  
Once again, no one stops you from using []:


auto c = [ 2.71, 3.14, 6.023e22 ][]; // a slice is returned

The opposite is impossible - you can't get a fixed-sized array from a  
dynamic one.


Another question is, what type should .dup return? T[new] or T[]? (The  
former one, probably, since the latter one is accessible via .dup[]  
syntax...) Anyway, what is the state of T[new] in future of D?


Re: Array literals' default type

2009-10-08 Thread Steven Schveighoffer
On Thu, 08 Oct 2009 15:10:46 -0400, Denis Koroskin 2kor...@gmail.com  
wrote:


On Thu, 08 Oct 2009 22:07:32 +0400, Andrei Alexandrescu  
seewebsiteforem...@erdani.org wrote:



Consider:

auto c = [ 2.71, 3.14, 6.023e22 ];
c ~= 2.21953167;

Should this work? Currently it doesn't because c's type is deduced as  
double[3].


The literal can initialize either double[3] or double[], so the  
question is only what the default should be when auto is used.



Thoughts?

Andrei


I was just about to bump a similar topic.

I strongly believe typeof(c) must be immutable(double)[3].


You're half right.  It should be immutable(double)[].

Remember, double[3] is allocated *on the stack*, so there is no point in  
making it immutable.


So the only two logical choices are:

double[3] - The compiler stores a copy of this array somewhere, and  
initializes the stack variable with the contents each time the literal is  
used (or generates code to make the array in the function itself).


immutable(double)[] - The compiler stores a copy of this array somewhere  
in ROM and initializes the stack variable with the immutable pointer to  
the data.


The second choice is almost certainly more useful than the first, and if  
you truly don't need it mutable, much better performing.


This then leaves the quandry -- what if you *do* want a static array, but  
you don't want to have to match the size?  I think bearophile's suggestion  
is a good one:


double[$] c = ...

Or another option:

auto[$] c = ...

if you want true type inference from the literal.


2) There is an inconsistency with strings:

 auto c1 = Hello; // immutable
 auto c2 = ['H', 'e', 'l', 'l', 'o']; // mutable



Note that the type of c1 is not immutable(char)[5], it's immutable(char)[]  
(this is different from D1, where the Hello literal would be typed  
char[5u]).


-Steve


Re: Array literals' default type

2009-10-08 Thread Denis Koroskin
On Thu, 08 Oct 2009 23:50:31 +0400, Steven Schveighoffer  
schvei...@yahoo.com wrote:


On Thu, 08 Oct 2009 15:10:46 -0400, Denis Koroskin 2kor...@gmail.com  
wrote:


On Thu, 08 Oct 2009 22:07:32 +0400, Andrei Alexandrescu  
seewebsiteforem...@erdani.org wrote:



Consider:

auto c = [ 2.71, 3.14, 6.023e22 ];
c ~= 2.21953167;

Should this work? Currently it doesn't because c's type is deduced as  
double[3].


The literal can initialize either double[3] or double[], so the  
question is only what the default should be when auto is used.



Thoughts?

Andrei


I was just about to bump a similar topic.

I strongly believe typeof(c) must be immutable(double)[3].


You're half right.  It should be immutable(double)[].

Remember, double[3] is allocated *on the stack*, so there is no point in  
making it immutable.


So the only two logical choices are:

double[3] - The compiler stores a copy of this array somewhere, and  
initializes the stack variable with the contents each time the literal  
is used (or generates code to make the array in the function itself).


immutable(double)[] - The compiler stores a copy of this array somewhere  
in ROM and initializes the stack variable with the immutable pointer to  
the data.


The second choice is almost certainly more useful than the first, and if  
you truly don't need it mutable, much better performing.




Right, that was an oversight. I'm now in favor of immutable(double)[].




2) There is an inconsistency with strings:

 auto c1 = Hello; // immutable
 auto c2 = ['H', 'e', 'l', 'l', 'o']; // mutable



Note that the type of c1 is not immutable(char)[5], it's  
immutable(char)[] (this is different from D1, where the Hello literal  
would be typed char[5u]).


-Steve


I believe the two should be the same (with the tiny difference that c1 is  
null-terminated under the hood), immutable(char)[] that is.