December 10, 2013
On Tuesday, 10 December 2013 at 08:26:34 UTC, Jonathan M Davis wrote:
> On Tuesday, December 10, 2013 09:00:22 Namespace wrote:
>> I use this implict converting to static arrays very often and if
>> we deprecate it, we really need something to declare static array
>> literals.
>
> Implicit conversion isn't the problem. It's the fact that there are two
> possible matches, and it picks one over the other rather than requiring the
> programmer to indicate which one is correct (e.g. via casting). That's just
> going to lead to bugs. If there is no conflict, then the implicit conversion is
> fine. It's just that when there is a conflict that it's a problem.
Ok.

> We have similar problems with stuff like
>
> void foo(bool b) {...}
> void foo(long l) {...}
>
> foo(1); //calls the bool overload
>
> There was a huge thread on this a while back where almost no one other than
> Walter thought that this behavior was good, and it was clearly causing bugs
> (Walter argued that the solution was to just add an overload for int rather
> than fixing the conversion problem). IMHO, there should be no implicit
> conversion of literals when there's a conflict. It should result in an
> ambiguity error so that the programmer has the opportunity to indicate the
> correct overload.
>
> - Jonathan M Davis

Yeah I remember, but Kenji made a Pull Request to change this.
Regardless it would be very useful to have static array literals.
December 10, 2013
On Tuesday, December 10, 2013 10:10:22 Namespace wrote:
> Yeah I remember, but Kenji made a Pull Request to change this. Regardless it would be very useful to have static array literals.

It should be possible to do that via a templated function which takes a static array and then returns it. e.g.

auto staticLiteral(T, size_t n)(T[n] literal)
{
    return literal;
}

auto staticArray = staticLiteral([1, 2, 3, 4]);

