Array literals' default type

Steven Schveighoffer schveiguy at yahoo.com
Fri Oct 9 09:03:14 PDT 2009


On Fri, 09 Oct 2009 11:06:18 -0400, Don <nospam at nospam.com> wrote:

> Steven Schveighoffer wrote:
>> On Fri, 09 Oct 2009 09:27:01 -0400, Don <nospam at nospam.com> wrote:
>>
>>> Steven Schveighoffer wrote:
>>>> On Fri, 09 Oct 2009 08:34:31 -0400, Don <nospam at 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 20000 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 20000 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 working around possible type issues (a unique type modifier  
would be helpful here).

-Steve



More information about the Digitalmars-d mailing list