On Saturday, 14 October 2017 at 23:20:26 UTC, sarn wrote:
On Saturday, 14 October 2017 at 22:20:46 UTC, Q. Schroll wrote:
Therefore, and because of brackets, you can distinguish f(1, 2) from f([1, 2]).

But in f([1, 2]), it's ambiguous (just by parsing) whether [1, 2] is a tuple literal or a dynamic array literal.

It would be a tuple if that's the best match, otherwise conversion to int[] is tried. Even today, [1, 2] is ambiguous: Is it a static or a dynamic array of int? Is it of type int[2] or int[]? The spec says, it depends what you do with it! We can progress that and enlarge the int[2] version to [int, int] -- a special case of a 2-tuple. It remains the same: If [1, 2] can be used as a dynamic array, it will be. If not, the compiler tries a static array. With tuples, it would try a tuple. If f has an overload taking int[] or something similar, it will treat [1, 2] as a dynamic array with homogeneus types. If the objects are not compatible, an error occurs like "tuple [..contents..] cannot be implicitly converted to T[]". Else, if it has an overload for a compatible (length, implicit conversion) tuple, that will be taken. Consider
   void f(int[2] v) { } // (1)
   void f(int[ ] v) { } // (2)
Here, f([1, 2]) calls (1) as it is the better match. Yet with
   auto x = [1, 2];
f(x) calls (2) because of strict typing. So while [1, 2] is of type int[2] or [int, int] as a tuple, typeof([1, 2]) will still yield int[]. You cannot ask the one and only correct type of []-literals as they have more than one type. Even if the values are incompatible like [1, "a"], asking typeof([1, "a"]) will result in an error, because in typeof deduction, []-literals must result in dynamic arrays. This holds for auto, because auto has the same rules.
   auto tup = [1, "a"];
must fail. You'd need
   [auto, auto] tup = [1, "a"];
or maybe some shorthand syntax that lowers to this.

You'd need to use a prefix or something to the bracket syntax.
[snip]

I just argued, you don't!

The reason there is no such prefix and not even a function in Phobos, is it is a trivial task to make one.
    T[n] s(T, size_t n)(T[n] elem ...) { return elem; }
    static assert(is(typeof(s(1, 2, 3)) == int[3]));
    static assert(is(typeof([1, 2, 3].s) == int[3]));
    auto x = s(1, 2, 3);
    static assert(is(typeof(x) == int[3]));
    auto x = s(1, 2.0, 3);
    static assert(is(typeof(x) == double[3]));
Try it yourself. It works fine. Instead of s one would use t or tuple to allow incompatible types.

Reply via email to