The compiler should optimize out the heap allocation, since the literal is directly converted to a static array (it might not optimize it now, but it definitely should, in which case, you're effectively creating a static array literal without any heap allocations).

Maybe that's more verbose than would be ideal, but it allows us to essentially have static array literals without having to add anything to the language.

- Jonathan M Davis
December 10, 2013
On Tuesday, 10 December 2013 at 09:28:27 UTC, Jonathan M Davis wrote:
> On Tuesday, December 10, 2013 10:10:22 Namespace wrote:
>> Yeah I remember, but Kenji made a Pull Request to change this.
>> Regardless it would be very useful to have static array literals.
>
> It should be possible to do that via a templated function which takes a static
> array and then returns it. e.g.
>
> auto staticLiteral(T, size_t n)(T[n] literal)
> {
>     return literal;
> }
>
> auto staticArray = staticLiteral([1, 2, 3, 4]);
>
> The compiler should optimize out the heap allocation, since the literal is
> directly converted to a static array (it might not optimize it now, but it
> definitely should, in which case, you're effectively creating a static array
> literal without any heap allocations).
>
> Maybe that's more verbose than would be ideal, but it allows us to essentially
> have static array literals without having to add anything to the language.
>
> - Jonathan M Davis
Ugly. Why not {1, 2, 3} or [1, 2, 3]s. The compiler could (as long as necessary) rewrite this to your ugly solution.
But library solutions are always ugly and mostly bad and bug prone. See scoped, Typedef and destroy.
December 10, 2013
On Tuesday, December 10, 2013 10:33:33 Namespace wrote:
> On Tuesday, 10 December 2013 at 09:28:27 UTC, Jonathan M Davis
> 
> wrote:
> > On Tuesday, December 10, 2013 10:10:22 Namespace wrote:
> >> Yeah I remember, but Kenji made a Pull Request to change this. Regardless it would be very useful to have static array literals.
> > 
> > It should be possible to do that via a templated function which
> > takes a static
> > array and then returns it. e.g.
> > 
> > auto staticLiteral(T, size_t n)(T[n] literal)
> > {
> > 
> >     return literal;
> > 
> > }
> > 
> > auto staticArray = staticLiteral([1, 2, 3, 4]);
> > 
> > The compiler should optimize out the heap allocation, since the
> > literal is
> > directly converted to a static array (it might not optimize it
> > now, but it
> > definitely should, in which case, you're effectively creating a
> > static array
> > literal without any heap allocations).
> > 
> > Maybe that's more verbose than would be ideal, but it allows us
> > to essentially
> > have static array literals without having to add anything to
> > the language.
> > 
> > - Jonathan M Davis
> 
> Ugly. Why not {1, 2, 3} or [1, 2, 3]s. The compiler could (as
> long as necessary) rewrite this to your ugly solution.
> But library solutions are always ugly and mostly bad and bug
> prone. See scoped, Typedef and destroy.

Walter and Andrei are very much against adding anything further to the language when it can be done in a library instead. {1, 2, 3} conflicts with C- style struct construction, and while [1, 2, 3]s is nice and short, all it does over staticLiteral([1, 2, 3]) is save some typing, and it requires language changes, whereas it's trivial in comparison to do something like this in a library. In fact, if we were to start over with D now, there would be a number of things that would just be in the library instead of the language (e.g. Andrei has stated several times that new should not have been a keyword and that it should have been handled by the standard library instead of the language). But it's too late for that now, so pretty much all of the stuff that might not end up the language if we were to start over is going to stay. However, that doesn't mean that we're going to be anything more like that in the language when we can do it in the library.

- Jonathan M Davis
December 10, 2013
On Tuesday, 10 December 2013 at 09:42:50 UTC, Jonathan M Davis wrote:
> On Tuesday, December 10, 2013 10:33:33 Namespace wrote:
>> On Tuesday, 10 December 2013 at 09:28:27 UTC, Jonathan M Davis
>> 
>> wrote:
>> > On Tuesday, December 10, 2013 10:10:22 Namespace wrote:
>> >> Yeah I remember, but Kenji made a Pull Request to change this.
>> >> Regardless it would be very useful to have static array
>> >> literals.
>> > 
>> > It should be possible to do that via a templated function which
>> > takes a static
>> > array and then returns it. e.g.
>> > 
>> > auto staticLiteral(T, size_t n)(T[n] literal)
>> > {
>> > 
>> >     return literal;
>> > 
>> > }
>> > 
>> > auto staticArray = staticLiteral([1, 2, 3, 4]);
>> > 
>> > The compiler should optimize out the heap allocation, since the
>> > literal is
>> > directly converted to a static array (it might not optimize it
>> > now, but it
>> > definitely should, in which case, you're effectively creating a
>> > static array
>> > literal without any heap allocations).
>> > 
>> > Maybe that's more verbose than would be ideal, but it allows us
>> > to essentially
>> > have static array literals without having to add anything to
>> > the language.
>> > 
>> > - Jonathan M Davis
>> 
>> Ugly. Why not {1, 2, 3} or [1, 2, 3]s. The compiler could (as
>> long as necessary) rewrite this to your ugly solution.
>> But library solutions are always ugly and mostly bad and bug
>> prone. See scoped, Typedef and destroy.
>
> Walter and Andrei are very much against adding anything further to the
> language when it can be done in a library instead. {1, 2, 3} conflicts with C-
> style struct construction, and while [1, 2, 3]s is nice and short, all it does
> over staticLiteral([1, 2, 3]) is save some typing, and it requires language
> changes, whereas it's trivial in comparison to do something like this in a
> library. In fact, if we were to start over with D now, there would be a number
> of things that would just be in the library instead of the language (e.g.
> Andrei has stated several times that new should not have been a keyword and
> that it should have been handled by the standard library instead of the
> language). But it's too late for that now, so pretty much all of the stuff that
> might not end up the language if we were to start over is going to stay.
> However, that doesn't mean that we're going to be anything more like that in
> the language when we can do it in the library.
>
> - Jonathan M Davis
scoped waste a lot of space, Typedef is mostly unuseable and destroy is buggy with alias this and doesn't free the space (of course this is intended). I would prefer to do nothing, than a library solution. But let's wait and see. :)
December 10, 2013
On Tuesday, 10 December 2013 at 09:28:27 UTC, Jonathan M Davis wrote:
> On Tuesday, December 10, 2013 10:10:22 Namespace wrote:
> auto staticLiteral(T, size_t n)(T[n] literal)
> {
>     return literal;
> }
>
> auto staticArray = staticLiteral([1, 2, 3, 4]);

