Array literals' default type
Bill Baxter
wbaxter at gmail.com
Fri Oct 9 08:37:07 PDT 2009
On Fri, Oct 9, 2009 at 8:06 AM, 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>.
>
>> 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 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!
>
> 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
More information about the Digitalmars-d
mailing list