August 19, 2013
On Monday, 19 August 2013 at 16:53:06 UTC, Wyatt wrote:
> To be clear, I'm not talking about braces, {}; I'm talking about parentheses, ().  I read over that whole DIP32 thread a couple times, and didn't see any rationale offered for why the likely "cleanest" version "can't be used".  It wasn't even brought up (unless I've missed something subtle).  In the second thread, linked in the OP here, they were glossed over again.  Now, I fully believe there's a very good reason that's been written somewhere, but I _would_ like to know what that is, preferably documented somewhere less ephemeral and difficult to search than the newsgroup (such as in DIP32).  The closest I've seen so far is the pull request where Walter and Andrei expressed that it should be considered further.

I could very well be wrong, but I would bet that one of the reasons is that (a, b, c) expressions already have well-defined semantics in D (as well as (2, "a", func()). Example:

void main()
{
	import std.stdio;
	
        //Prints "a"
	writeln((true, false, "a"));
}

Making this a tuple literal would be a change in semantics, which I don't think would go over well and would break code. Another example:

void main()
{
	int a, b;
	(a, b) = (3, 4);
	assert(a == 0 && b == 4);
}

Of course, for the second case, Kenji's proposed syntax used "auto (a, b) = ...", which would disambiguate it, but it could confuse people as to whether the first syntax is somehow related to the second.

> The octothorpe _is_ much better than the t simply in terms of readability, though, even more than q{} or t{}, I have concerns about its ability to be found with an ordinary search engine by an ordinary user.  Have you tried looking for documentation on weird operators with a search engine lately?  They don't exactly take to it well. :/ (cf. Perl's <=>)

I'm not sure how much of a problem that would be. There's only one other syntactic form that uses # in D, but you're right, it may cause some difficulty trying to search "d programming #".

> Addressing the other suggestion I saw that cropped up, I personally find the two-character "bananas" to be impressively ugly.  I considered suggesting some permutation on that same idea, but after toying with a few examples I find it ends up looking awful and I think it's honestly annoying to type them in any form.  I even don't like how the unicode version of that one looks; for doubling up, I think ⟦ ⟧ or ⟪ ⟫ or are easier on the eyes.

My browser can't even display the second set of characters. D seems to have generally shied away from using any unicode operators (for a good reason. Who the hell has Σ on their keyboard?)

> I feel weird admitting this, but if we can't use some manner of bare brace, I think I'd rather have tup(), tup[], tup{} (or even tuple() et al) as a prefix over any single character.

It's not terrible, but it's rather wordy, especially if tuples begin to be used a lot in code.