Why do you think this is possible? If an array literal should match _only_ dynamic array types, it would never work.

Because compiler will try to match array literal to static array T[n]. The feature which I have described is working here.

Kenji Hara
December 10, 2013
On Tuesday, December 10, 2013 11:19:45 Kenji Hara wrote:
> On Tuesday, 10 December 2013 at 09:28:27 UTC, Jonathan M Davis
> 
> wrote:
> > On Tuesday, December 10, 2013 10:10:22 Namespace wrote:
> > auto staticLiteral(T, size_t n)(T[n] literal)
> > {
> > 
> >     return literal;
> > 
> > }
> > 
> > auto staticArray = staticLiteral([1, 2, 3, 4]);
> 
> Why do you think this is possible? If an array literal should match _only_ dynamic array types, it would never work.
>
> Because compiler will try to match array literal to static array T[n]. The feature which I have described is working here.

It doesn't need to match only dynamic array types. The problem is when you have an overload. e.g.

auto foo(T[] arr) {...}
auto foo(T[3] arr) {...}

foo([1, 2, 3]);

Silently selecting one of the two is bug-prone - especially if it's the static one that gets selected, as in most cases, it would be the dynamic one which matches. Having dynamic array literals implicitly convert to static arrays when they're assigned to static arrays makes sense when there's no ambiguity.

And in general, something like staticLiteral should be unnecessary when passing to a function, as the array literal would be treated as a dynamic array or a static array depending on the function's parameters, but it could be useful in cases where you want to be explicit about the type or when using auto. And it may not be worth adding a function such as staticLiteral, but I think that it's better than trying to add static array literals to the language, particularly since we're trying to avoid adding features to the language when they can be implemented in the standard library instead.

- Jonathan M Davis
December 10, 2013
On 12/10/2013 08:29 AM, Kenji Hara wrote:
>
> This is an intended behavior. An array literal has dynamic array type
> *by default*.
> But all of literals in D behave as polymorphic.
>
> char c = 'A';   // character literal has char type by default
> dchar d = 'A';  // but it may be implicitly typed as wchar/dchar
>
> string str = "hello";
> dstring dstr = "hello";  // string literal is implicitly typed as dstring
>
> int[] darr = [1,2,3];
> int[3] darr = [1,2,3];   // implicitly typed as int[3]
>
> So, an array literal [1,2,3] is implicitly convertible both to int[] and
> int[3].
> And, int[3] is more specialized than int[], so overload resolution will
> choose the first 'bar'.
>
> Kenji Hara

Match with implicit conversion cannot be what is really happening as otherwise the following call would be ambiguous:


int bar(int[3] arr){
    return 1;
}

int bar(double[] arr){
    return 2;
}

int bar(int[] arr){
    return 3;
}

static assert(bar([1,2,3])==1);

December 10, 2013
On Tuesday, 10 December 2013 at 07:32:08 UTC, Marco Leise wrote:
> [1,2,3] looks like a static array to me. And if overload
> resolution picked the most specialized function it seems
> natural to call the int[3] version.
> My reasoning being that static arrays can be implicitly
> converted to dynamic array, but the reverse is not true. So I
> think it would be better to have [1,2,3] be a static array and
> keep the current behavoir, no?)

In early D1 age, array literals and string literals had had static array types which corresponding to the literals' element count. However it had caused template code bloat.

void foo(T)(T arg) { ... }

foo("aaa");   // instantiate foo!(char[3])
foo("bbbb");  // instantiate foo!(char[4])

foo([1,2]);    // instantiate foo!(int[2])
foo([1,2,3]);  // instantiate foo!(int[3])

So their types were changed to dynamic array by default.

Kenji Hara
December 10, 2013
Jonathan M Davis:

> and while [1, 2, 3]s is nice and  short, all it does
> over staticLiteral([1, 2, 3]) is save some typing, and it requires language changes,

[1, 2, 3]s  seems nice.