static array literal syntax request: auto x=[1,2,3]S;

Artur Skawina art.08.09 at gmail.com
Sun Jun 10 11:49:29 PDT 2012


On 06/10/12 19:32, Timon Gehr wrote:
> On 06/10/2012 07:00 PM, Artur Skawina wrote:
>> On 06/10/12 18:02, Timon Gehr wrote:
>>> On 06/10/2012 04:54 PM, Artur Skawina wrote:
>>>> ...
>>>> An array literal is a dynamic array with a known constant length that
>>>> implicitly converts to a static array of the same size and element type.
>>>> That's a sane definition,
>>>
>>> It is not. It does not specify if/when allocations take place, for example.
>>
>> Implementation details. Would you like to forbid "unnecessary" allocations?
>> Not doing this should be harmless as it only affects performance,
> 
> Wrong.
> 
> class S{
>     ~this() {
>         int[3] a = [1,2,3];
>     }
> }

I'm sure we agree that no allocation should take place here, just a memcpy,
which would often be optimized to only a few stores.

>> but maybe
>> the hidden heap allocations should indeed be disallowed. Any decent compiler
>> won't be emitting them anyway.

Your example is a good case for explicitly banning them, I agree.


>>>> and AFAICT this is how it's currently handled.
>>>>
>>>
>>> It is not.
>>>
>>> void main(){
>>>      int[0] x = [1];
>>> }
>>
>> Try running that, in non-release mode. :)
>>
> 
> (I never post valid D code that I haven't run.)

Then I'm not sure what you're trying to say; that program will throw
an exception at runtime. That the compiler is buggy by compiling it?


>> The fact that the compiler accepts it even in the cases where it should
>> be able to statically figure out that it will fail at runtime isn't ideal,
>> but this is just a quality of implementation issue.
>>
> 
> It is a bug. A static type system is pointless if it is not used for validating certain code properties.

True. The way i see this --  there are so many large problems and holes in
both the language and compiler that worrying about cases like this one not
being caught at compile-time is premature. Sure, eventually it needs to be
handled better, but right now there are bigger issues. And my comment wrt
the compiler wasn't necessarily fair - it seems to do a very decent job in
most cases, front-end wise; most issues are not with the implementation, but
with the definition/specification.


>>>>>>> The
>>>>>>> other place that this causes problems is templated functions. e.g.
>>>>>>>
>>>>>>> void func(A)(A array)
>>>>>>>        if(isStaticArray!A)
>>>>>>> {}
>>>>>>>
>>>>>>> func([1, 2, 3, 4, 5]);
>>>>>>>
>>>>>>> will fail to compile. You're forced to create one on the stack first.
>>>>>>>
>>>>>>> int[5] array = [1, 2, 3, 4, 5];
>>>>>>> func(array);
>>>>>>>
>>>>>>
>>>>>> func(cast(int[5])[1,2,3,4,5]);
>>>>>>
>>>>>>> That _might_ merit adding a syntax for indicating that an array
>>>>>>> literal is
>>>>>>> static.
>>>>
>>>> I wasn't kidding about overloading 'static' for this; it would certainly
>>>> be better that inventing yet another literal syntax.
>>>>
>>>
>>> Using 'static' is "inventing yet another literal syntax" as well.
>>
>> In a way - yes. But i think "static[...]" would be much better than "[...]S".
>>
> 
> Obviously, none is much better than the other.
> 
>> ...
>>>>
>>>> The isStaticArray!A problem is partially related to how the compiler handles
>>>> arrays.
>>>>
>>>>      auto f(T)(T a) { enum l = a.length; return l; }
>>>>
>>>> works with
>>>>
>>>>      int[3] a = [1,2,3];
>>>>      f(a);
>>>>
>>>> but fails with
>>>>
>>>>      f([1,2,3]);
>>>>
>>>> And cases like
>>>>
>>>>      auto f(E)(E[] a) { enum l = a.length; return l; }
>>>>
>>>> don't work at all.
>>>>
>>>> Making these things work, which should be possible,
>>>
>>> f([1,2,3]);               // f!(int[])
>>> f([1,2,3,4]);             // f!(int[])
>>>
>>> int[3] a = [1,2,3];
>>> f(a);                     // f!(int[3])
>>> f(cast(int[3])[1,2,3]);   // f!(int[3])
>>> f(cast(int[4])[1,2,3,4]); // f!(int[4])
>>
>> I'm not sure what your point is here.
> 
> A statically known length cannot be different in two identical instantiations.

Obviously. That's why I mentioned cloning them. This is done for
non-templated functions that are called with known arguments already;
all i'm suggesting is using a similar approach here.
The 'length' property of an array literal can be viewed as known
parameter. (and, yes, my solution requires for this be done at an
earlier stage)


>> Mine is that 'length' is
>> known in all these cases at compile time. Yet it's only possible
>> to retrieve it when the argument is a real static array. It should
>> also be possible when the function is called with a literal.
> 
> That is a case for introducing a dedicated static array literal syntax, not for butchering the template instantiation semantics. (if at all)

A solution that requires the programmer to always remember to mark
literals in a special way is not the best approach. It should be possible
to call a library functions with both a "real" array and a literal and the
syntax shouldn't be different. Especially as that "array" could be an enum.
Or immutable variable set at compile time.

Another approach would be using __traits, but the implications wouldn't
really be much different...


> The optimizer can inline the call and use the additional information gained without language changes.

What if i'd like to use a different algorithm for a certain array size?
Right now, I can, but have to assign the literal to a temporary static
array, before calling the function. This is the main issue, everything
else is just a consequence of my proposed solution, more of a side-effect
actually.

The naive approach would be to convert the dynamic array literal to a
static array, but that won't work, because static arrays are passed by
value. Hmm, special-casing for const args and literals might work.

Anyway, can you think of a better solution? Ie one, that does not
involve introducing a new literal syntax?

> What you want to achieve is better left to macros.

I'd love to have macros, they are necessary for things like attributes and
pragmas. But if macros are required for generic programming then something
is wrong.

artur


More information about the Digitalmars-d mailing list