proposed syntax for tuple: t{} and TypeTuple: T{} (cf precedent of q{...})

ZombineDev via Digitalmars-d digitalmars-d at puremagic.com
Tue Apr 5 13:48:54 PDT 2016


On Tuesday, 5 April 2016 at 20:13:59 UTC, Timon Gehr wrote:
> On 05.04.2016 17:29, ZombineDev wrote:
>> On Tuesday, 5 April 2016 at 05:45:08 UTC, Timothee Cour wrote:
>>> {} for tuples hasn't worked out since it was deemed ambiguous 
>>> with
>>> delegate syntax (was it for the case of empty 
>>> statements/tuple?).
>>>
>>> How about the following syntax instead:
>>>
>>> ----
>>> {} // delegate (existing syntax)
>>> q{...} // string literal (existing syntax)
>>> t{...} // tuple(a,b) (proposed syntax)
>>> T{...} // TypeTuple!(a,b) (proposed syntax)
>>> ----
>>>
>>> See also [1] where i propose i{...} for a D analog of C++11's 
>>> uniform
>>> initialization.
>>>
>>>
>>> [1] EMAIL: uniform initialization in D (as in C++11): i{...}
>>
>> I don't think that t or T is needed in front of {}.
>>
>> 1) Function literals / lambdas / delegates:
>> If someone wants an empty function literal, they just have to 
>> use (){}
>> instead of {}:
>> alias Action = void delegate();
>> Action action = (){}; // instead of
>> Action action = {}; // error: `{}` is an empty tuple, can't be 
>> assigned
>> to delegates
>
> (This specific case would actually be unproblematic. {} can be 
> polysemous.)
>
>> auto t = {}; // deduced as an empty tuple.
>> Also, the non-empty {} syntax can't be mistaken for a function 
>> literal
>> because non-empty function literals always have at least one 
>> statement
>> that ends with a semicolon.
>>
>> 2) Tuples and AliasSeq-s.
>> Correct me if I'm wrong, but I think that in all cases the 
>> expression is
>> unambiguous:
>> auto t1 = {3, 4}; // Tuple
>> enum t2 = {3, 4}; // Tuple
>> alias t3 = {3, 4}; // AliasSeq
>> ...
>
> This is moot.
>
> template T(alias a,alias b){}
> template T(alias a){}
>
>
> T!({1,2}) // <- ?

The answer to this question and all similar cases is that is that
{1,2} is rewritten to AliasSeq!(1, 2). In this particular case it 
auto-expands and calls the T template with two alias parameters.

> Note that template alias parameters can accept values. (Other 
> alias declarations can too, possibly depending on how you look 
> at it; the language grammar is a little warty there.)

Yes I know. And I see no problem with this.

template K(alias fun, alias var, size_t idx, string str, T, Y...)

int local = 42;

K!(AliasSeq!(x => x * 2, local, 1 + 5, "asd", int, float, 
double));
K!({ x => x * 2, local, 1 + 5, "asd", int, float, double });
// also the same as:
K!(x => x * 2, local, 1 + 5, { "asd", int, {float, double} });

> I don't think there should be separate syntax for 'AliasSeq' 
> especially if it resembles tuple syntax. (The design is already 
> confusing enough, for no gain.)

Well it would be a pretty big whole in the language if you could 
do tuple, but not alias sequences. Also it's nice to do:

{float, float} scale({float, float} vec, float x)
{
     return vec * x;
}

>> void foo(Tuple!(int, int) x);
>> foo({3, 4}); // same as foo(t1), or foo(t2)
>>
>> template staticMap(alias F, T...);
>> alias constTypes = staticMap!(  constOf, { int, float, void[] 
>> } );
>> static assert (is(  constTypes == { const(int), const(float),
>> const(void[]) }  );
>>
>> writefln!({int, string, double})("%s %s %s", {3, "test", 4.2});
>
> That highlights another flaw in AliasSeq. This should do the 
> trick, but does not:
> alias constTypes = const(AliasSeq!(int,float,void[]));
> pragma(msg, constTypes); // (int, float, void[]) // wat?
>
>
> This means that
>
> auto a=...;
> const b=a;
>
> is not always the same as
>
> auto a=...;
> const(typeof(a)) b=a;

Yeah this looks like a bug in the current implementation. I also 
find the following limitation unfortunate:

struct Point3 { int x, y, z; }

Point3 a, b, c;
c = a.tupleof + b.tupleof; // doesn't work :(



More information about the Digitalmars-d mailing list