> Can't make it a single underscore? Question mark works best then, IMO.  It isn't as burdened with meanings elsewhere (sure there's ternary and possibly-match in regex, but...have I forgotten something?)

It *could* be an underscore; the only thing is that the underscore is a valid variable name, so the above expression would actually be binding two variables, which might surprise someone who was expecting otherwise. I don't really care all that much, but it's something to think about.

> #(a, ...) looks like to me like it would make a 2-tuple containing a and a tuple of "everything else", because of the ellipsis' use in templated code.  I think this is a little unclear, so instead I'd prefer #(a, ? ...) (or whatever ends up used for the discard character) to make it explicit.

To be clear, what I have in mind is that this would be "a, plus (none/one?) or more things that can either be elements or nested tuples". Then, in a construction such as #(head, rest...), rest would be exactly as you describe: a tuple consisting of everything after head. The semantics could get tricky, maybe this needs more thought.

> As a bonus, explicit discard means a simple comma omission is less likely to completely change the meaning of the statement.  Compare:
> #(a, b, ...)   //bind the first two elements, discard the rest.
> #(a, b ...)    //bind the first element to a and everything else to b
> #(a, b, ? ...) //same as the first
> #(a, b ? ...)  //syntax error
>
> Granted, there's this case:
> #(a, ?, ...)
> ...but that seems like it would be less common just based on how people conventionally order their data structures.

That's true. Something to think about. Maybe combine the question mark and ellipsis like so:

#(a, b, ?..)

> Thought: Is there sufficient worth in having different tokens for discarding a single element vs. a range? e.g.
> #(a, ?, c, * ...) //bind first and third elements; discard the rest
> // I'm not attached to the asterisk there.
> // +, #, or @ would also make some amount of sense to me.

Not sure. I need to think about it.

>> - Concatenating tuples with ~. This is nice to have, but not particularly important.
>>
> What does concatenating a tuple actually do?  That is:
> auto a = #(1,2) ~ 3; //Result: a == #(1,2,3), right?
> auto b = a ~ #(4,5); //Is  b == #(1,2,3,#(4,5)) or is b == #(1,2,3,4,5)?

I think it should work the same as with arrays. So:

auto a = #(1, 2) ~ 3; //Error: 3 is not a tuple
auto a = #(1, 2) ~ #(3); //Result: #(1, 2, 3), just like an array

auto b = a ~ #(4, 5); //Result: #(1, 2, 3, 4, 5). Again, like arrays.

I think keeping the same semantics as arrays would be the best way to do it. I think it nicely follows the principle of least astonishment. If you wanted to explicitly append a tuple and have it nested, you'd need to do:

auto b = a ~ #(#(4, 5));

Which is messy, but at least it's explicit about what is going on.

> Great! After this, let's fix properties. ;)

Oh boy, no need to start *another* flame war.
August 19, 2013
On Monday, 19 August 2013 at 18:19:11 UTC, bearophile wrote:
>
> The ? of regexes is inside strings, so I think it causes no problems. And I think it doesn't clash with the ternary operator because before the ? wildcard you put a comma, a semicolon or a #(.
>
I was primarily addressing the fact that there aren't many _meanings_ attached to the same character.  This was brought up before when someone talked about using an asterisk, but it was pointed out that it would be a bad choice because it's already commonly seen in multiplication, pointers, and exponentiation (**).

If anything, I'm inclined to think the regex heritage of the question mark improves its case.

-Wyatt
August 19, 2013
Realistically, Andrei, how amenable are you and Walter to adding tuple literal/packing&unpacking/pattern matching syntax to D, be it Tuple, TypeTuple, whatever? I don't recall either of you commenting much in the two other discussion threads linked. We can discuss this all day, but it what are the actual chances of you agreeing to such a large change in the language?

August 19, 2013
On 08/19/2013 07:44 PM, H. S. Teoh wrote:
> Well, OK, whatever they're supposed to be called. Compiler-tuples, or
> expression tuples, or whatever. See, part of the problem is that they
> just don't have any good name that correctly conveys what they are.
>

They are simply template argument lists.

(http://wiki.dlang.org/The_D_Programming_Language/Seq)
August 19, 2013
Meta:

> It *could* be an underscore; the only thing is that the underscore is a valid variable name, so the above expression would actually be binding two variables, which might surprise someone who was expecting otherwise. I don't really care all that much, but it's something to think about.

You can't define a variable more than once in a scope, so this can't be valid:

void main() {
    auto t1 = #(5, "hello", 1.5);
    auto (_,  _, x) = t1;
    auto (_, gr, _) = t1;
}


While ? defines nothing, so this is OK:

void main() {
    auto t1 = #(5, "hello", 1.5);
    auto (?,  ?, x) = t1;
    auto (?, gr, ?) = t1;
}

Bye,
bearophile
August 19, 2013
On Monday, 19 August 2013 at 19:54:43 UTC, bearophile wrote:
> ...

That too.
August 19, 2013
> void main() {
>     auto t1 = #(5, "hello", 1.5);
>     auto (_,  _, x) = t1;
>     auto (_, gr, _) = t1;
> }

I need to get used to the proposed syntax, sorry:

void main() {
    auto t1 = #(5, "hello", 1.5);
    auto #(_,  _, x) = t1;
    auto #(_, gr, _) = t1;
}

Bye,
bearophile
August 19, 2013
On 8/19/13 11:14 AM, Dicebot wrote:
> On Monday, 19 August 2013 at 18:11:34 UTC, Andrei Alexandrescu wrote:
>> I'd call them alias tuples.
>
> Because we don't have strict definition of alias too? :)

I'm thinking such a tuple may hold everything that one may define an alias to.

Andrei

August 19, 2013
On Monday, 19 August 2013 at 20:36:10 UTC, Andrei Alexandrescu wrote:
> On 8/19/13 11:14 AM, Dicebot wrote:
>> On Monday, 19 August 2013 at 18:11:34 UTC, Andrei Alexandrescu wrote:
>>> I'd call them alias tuples.
>>
>> Because we don't have strict definition of alias too? :)
>
> I'm thinking such a tuple may hold everything that one may define an alias to.

Normal alias or template alias parameter? ;) Because those two are different :P Former can't take lambda literals. Latter won't accept built-in types like int.

But built-in tuple is fine with both. "T..." is a _very_ special thing in D.

August 19, 2013
On 8/19/13 11:54 AM, Meta wrote:
> Realistically, Andrei, how amenable are you and Walter to adding tuple
> literal/packing&unpacking/pattern matching syntax to D, be it Tuple,
> TypeTuple, whatever? I don't recall either of you commenting much in the
> two other discussion threads linked. We can discuss this all day, but it
> what are the actual chances of you agreeing to such a large change in
> the language?

We'd be fools to reject a valuable addition to the language. That being said, there's no broad agreement on what's needed and what's to be added. Furthermore, most discussions are disproportionally focused on syntax (as opposed to semantics) and fall for syntactic cutesies instead of simple and robust library support. That in my experience is a bad omen. Now _that_ being said, if and when a gem comes about, we hope to have the insight to see it.


Andrei