A Discussion of Tuple Syntax

Meta jared771 at gmail.com
Mon Aug 19 11:43:35 PDT 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.


More information about the Digitalmars-d mailing list