Re: A Discussion of Tuple Syntax

2013-08-21 Thread Michel Fortin
On 2013-08-21 16:59:17 +, Andrei Alexandrescu 
 said:



On 8/20/13 8:25 PM, Michel Fortin wrote:

On 2013-08-21 00:38:30 +, Andrei Alexandrescu
 said:


1. What do we need?


I think D needs less tuples. It has two kinds (language kind and
Phobos's kind), which is confusing. It should have just one that covers
most use cases.


Yah, fewer tuples (or assigning distinct names to what we call today 
such) would be awesome.


That seems like the only thing everyone agrees with. :-)


I'm unfortunately lost already. I was discussing tuples as in 
"anonymous structs", not as in "template tuples".


Well, the original post that started this discussion talked about both. 
I don't think narrowing it only to "anonymous structs" is going to 
solve the syntax problem as a whole.




 int a, b, c, d, e, f;
 swap(...(a, c, e), ...(b, d, f));


This looks like an example taken from a book in which "..." means some 
stuff is omitted.


Seriously, the major issue with tuples is a conceptual one. No pretty 
syntax is going to fix it alone. Unfortunately, talking about concepts 
requires inventing a syntax for them. The syntax then immediately get 
dismissed as ugly/impractical and no thought is given to what's under 
it. No wonder this is getting nowhere for the nth time when everyone 
thinks so superficially.


Just disregard the "..." syntax. It makes sense in the context of my 
other post. There's no way to appreciate it without that context (and 
even then, it can surely be improved).


The idea (in my other post) was to un-cripple language-level tuples 
with one simple fundamental change: allow them to be packed and 
expanded. With that you can cover 99% of what you want from a tuple 
struct using the built-in language-level tuple. Plus you can do some 
other things like the swap of aliases to variables shown above.


There is no reason for template-argument-tuples to be auto-expanding. 
If you fix that, as I proposed in my other post, you'll almost never 
need a library struct template to represent a tuple anymore. Thus, 
fewer tuples.


--
Michel Fortin
michel.for...@michelf.ca
http://michelf.ca



Re: A Discussion of Tuple Syntax

2013-08-21 Thread Walter Bright

On 8/20/2013 1:10 PM, Jonathan M Davis wrote:

On Tuesday, August 20, 2013 13:06:27 H. S. Teoh wrote:

On Tue, Aug 20, 2013 at 11:53:50AM -0700, Andrei Alexandrescu wrote:

Somebody shoot me.


[...]

BANG!


Don't kill him. He hasn't finished the allocators yet! ;)


Don't worry, we'll keep sliding food under his door!



Re: A Discussion of Tuple Syntax

2013-08-21 Thread bearophile

Zach the Mystic:

I agree. The negative space *around* the bikeshed should be 
used...


Andrei missed the point of that part of the discussion. That was 
not an explanation of the usefulness of wildcards, it was a small 
explanations of why probably you can't use '_' as wildcard 
symbol. The examples I have shown were not meant to show why 
wildcards are very useful in a rounded tuple design.




auto (void, void, x) = t1;

(Just an idea I had. Don't know whether it's technically sound. 
It just seemed so funny to me that the idea popped into my head 
as soon as you said "rainbow". Not trying to waste time. )


That is perhaps technically acceptable, but it's longer.

Bye,
bearophile


Re: A Discussion of Tuple Syntax

2013-08-21 Thread bearophile

H. S. Teoh:

This is adequately taken care of by std.typecons.Tuple, isn't 
it?


You can't make 'i' a runtime value because D is a 
statically-typed language.


Yep. (From several persons explaining me similar things in 
answers to my posts it seems I am not expressing well that I know 
what I am discussing about. In future I will add notes to avoid 
this).




Currently you could do:

Tuple!(...) t1;
auto a = t1[0];
auto b = t1[1];

Not as nice, certainly, but I wouldn't consider it a 
deal-breaker.



Currently we have:

auto mult = (Tuple!(int,int) t) => t[0] * t[1];

Not as pretty, but surely still readable and usable? Or am I 
missing

something?


I didn't look in detail at your red-black tree example, or the 
Huffman
encoding example, but it would seem that currently, 
std.typecons.Tuple
more-or-less suffices for your needs, right? Except for some 
syntactic unpleasantness, that is.


Or is there something that *can't* be expressed in an adequate 
way by the current Tuple that I missed?


See what I wrote at the beginning of the post:


We can live fine without a syntax to manage tuples, so strictly
speaking we need nothing


The semantics of tuples is simple and everything you can do when 
them is very easy to do in a language like C. The point of having 
tuples is to write code that is more readable, shorter, more 
expressive, a bit higher level. std.typecons.Tuple misses some 
expressiveness that some programmers think is handy to have, that 
I have listed in my post.



What should happen if s is a runtime variable that may not have 
the same
number of words as the number of elements in the tuple on the 
left-hand

side? A runtime error?


Again, what should happen if at runtime the lines have more or 
less

elements than the tuple on the left-hand side? A runtime error?


The answer I wrote in another post:

Runtime boundary checks and tests are not needed if you unpack 
a fixed-sized array:


auto tup = Tuple!(int, string[2])(1, ["red", "blue"]);
auto {x, [c1, c2]} = tup;

Regarding the de-structuring of dynamic arrays, I think it's 
not too much different than this:


void main() {
int[] a = [10, 20, 30];
int[2] b = a;
}

If you compile and run it without switches, you get at run-time:

object.Error: lengths don't match for array copy, 2 = 3


While I receive no run-time errors if I compile with 
-noboundscheck.




Isn't this an auto-expanding tuple that Andrei didn't like?


I don't know. Ask to him.

Bye,
bearophile


Re: A Discussion of Tuple Syntax

2013-08-21 Thread Dicebot
On Wednesday, 21 August 2013 at 03:39:32 UTC, Jonathan M Davis 
wrote:
But I see no reason to try and combine any of that with Tuple, 
as Tuple and

TypeTuple do fundamentally different things.


TypeTuple does not cover all built-in tuple cases. There is also 
built-in expression/run-time tuple which is also native to 
language but differs from library std.typecons.Tuple _only_ with 
lack of ABI.


You may underestimate the mess here.


Re: A Discussion of Tuple Syntax

2013-08-21 Thread Zach the Mystic
On Monday, 19 August 2013 at 20:46:02 UTC, Andrei Alexandrescu 
wrote:

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

Bye,
bearophile


It's stuff like this that's just useless and gives a bad 
direction to the whole discussion. There's hardly anything 
wrong with auto x = t1[2] or auto gr = t1[1], but once the 
bikeshed is up for painting, the rainbow won't suffice.



Andrei


I agree. The negative space *around* the bikeshed should be 
used...


auto (void, void, x) = t1;

(Just an idea I had. Don't know whether it's technically sound. 
It just seemed so funny to me that the idea popped into my head 
as soon as you said "rainbow". Not trying to waste time. )


Re: A Discussion of Tuple Syntax

2013-08-20 Thread H. S. Teoh
On Wed, Aug 21, 2013 at 03:43:45AM +0200, bearophile wrote:
> Andrei Alexandrescu:
> 
> >1. What do we need?
> 
> We can live fine without a syntax to manage tuples, so strictly
> speaking we need nothing (almost, I'd like to kill one currently
> accepted syntax, see below).
> 
> But when you write D in a high-level style, and you are used to
> other functional or scripting languages, in several cases you desire
> a more handy/compact syntax to manage tuples.
> 
> Tuples are simple data structure, so the operations you want to do
> with them are few and simple:
> - To define a tuple of various fields of different type, that is a
> tuple literal, to create a tuple;

This is adequately taken care of by std.typecons.Tuple, isn't it?


> - A way to read and write items of a tuple (unless it's read-only),
> D uses a nice syntax [i] as arrays indexing, but i can't be a
> run-time value.

You can't make 'i' a runtime value because D is a statically-typed
language. The compiler has to know at compile-time what type tup[i] is.
Otherwise it couldn't generate machine code for things like:

void func(Tuple t, int i) {
auto x = t[i];  // what's the type of x?
}


> - With the Phobos tuple we are used to giving names to fields. It's
> handy, but it's not so necessary if you have a way to assign tuple
> items to variables, defined in-place. There are several places where
> pulling apart a tuple in that way is useful, here I use a basic
> syntax to be more clear:
> 
> Assignments:
> auto (a, b) = t1;

Currently you could do:

Tuple!(...) t1;
auto a = t1[0];
auto b = t1[1];

Not as nice, certainly, but I wouldn't consider it a deal-breaker.


> In function signatures:
> auto mult = ((int x, int y)) => x * y;

Currently we have:

auto mult = (Tuple!(int,int) t) => t[0] * t[1];

Not as pretty, but surely still readable and usable? Or am I missing
something?


> In foreach loops:
> 
> void main() {
>   import std.range, std.stdio;
>   auto a = [10, 20];
>   auto b = [100, 200];
> 
>   // Currently D supports this syntax:
>   foreach (x, y; zip(a, b))
> writeln(x, " ", y);
> 
>   // But it's unreliable, now x is the index of the
>   // array instead of the first tuple fields, so I
>   // think this feature of D should be killed as
>   // soon as possible:
>   foreach (x, y; zip(a, b).array)
> writeln(x, " ", y);
> }

Isn't this an auto-expanding tuple that Andrei didn't like?

Though granted, the current way of expressing it is not as nice:

foreach (t; zip(a,b)) {
writeln(t[0], " ", t[1]);
}


[...]
> There are few more little pieces that are useful, like unpacking an
> array:
> 
> string s = "red blue";
> auto (col1, col2) = s.split;

What should happen if s is a runtime variable that may not have the same
number of words as the number of elements in the tuple on the left-hand
side? A runtime error?


[...]
> For an use case of the assignment from an array, let's say you have
> a text file containing two numbers in a line, that you want to read:
> 
> const (x, y) = filein.byLine.front.split.to!(int[]);
[...]

Again, what should happen if at runtime the lines have more or less
elements than the tuple on the left-hand side? A runtime error?

I didn't look in detail at your red-black tree example, or the Huffman
encoding example, but it would seem that currently, std.typecons.Tuple
more-or-less suffices for your needs, right? Except for some syntactic
unpleasantness, that is.

Or is there something that *can't* be expressed in an adequate way by
the current Tuple that I missed?

Also, I note that none of your examples need TypeTuples at all, so it
would appear that your use case do not necessitate the unification of
TypeTuple with Tuple. Though that would be nice conceptually, it does
introduce a lot of complications into the language and require
addressing some non-trivial issues which, taking a step back, perhaps we
don't *need* to address, because they are of little or no practical use?


T

-- 
Knowledge is that area of ignorance that we arrange and classify. -- Ambrose 
Bierce


Re: A Discussion of Tuple Syntax

2013-08-20 Thread eles
On Wednesday, 21 August 2013 at 00:38:31 UTC, Andrei Alexandrescu 
wrote:

On 8/20/13 5:28 PM, Tyler Jameson Little wrote:
Instead there have been 1001 proposals for new syntax for tuple 
literals, one cuter than the next.


I agree. However, that syntax issue is the bikeshed and it keeps 
everyone's mind busy. So, I propose to pick-up a syntax, even a 
provisional one, let's say that &(a,b) that I kinda like, then 
stick with it.


This will free the way for more important and fundamental issues 
and, on the way, it will also allow to discover the eventual 
shortcomings of the syntax that was picked-up.


Re: A Discussion of Tuple Syntax

2013-08-20 Thread Meta
On Wednesday, 21 August 2013 at 00:38:31 UTC, Andrei Alexandrescu 
wrote:

1. What do we need?


Nothing. Everything discussed thus far can already be done in D, 
but with either a little or a lot of tedium and error-prone 
hackery. What I think would benefit D is a 
cleanup/simplification/sugarization of the current tuple 
situation. TypeTuple causes no end of grief and confusion.



2. What does a solution look like in the current language?


See Kenji's DIP for Bearophile's example of tuple use in the 
current language. Throughout this discussion there have also been 
several other examples of how TypeTuple misbehaves.


3. Which parts of the solution are frequent/cumbersome enough 
to warrant a language change?


IMO, TypeTuple auto-expansion and mixing of data/types within the 
same TypeTuple. It's also annoying that TypeTuples are not 
first-class values, and it would be a pity if we did not come up 
with some sort of tuple literal syntax, but that situation can be 
worked around by wrapping it in Tuple.


Instead there have been 1001 proposals for new syntax for tuple 
literals, one cuter than the next.


Wouldn't you call this characterization a little unfair, when 
there were numerous posts also discussing relevant issues and 
semantics? I'd say the ratio of form:function has been pretty 
good thus far.




Re: A Discussion of Tuple Syntax

2013-08-20 Thread deadalnix
On Tuesday, 20 August 2013 at 18:51:23 UTC, Andrei Alexandrescu 
wrote:

On 8/19/13 11:39 PM, Timon Gehr wrote:

On 08/20/2013 02:18 AM, Andrei Alexandrescu wrote:


Why would it be necessary to return an object of type 
TypeTuple (i.e.

template tuple)?



- Elegance. Eg:

auto seq(T...)(T arg){ return arg; }

auto fold(alias a,S,R)(S start, R range){ ... }


seq(0,[1,2,3]).fold!((a,b)=>a+b);


But this is again a value tuple not a template tuple, no?

Andrei


A value tuple IS a tuple. What we call a tuple here as nothing to 
do with a tuple.


Re: A Discussion of Tuple Syntax

2013-08-20 Thread Jonathan M Davis
On Tuesday, August 20, 2013 23:25:03 Michel Fortin wrote:
> On 2013-08-21 00:38:30 +, Andrei Alexandrescu
> 
>  said:
> > 1. What do we need?
> 
> I think D needs less tuples. It has two kinds (language kind and
> Phobos's kind), which is confusing. It should have just one that covers
> most use cases.

I honestly think that trying to combine Tuple and TypeTuple would increase the 
confusion, because you'd be forcing the compiler to decide what you meant in 
any given situation, and from the programmer's perspective, it will frequently 
be non-obvious whether what's being done is being done at compile time or at 
runtime.

The main problem I see is that TypeTuple is badly named. Heck, the fact that 
it's even referred to as a tuple is problematic, since it isn't really, as it 
always expands. And the fact that it's the "built-in" tuple but requires a 
library solution to be able to actually declare it is a bit odd. So, I think 
that creating as syntax for the built-in tuples in order to get rid of 
TypeTuple would clean things up.

But I see no reason to try and combine any of that with Tuple, as Tuple and 
TypeTuple do fundamentally different things. The main gain I see is simply in 
cleaning up the naming mess, and by making it so that the built-in tuple 
actually has a built-in syntax, the language is cleaner and should be easier 
to understand (especially if we can come up with a name other than tuple or 
built-in tuple to call them so that they stop getting confused with Tuple).

- Jonathan M Davis


Re: A Discussion of Tuple Syntax

2013-08-20 Thread Michel Fortin
On 2013-08-21 00:38:30 +, Andrei Alexandrescu 
 said:



1. What do we need?


I think D needs less tuples. It has two kinds (language kind and 
Phobos's kind), which is confusing. It should have just one that covers 
most use cases.


So in essence a tuple should:

1. be able to contain anything you can put as a template argument
2. be able to be packed and expanded as needed

And the above should be usable in these situations:

- using a type tuple as a variable's type
- unpacking a tuple as function/template arguments
- using a tuple as a return type
- assigning a value tuple to an alias-of-variables tuples
- using foreach with a tuple
- pass a tuple by reference to a function
- return a tuple by reference from a function
- slice a tuple
- concat tuples

I'm on the fence about taking the address of a tuple. Not being able to 
take the address has an upside: if the function call ABI pass each 
component of a tuple as one ref parameter under the hood, then you 
could pass tuple of aliases as function arguments. For instance, here 
I'd be swapping variables a, c, and e with variables b, d, and f with 
just one call to swap:


int a, b, c, d, e, f;
swap(...(a, c, e), ...(b, d, f));

(Note: using "..." syntax to create packed tuple literals. See my other 
post about how that'd work.)


--
Michel Fortin
michel.for...@michelf.ca
http://michelf.ca



Re: A Discussion of Tuple Syntax

2013-08-20 Thread Michel Fortin
On 2013-08-20 20:16:48 +, Andrei Alexandrescu 
 said:



On 8/20/13 6:57 AM, Dicebot wrote:

Preserve
auto-expansion.


That would be problematic to say the least. (There have been a few 
discussions in this group; I've come to think auto expansion is fail.)


I used to like auto expansion, probably because it was convenient for 
what I was doing. I always feared that not having auto-expansion would 
make my code ugly.


But now that I've been working with C++11 with its variadic template 
parameters that don't auto expand, I'm quite fond of it. To expand a 
"tuple" all you have to do is suffix it with "...", example:


template < typename A, typename B, typename... C >
shared_ptr< Expression > make_exp(Operator op, A first, B second, C... 
more)
{
return make_exp(op, make_exp(op, first, second), more...);
}

Now, if we could get rid of auto expansion while requiring a "..." 
suffix to expand a tuple, I think it'd be really great. Can't we steal 
this from C++?


What follows is how I'd transpose this to D.

First, let's put the three-dots *before* the template argument 
(somewhat as in C++) to get a packed tuple. This will ensure backward 
compatibility (if you put the three-dots after, like current D, you'd 
still get an auto-expanding tuple):


Expression make_exp(A, B, ...C)(Operator op, A first, B second, C... 
more)
{
return make_exp(op, make_exp(op, first, second), more...);
}

Basically, the rule is simple: three dots before an expression means 
"pack", three dots after it means "expand".


In the example above, the template argument C is a packed tuple type. 
Expanding C in the function's argument list means that we're expecting 
arguments to come as separate argument and not as one packed tuple 
argument. Those separate arguments get packed into the "more" parameter 
variable, which is of type C, which is then expanded as requested by 
the three-dot suffix when calling the function.


Extrapolating things a little, a packed tuple type could be expressed 
like this:


...(int, double) x; // a packed type tuple variable
x = ...(1, 2.3); // create a packed value tuple and assign it to x.
writeln(x...); // expand tuple to make it two separate arguments
writeln(x); // keep it packed and you're passing it as one argument

...(int, ...(double, float)) y; // nested tuples

Also, you can take an auto-expanding tuple and make it packed:

template (X...)
{
...(X) x; // auto-expanding tuple becomes packed
}

Which is the same as making it packed directly from the argument list:

template (...X)
{
X x; // already packed tuple
}

And since this is a "language-type" tuple, it can contain a mix of 
expression, types, aliases, etc, and therefore can be used like this:


	...(int, "ha!", writeln); // can contain anything usable as a template 
argument


Other examples:

int x;
double y;
...(x, y) = ...(1, 2.3); // multiple assignments
...(x, y) = getPackedTuple();

And finally, we could support expanding whole expressions that have a 
packed tuple in them by shifting the expanding three-dot outward, as 
you can do with C++11:


...(int, double) x;
func(exp(x+5)...); // expands to: func(exp(x[0]+5), exp(x[1]+5));

Wouldn't that be great?

After some time, if desired, auto-expanding tuples could be deprecated. 
The migration path wouldn't be too hard, nor too verbose: just add 
those three-dots right and left as needed.


--
Michel Fortin
michel.for...@michelf.ca
http://michelf.ca



Re: A Discussion of Tuple Syntax

2013-08-20 Thread Dicebot

On Wednesday, 21 August 2013 at 01:50:49 UTC, Dicebot wrote:
On Wednesday, 21 August 2013 at 00:38:31 UTC, Andrei 
Alexandrescu wrote:
I think this whole thread is approaching things wrongly. It 
should be:


1. What do we need?


Also my answer to this question may probably be not very 
mainstream according to this thread :) I thing that most of all 
we need definition-driven tuple classification as opposed to 
current behavior-driven one (here is the built-in tuple and look 
what shiny stuff it can do).


Everything else is just a consequence.



Re: A Discussion of Tuple Syntax

2013-08-20 Thread Dicebot
On Wednesday, 21 August 2013 at 00:38:31 UTC, Andrei Alexandrescu 
wrote:
I think this whole thread is approaching things wrongly. It 
should be:


1. What do we need?

2. What does a solution look like in the current language?

3. Which parts of the solution are frequent/cumbersome enough 
to warrant a language change?


Exactly. Though if we want to avoid breaking changes as much as 
possible, maybe it should be more like this:


2. What use cases current language state cover?

3. How it can me remodeled to have less confusing semantics / 
definitions while covering as much old behavior as possible?


I am struggling at (3) because current applications love to 
contradict each other when any relatively simple rule set is 
imagined.


Basically there are 3 distinct (according to allowed usage) cases 
for built-in tuples:


1) pure type-tuple
2) mixed compile-time tuple (literals and other compile-time 
expressions go here)

3) run-time tuple over set of variables/parameters

As far as I can see, covering std.typecons.Tuple in similar way 
is trivial - but re-defining those 3 in a meaningful way is 
really challenging. Maybe you have any opinion as a concept 
author? :P


Re: A Discussion of Tuple Syntax

2013-08-20 Thread bearophile

Andrei Alexandrescu:


1. What do we need?


We can live fine without a syntax to manage tuples, so strictly 
speaking we need nothing (almost, I'd like to kill one currently 
accepted syntax, see below).


But when you write D in a high-level style, and you are used to 
other functional or scripting languages, in several cases you 
desire a more handy/compact syntax to manage tuples.


Tuples are simple data structure, so the operations you want to 
do with them are few and simple:
- To define a tuple of various fields of different type, that is 
a tuple literal, to create a tuple;
- A way to read and write items of a tuple (unless it's 
read-only), D uses a nice syntax [i] as arrays indexing, but i 
can't be a run-time value.
- With the Phobos tuple we are used to giving names to fields. 
It's handy, but it's not so necessary if you have a way to assign 
tuple items to variables, defined in-place. There are several 
places where pulling apart a tuple in that way is useful, here I 
use a basic syntax to be more clear:


Assignments:
auto (a, b) = t1;

In function signatures:
auto mult = ((int x, int y)) => x * y;

In foreach loops:

void main() {
  import std.range, std.stdio;
  auto a = [10, 20];
  auto b = [100, 200];

  // Currently D supports this syntax:
  foreach (x, y; zip(a, b))
writeln(x, " ", y);

  // But it's unreliable, now x is the index of the
  // array instead of the first tuple fields, so I
  // think this feature of D should be killed as
  // soon as possible:
  foreach (x, y; zip(a, b).array)
writeln(x, " ", y);
}


Its output:

10 100
20 200
0 Tuple!(int, int)(10, 100)
1 Tuple!(int, int)(20, 200)


In (final) switch cases, this also shows one use case and one 
usefulness of wildcards (and the usage of an unapply() standard 
method, as explained a bit here: 
http://d.puremagic.com/issues/show_bug.cgi?id=596 ):


final switch (tup1) {
case (0, 10): break;
case (0,  ?): break;
case (?,  ?): break;
}


An nice example usage of such basic pattern matching is visible 
here, to implement the insertion in a red-black-tree. This is a 
well known hairy operation to do in languages as C:

http://rosettacode.org/wiki/Pattern_matching


This is how insertion and balancing is done in Haskell (this 
needs long lines and it probably comes out unreadable here, so 
see here for a better visualization: 
http://rosettacode.org/wiki/Pattern_matching#Haskell ):


data Color = R | B
data Tree a = E | T Color (Tree a) a (Tree a)

balance :: Color -> Tree a -> a -> Tree a -> Tree a
balance B (T R (T R a x b) y c  ) z d 
  =

T R (T B a x b) y (T B c z d)
balance B (T R a   x (T R b y c)) z d 
  =

T R (T B a x b) y (T B c z d)
balance B a   x (T R (T R b y c) z d  
) =

T R (T B a x b) y (T B c z d)
balance B a   x (T R b   y (T 
R c z d)) =

T R (T B a x b) y (T B c z d)
balance col a x b = T col a x b

insert :: Ord a => a -> Tree a -> Tree a
insert x s = T B a y b where
  ins E  =  T R E x E
  ins s@(T col a y b)
| x < y  =  balance col (ins a) y b
| x > y  =  balance col a y (ins b)
| otherwise  =  s
  T _ a y b = ins s



There are few more little pieces that are useful, like unpacking 
an array:


string s = "red blue";
auto (col1, col2) = s.split;


Hara has suggested pattern matching in if statements, that is a 
special case of the pattern matching in switch cases, and it's 
sometimes useful (similar code is common in Scala):


if (auto {1, y} = tup) {...}

That is equivalent to:

if (tup[0] == 1) {
auto y = tup[1];
...
}

It looks simple and not so essential, but when tuples become a 
little more more complex pattern matching shows it usefulness 
better, as in the Haskell example.


Languages as Haskell and Rust also show that even a simple 
version of pattern matching is handy when you manage types like 
Nullable() (that need to define an unapply() standard method).



(It's not unthinkable to support pattern matching in function 
signatures too, as often used in many functional languages as 
OCaML and Haskell, but this is an orthogonal feature, it could be 
added later, and we can probably live without it for now).



Others have suggested a syntax with ... to gather more than one 
item, or to ignore more than one item with ?...  Such syntax is 
handy with arrays but with tuples, that are often short and of 
well known size I think it's not so much useful, so it can be 
left for later.




2. What does a solution look like in the current language?


The DIP32 shows a complete very small program that I wrote for 
RosettaCode site, it computes the Huffman encoding of a given 
string:

http://wiki.dlang.org/DIP32


import std.stdio, std.algorithm, std.typecons, std.container, 
std.array;


auto encode(T)(Group!("a == b", T[]) sf) {
auto heap = sf.map!(s => tuple(s[1], [tuple(s[0], "")

Re: A Discussion of Tuple Syntax

2013-08-20 Thread Kenji Hara
2013/8/21 Andrei Alexandrescu 

> I think this whole thread is approaching things wrongly. It should be:
>
> 1. What do we need?
>

Both
a. Built-in tuple construction syntax
and
b. Built-in tuple deconstruction syntax

2. What does a solution look like in the current language?
>

a.
  alias Types = {int, long};
  auto values = {1, "str"};
b.
  auto {a, b} = tup;  // on variable declaration
  {a, b} = tup;   // on assignment expression
  ...

3. Which parts of the solution are frequent/cumbersome enough to warrant a
> language change?
>

a1. To make std.typetuple.TypeTuple template unnecessary.
a2. To keep std.typecons.Tuple as-is.
a3. To make expression tuple more usable.

  Today making the built-in tuple of runtime values needs unavoidable
runtime cost.

  int x, y;
  auto tup = TypeTuple!(x+1, y+2);
  // NG, template cannot take x+1 and y+2 because they are
  // expressions which cannot be evaluated in compile time
  auto tup = tuple(x+1, y+2);
  // NG, tup is not a builti-in tuple (it is an object of
std.typecons.Tuple struct).
  auto tup = tuple(x+1, y+2).expand;
  // OK, tup is a builti-in tuple. But we cannot avoid the cost to pack
in std.typecons.Tuple.

  Built-in tuple syntax would solve the issue.

  auto tup = {x+1, y+2};
  // tup is a built-in tuple, and it would be equivalent with:
  // auto tup[0] = x+1, tup[1] = x*2; // pseudo code
  // so no packing cost in runtime is there.

b.
  To make deconstruction code more readable.

  auto tup = std.typecons.tuple(1, "str");
  auto a = tup[0], b = tup[1];// Currrent:
  // Deconstruct two fields in tup to the two variables a and b
  auto {a, b} = tup;// New syntax:
  // Deconstruct syntax would recognize alias this tuple,
  // and expand it automatically.

Kenji Hara


Re: A Discussion of Tuple Syntax

2013-08-20 Thread Kenji Hara
2013/8/21 Timon Gehr 

> On 08/20/2013 10:16 PM, Andrei Alexandrescu wrote:
>
>> (There have been a few discussions in this group; I've come to think
>> auto expansion is fail.)
>>
>
> +1. :)
>

+1, too.

Since I wrote a compiler patch for the auto expansion on function
arguments, but it was rejected by Andrei.
http://d.puremagic.com/issues/show_bug.cgi?id=2779

And today, I'm mostly consent in his opinion.

Kenji Hara


Re: A Discussion of Tuple Syntax

2013-08-20 Thread Andrei Alexandrescu

On 8/20/13 5:28 PM, Tyler Jameson Little wrote:

OT: is the only thing stopping us from using the nice (x,y) syntax for
tuples the comma operator? If so, can we take that mis-feature behind
the woodshed and shoot it? I sincerely hope nobody is relying on it...


I think this whole thread is approaching things wrongly. It should be:

1. What do we need?

2. What does a solution look like in the current language?

3. Which parts of the solution are frequent/cumbersome enough to warrant 
a language change?


Instead there have been 1001 proposals for new syntax for tuple 
literals, one cuter than the next.



Andrei



Re: A Discussion of Tuple Syntax

2013-08-20 Thread Tyler Jameson Little
On Tuesday, 20 August 2013 at 21:25:11 UTC, Andrei Alexandrescu 
wrote:

On 8/20/13 1:24 PM, Dicebot wrote:
That would be problematic to say the least. (There have been 
a few
discussions in this group; I've come to think auto expansion 
is fail.)


:O it is awesome!


"Spawn of Satan" would be a tad more appropriate.


+1

I can stand explicit expansion though, like Go's variadic 
argument ellipses syntax: 
http://golang.org/doc/effective_go.html#append


OT: I'm not really a fan of D's variadic function syntax. I'd 
prefer it to be explicit:


int sum(int[] ar ...) {
}
int[3] foo = [4, 5, 6];
sum(foo...);
sum(3, 4, foo...); // on my wish list...


Stuff like foo(myStructInstance.tupleof) is very
powerful tool for generic interfaces.


One problem with automatic expansion is that now there's a 
whole new kind - a single expression that doesn't quite have 
one value and one type, but instead is an explosion of other 
expressions.


snip...

Alternatively, we could do what Go does and prevent all packing 
altogether (if I understand what Go does correctly). That is, 
if a function returns a tuple you can't even keep that tuple 
together unless you use some handcrafted solution. In that 
case, before long there will be some "Pack" structure and some 
pack helper function, viz. the converse of .expand.


+1

I've been itching for multiple returns in D for a long time, and 
this seems like a nice way to add it in. I think I'd prefer to 
use tuple syntax instead though, just so there's less magic:


(int, int) doStuff() {
return (1, 2);
}

// syntax error
auto a, b = doStuff();
// ok
auto (a, b) = doStuff();


Clearly both packing and unpacking tuples are necessary.

snip...

Andrei


OT: is the only thing stopping us from using the nice (x,y) 
syntax for tuples the comma operator? If so, can we take that 
mis-feature behind the woodshed and shoot it? I sincerely hope 
nobody is relying on it...


Re: A Discussion of Tuple Syntax

2013-08-20 Thread Dicebot
On Tuesday, 20 August 2013 at 21:25:11 UTC, Andrei Alexandrescu 
wrote:

Ionno so I just summarized it.


Andrei


I guess  I need just deal with it and accept as given then :) 
Okay, it does not really change much for main issue I wanted to 
pay attention to - thin edge between run-time expression tuples 
and compile-time ones.


Only problematic moment I can see so far is that compile-time 
tuples can contain both types and expressions at the same time. 
But this can be solved by considering them non-instantiatable 
type tuples - similar to existing handling. Or just call them 
"template argument lists" to be 100% straight and reserve word 
"tuple" for expression tuple while preserving "typeof" relation 
(and enhancing expression tuples with ABI).


Sounds like dreaming? :)


Re: A Discussion of Tuple Syntax

2013-08-20 Thread Meta
On Tuesday, 20 August 2013 at 21:25:11 UTC, Andrei Alexandrescu 
wrote:

"Spawn of Satan" would be a tad more appropriate.


I can not agree more.


Re: A Discussion of Tuple Syntax

2013-08-20 Thread H. S. Teoh
On Tue, Aug 20, 2013 at 05:12:43AM +0200, Meta wrote:
> Aggh, misposted. Let's try that again.
> 
> On Tuesday, 20 August 2013 at 02:51:20 UTC, Meta wrote:
> >On Tuesday, 20 August 2013 at 01:06:28 UTC, H. S. Teoh wrote:
> >>Actually, reading through DIP32 again, it sounds like Kenji is
> >>proposing the *same* syntax for both built-in tuples and
> >>std.typecons.Tuple. In the code example under "Generic
> >>type/expression tuple syntax", he refers to them respectively as
> >>"tuple type" and "tuple value". Mixing is also allowed (e.g., in the
> >>"alias Fields" line).
> 
> Maybe mixing should be disallowed, then, unless your tuple was
> constructed from a variadic template argument list.
[...]

I don't like this "unless". Either we support mixing, or we don't.
Adding in "unless" adds unnecessary complication, which will inevitably
have a ripple effect that adds complications everywhere. Next thing you
know, Phobos will acquire a template that returns a tuple of its
arguments -- as a workaround for the inability to manually construct a
mixed tuple, and then we'll have a rehash of this thread, this time
surrounding how to merge/get rid of std.typecons.createMixedTuple.

I think any workable design of tuples must include a sane way of working
with mixed tuples, because they can and do appear in template arguments.


T

-- 
Без труда не выловишь и рыбку из пруда. 


Re: A Discussion of Tuple Syntax

2013-08-20 Thread Timon Gehr

On 08/20/2013 10:16 PM, Andrei Alexandrescu wrote:

(There have been a few discussions in this group; I've come to think
auto expansion is fail.)


+1. :)


Re: A Discussion of Tuple Syntax

2013-08-20 Thread Andrei Alexandrescu

On 8/20/13 1:24 PM, Dicebot wrote:

That would be problematic to say the least. (There have been a few
discussions in this group; I've come to think auto expansion is fail.)


:O it is awesome!


"Spawn of Satan" would be a tad more appropriate.


Stuff like foo(myStructInstance.tupleof) is very
powerful tool for generic interfaces.


One problem with automatic expansion is that now there's a whole new 
kind - a single expression that doesn't quite have one value and one 
type, but instead is an explosion of other expressions.


The problem now is how to contain these things - presumably one should 
associate a self-exploding tuple with a symbol:


auto pack = functionReturningTuple();

The symbol should not expand when, for example, assigned to another:

auto packCopy = pack;

However, the symbol _should_ expand "where it should", presumably in a 
function code:


auto m = min(pack, 0);

So this will invoke min with various numbers of arguments depending on 
what pack contains. Same with e.g.


writeln(pack);

Before one even realizes it, the matter of when to expand vs. when not 
to expand becomes a thing. That thing will have people confused (because 
now an expression isn't what it seems; it may be, in fact, several 
expressions at once). It will get explained in articles and books. There 
will be debates about choices of automatic unpacking vs. not in which 
reasonable people may disagree. People will get all confused about it. 
Generic code won't be able to tell much about what's going on because 
arity can't be guaranteed anymore.


Alternatively, we could do what Go does and prevent all packing 
altogether (if I understand what Go does correctly). That is, if a 
function returns a tuple you can't even keep that tuple together unless 
you use some handcrafted solution. In that case, before long there will 
be some "Pack" structure and some pack helper function, viz. the 
converse of .expand.


Clearly both packing and unpacking tuples are necessary. The question is 
what the default is. My argument here is that keeping one 
expression/symbol have one value is so deeply embedded in the semantics 
(and the ethos for that matter) of D, that it would be a major step 
backwards to retrofit it all to accommodate self-expanding tuples. Not 
speaking for other languages, I think it's great that in D


writeln(x);

is known to take an argument, whereas

writeln(x.expand);

takes zero or more arguments. It is the best compromise I can imagine 
that keeps the language sealed tight.



Do you remember any keywords to
look for to find those discussions? Ones I remember were mostly about
auto-expansion _not_ happening in some reasonable places.


Ionno so I just summarized it.


Andrei



Re: A Discussion of Tuple Syntax

2013-08-20 Thread Dicebot
On Tuesday, 20 August 2013 at 20:16:54 UTC, Andrei Alexandrescu 
wrote:

On 8/20/13 6:57 AM, Dicebot wrote:
I am proposing something more radical. Deprecate _both_ 
TypeTuple and
Tuple. Clearly define the difference between built-in type 
tuple and

expression tuple (latter being instance of former).


But that can't be the case.


Can you elaborate on this? I can only judge by observable 
behavior which clearly says that typeof(TypeTuple!(2, 3)) is 
TypeTuple!(int, int). And when you use variadic template argument 
syntax in functions, you use "T..." (which is a built-in type 
tuple) to declare arguments (which is built-in expression tuple). 
There are probably some inconsistencies in implementation but 
this is the observable behavior that can be declared official.



Preserve
auto-expansion.


That would be problematic to say the least. (There have been a 
few discussions in this group; I've come to think auto 
expansion is fail.)


:O it is awesome! Stuff like foo(myStructInstance.tupleof) is 
very powerful tool for generic interfaces. Do you remember any 
keywords to look for to find those discussions? Ones I remember 
were mostly about auto-expansion _not_ happening in some 
reasonable places.


Re: A Discussion of Tuple Syntax

2013-08-20 Thread Andrei Alexandrescu

On 8/20/13 8:43 AM, Kenji Hara wrote:

2013/8/20 Dicebot mailto:pub...@dicebot.lv>>

What we have here are two completely different _built-in_ tuple
types. "T" is pure template arguments list and is pretty much equal
TypeTuple!(int, int). But what is "args"? It uses the very same
built-in tuple syntax but it is much closer to std.typecons.Tuple in
its behavior (actually, latter is implemented in terms of it as I
was pointed out) - it is an entity that provides abstraction of top
of group of run-time values. It does not have any binary structure
on its own (built on top of existing values) but observable semantic
are very "run-time'ish".


"args" is a built-in tuple of two function parameter variables. In
binary level, args[0] and args[1] could be bounded to completely
individual storage. (Even if args[1] is on stack, args[0] may be on
register)
On the other hand, std.typecons.Tuple is a struct. Its second field has
the memory address which follows of the first field.


Ome question would be whether appropriate inlining could solve the 
performance disadvantage of Tuple.


Andrei



Re: A Discussion of Tuple Syntax

2013-08-20 Thread Andrei Alexandrescu

On 8/20/13 6:57 AM, Dicebot wrote:

I am proposing something more radical. Deprecate _both_ TypeTuple and
Tuple. Clearly define the difference between built-in type tuple and
expression tuple (latter being instance of former).


But that can't be the case.


Preserve
auto-expansion.


That would be problematic to say the least. (There have been a few 
discussions in this group; I've come to think auto expansion is fail.)



Provide two different literals to remove ambiguity
between referencing symbol as a value and referencing it as an alias.
Make compiler auto-generate Tuple-like struct type for expression tuples
that need to be returned from functions. Create some new type in
std.typecons for those who don't want auto-expansion.

It won't even break stuff.


That sounds good :o).


Andrei


Re: A Discussion of Tuple Syntax

2013-08-20 Thread H. S. Teoh
On Tue, Aug 20, 2013 at 04:10:29PM -0400, Jonathan M Davis wrote:
> On Tuesday, August 20, 2013 13:06:27 H. S. Teoh wrote:
> > On Tue, Aug 20, 2013 at 11:53:50AM -0700, Andrei Alexandrescu wrote:
> > > Somebody shoot me.
> > 
> > [...]
> > 
> > BANG!
> 
> Don't kill him. He hasn't finished the allocators yet! ;)

Well, as my signature line said:

They say that "guns don't kill people, people kill people." Well
I think the gun helps. If you just stood there and yelled BANG,
I don't think you'd kill too many people. -- Eddie Izzard,
Dressed to Kill

;-)


T
-- 
Why can't you just be a nonconformist like everyone else? -- YHL


Re: A Discussion of Tuple Syntax

2013-08-20 Thread Jonathan M Davis
On Tuesday, August 20, 2013 13:06:27 H. S. Teoh wrote:
> On Tue, Aug 20, 2013 at 11:53:50AM -0700, Andrei Alexandrescu wrote:
> > Somebody shoot me.
> 
> [...]
> 
> BANG!

Don't kill him. He hasn't finished the allocators yet! ;)

- Jonathan M Davis


Re: A Discussion of Tuple Syntax

2013-08-20 Thread H. S. Teoh
On Tue, Aug 20, 2013 at 11:53:50AM -0700, Andrei Alexandrescu wrote:
> On 8/20/13 3:38 AM, eles wrote:
> >On Friday, 16 August 2013 at 21:07:52 UTC, Meta wrote:
> >>A good, comprehensive design has the potential to make tuples easy
> >>to use and understand, and hopefully clear up the unpleasant
> >>situation we have currently. A summary of what has been discussed so
> >>far:
> >>
> >>- (a, b) is the prettiest syntax, and it also completely infeasible
> >>
> >>- {a, b} is not as pretty, but it's not that bad of an alternative
> >>(though it may still have issues as well)
> >>
> >>- #(a, b) is unambiguous and would probably be the easiest option. I
> >>don't think it looks too bad, but some people might find it ugly and
> >>noisy
> >
> >What about:
> >
> >!!(a, b)
> >
> >? Yes, is long, but is type-able quite fast.
> >
> >Alternative would be:
> >
> >??(a, b)
> >
> >.
> 
> Somebody shoot me.
[...]

BANG!


T

-- 
They say that "guns don't kill people, people kill people." Well I think the 
gun helps. If you just stood there and yelled BANG, I don't think you'd kill 
too many people. -- Eddie Izzard, Dressed to Kill


Re: A Discussion of Tuple Syntax

2013-08-20 Thread Timon Gehr

On 08/20/2013 08:51 PM, Andrei Alexandrescu wrote:

On 8/19/13 11:39 PM, Timon Gehr wrote:

On 08/20/2013 02:18 AM, Andrei Alexandrescu wrote:


Why would it be necessary to return an object of type TypeTuple (i.e.
template tuple)?



- Elegance. Eg:

auto seq(T...)(T arg){ return arg; }

auto fold(alias a,S,R)(S start, R range){ ... }


seq(0,[1,2,3]).fold!((a,b)=>a+b);


But this is again a value tuple not a template tuple, no?

Andrei



In my understanding the former is a special case of the latter. Since 
you invented those terms, I might be mistaken. How do you distinguish 
between them?


Re: A Discussion of Tuple Syntax

2013-08-20 Thread Timon Gehr

On 08/20/2013 05:18 PM, bearophile wrote:

s = "red blue"
(a, b) = s.split()
a

'red'

b

'blue'


It's supported in Haskell too:

Prelude> let s = "red blue"
Prelude> let [a, b] = words s
Prelude> a
"red"
Prelude> b
"blue"

Bye,
bearophile


Any language with algebraic data types supports this.


Re: A Discussion of Tuple Syntax

2013-08-20 Thread Timon Gehr

On 08/20/2013 09:57 PM, Timon Gehr wrote:

On 08/20/2013 05:18 PM, bearophile wrote:

s = "red blue"
(a, b) = s.split()
a

'red'

b

'blue'


It's supported in Haskell too:

Prelude> let s = "red blue"
Prelude> let [a, b] = words s
Prelude> a
"red"
Prelude> b
"blue"

Bye,
bearophile


Any language with algebraic data types supports this.


(Some will only allow it if you can prove the match is total within 
them, of course.)


Re: A Discussion of Tuple Syntax

2013-08-20 Thread Andrei Alexandrescu

On 8/20/13 3:38 AM, eles wrote:

On Friday, 16 August 2013 at 21:07:52 UTC, Meta wrote:

A good, comprehensive design has the potential to make tuples easy to
use and understand, and hopefully clear up the unpleasant situation we
have currently. A summary of what has been discussed so far:

- (a, b) is the prettiest syntax, and it also completely infeasible

- {a, b} is not as pretty, but it's not that bad of an alternative
(though it may still have issues as well)

- #(a, b) is unambiguous and would probably be the easiest option. I
don't think it looks too bad, but some people might find it ugly and
noisy


What about:

!!(a, b)

? Yes, is long, but is type-able quite fast.

Alternative would be:

??(a, b)

.


Somebody shoot me.

Andrei


Re: A Discussion of Tuple Syntax

2013-08-20 Thread Andrei Alexandrescu

On 8/19/13 11:39 PM, Timon Gehr wrote:

On 08/20/2013 02:18 AM, Andrei Alexandrescu wrote:


Why would it be necessary to return an object of type TypeTuple (i.e.
template tuple)?



- Elegance. Eg:

auto seq(T...)(T arg){ return arg; }

auto fold(alias a,S,R)(S start, R range){ ... }


seq(0,[1,2,3]).fold!((a,b)=>a+b);


But this is again a value tuple not a template tuple, no?

Andrei



Re: A Discussion of Tuple Syntax

2013-08-20 Thread bearophile

Kenji Hara:


My position to such a feature is constant.


Even if your opinion is not changed, I have to show that common 
tuple-related features to the other persons that are reading this 
thread, because it's an an idea to keep in account (even if it's 
refused), and some other person could have an opinion different 
from yours.



However, array unpacking would require *hidden* runtime 
boundary check.

In above example code,

  assert(tup[2].length == 2);
  // or
  if (tup[2].length != 2) throw Error("Runtime mismatch of 
unpacking

pattern");
  // or similar

should be implicitly inserted by compiler, even in @system code.
I'm not sure that is acceptable cost or not.


Runtime boundary checks and tests are not needed if you unpack a 
fixed-sized array:


auto tup = Tuple!(int, string[2])(1, ["red", "blue"]);
auto {x, [c1, c2]} = tup;

Regarding the de-structuring of dynamic arrays, I think it's not 
too much different than this:


void main() {
int[] a = [10, 20, 30];
int[2] b = a;
}

If you compile and run it without switches, you get at run-time:

object.Error: lengths don't match for array copy, 2 = 3


While I receive no run-time errors if I compile with 
-noboundscheck.


Bye,
bearophile


Re: A Discussion of Tuple Syntax

2013-08-20 Thread bearophile

Dicebot:

bearophile I really respect informational contribution you have 
been doing in D community but in my opinion mentioning random 
snippets from other languages is the least useful thing 
possible in this thread. It is even less useful than discussing 
syntax.


Look better at them, those aren't random snippets, they show one 
more case of de-structuring, creating a tuple of variables out of 
an array. It's a commonly used operation in two very well 
designed languages that have tuples. Here we are discussing 
tuples and their packing and unpacking, so the two examples I've 
shown are very relevant, even if we decide to not support that 
specific feature.


Bye,
bearophile


Re: A Discussion of Tuple Syntax

2013-08-20 Thread Kenji Hara
2013/8/20 bearophile 

> So, std.typecons.Tuple _is not special_. You can define another Tuple
>> struct in the same way.
>> We should not define new syntax for the library utility
>> std.typecons.Tuple.
>>
>
> With your idea is there a way to unpack a short array into variables? This
> is an handy operation I do often in Python:
>
>  s = "red blue"
 (a, b) = s.split()
 a

>>> 'red'
>
>> b

>>> 'blue'
>

My position to such a feature is constant. We should not conflate tuple
unpacking and array unpacking.

But, extending unpacking syntax mentioned in DIP32 might help it.

// Just an idea: extending DIP32 unpacking syntax
import std.typecons : tuple;
auto tup = tuple(1, tuple(2,3), [4,5]);
{ auto a, {b, c}, [d, e] } = tup;
//{ auto a, [b, c], {d, e} } = tup;   // cause compile-time error
assert(a == 1);
assert(b == 2 && c == 3);
assert(d == 4 && e == 5);

However, array unpacking would require *hidden* runtime boundary check.
In above example code,

  assert(tup[2].length == 2);
  // or
  if (tup[2].length != 2) throw Error("Runtime mismatch of unpacking
pattern");
  // or similar

should be implicitly inserted by compiler, even in @system code.
I'm not sure that is acceptable cost or not.

Kenji Hara


Re: A Discussion of Tuple Syntax

2013-08-20 Thread eles

On Tuesday, 20 August 2013 at 13:14:46 UTC, Timon Gehr wrote:

On 08/20/2013 12:38 PM, eles wrote:


What about:

!!(a, b)



This already has a meaning.


True :( I dunno why I took it for some kind of binary operator 
instead of a unary one.


I was too quick on my keyboard.


Re: A Discussion of Tuple Syntax

2013-08-20 Thread Dicebot

On Tuesday, 20 August 2013 at 15:43:39 UTC, Kenji Hara wrote:
On the other hand, std.typecons.Tuple is a struct. Its second 
field has the

memory address which follows of the first field.


Yes but as you have said exact storage of built-in tuple elements 
is not defined - it can be distinct elements or struct fields, 
compiler is free to chose any. I am not asking about internal 
implementation but about behavior observable by user in typical 
cases - it is most important topic here.



Automatically packing/unpacking would need hidden runtime cost.


Will it be any more costly then returning std.typecons.Tuple and 
unpacking it manually? And, well, do we have _any_ other option 
of returning a tuple with no runtime costs right now anyway?


Considering we are far away from stable ABI that does not seem to 
be a real issue.


Re: A Discussion of Tuple Syntax

2013-08-20 Thread Kenji Hara
2013/8/20 Dicebot 

> What we have here are two completely different _built-in_ tuple types. "T"
> is pure template arguments list and is pretty much equal TypeTuple!(int,
> int). But what is "args"? It uses the very same built-in tuple syntax but
> it is much closer to std.typecons.Tuple in its behavior (actually, latter
> is implemented in terms of it as I was pointed out) - it is an entity that
> provides abstraction of top of group of run-time values. It does not have
> any binary structure on its own (built on top of existing values) but
> observable semantic are very "run-time'ish".
>

"args" is a built-in tuple of two function parameter variables. In binary
level, args[0] and args[1] could be bounded to completely individual
storage. (Even if args[1] is on stack, args[0] may be on register)
On the other hand, std.typecons.Tuple is a struct. Its second field has the
memory address which follows of the first field.

What bothers me is the question "can we clean this up and bring those two
> worlds together, even at cost of minor breakage?". I am not speaking about
> literals here or unpacking or whatever. I am speaking about re-defining
> semantics so that struct-based Tuple and built-in syntax sugar in form of
> run-time expression tuple both get merged into one built-in construct which
> can be used in wider variety of places.


> At least right now I can't find any technical objections why expression
> tuple can't use std.typecons.Tuple ABI when returned from function but
> still be automatically expanded when passed into functions. Kenji, what is
> your your opinion about complexity to implement something like that in DMD?
>

Automatically packing/unpacking would need hidden runtime cost.

Kenji Hara


Re: A Discussion of Tuple Syntax

2013-08-20 Thread Dicebot
bearophile I really respect informational contribution you have 
been doing in D community but in my opinion mentioning random 
snippets from other languages is the least useful thing possible 
in this thread. It is even less useful than discussing syntax.


Re: A Discussion of Tuple Syntax

2013-08-20 Thread bearophile

s = "red blue"
(a, b) = s.split()
a

'red'

b

'blue'


It's supported in Haskell too:

Prelude> let s = "red blue"
Prelude> let [a, b] = words s
Prelude> a
"red"
Prelude> b
"blue"

Bye,
bearophile


Re: A Discussion of Tuple Syntax

2013-08-20 Thread bearophile

Kenji Hara:

So, std.typecons.Tuple _is not special_. You can define another 
Tuple struct in the same way.
We should not define new syntax for the library utility 
std.typecons.Tuple.


With your idea is there a way to unpack a short array into 
variables? This is an handy operation I do often in Python:




s = "red blue"
(a, b) = s.split()
a

'red'

b

'blue'


Bye,
bearophile


Re: A Discussion of Tuple Syntax

2013-08-20 Thread Manu
On 20 August 2013 16:39, Timon Gehr  wrote:

> On 08/20/2013 02:18 AM, Andrei Alexandrescu wrote:
>
>>
>> Why would it be necessary to return an object of type TypeTuple (i.e.
>> template tuple)?
>>
>
> - ABI
>
> Multiple return values could use a more efficient ABI than struct
> instances because they do not have an address.
>

*** this

I've been banging this drum for years!

However this discussion resolves, I just hope it allows for convenient and
efficient MRV's.
Obviously it should be syntactically convenient, and assignment of MRV to
callee locals should be convenient too.
But more importantly, I'd like to see ALL the argument registers re-used to
return multiple values, rather than just the first one. They're just
sitting there begging to be used, and in many cases, would lead to some
great efficiency improvements across function calls/returns. Especially on
non-x86 architectures.

Perhaps one of the most common causes for (otherwise unnecessary) inlining
of functions is because of the terrible legacy ABI for returning multiple
values from functions.


Re: A Discussion of Tuple Syntax

2013-08-20 Thread H. S. Teoh
On Mon, Aug 19, 2013 at 09:41:24PM -0700, Jonathan M Davis wrote:
> On Monday, August 19, 2013 13:45:33 Andrei Alexandrescu wrote:
> > but once the bikeshed is up for painting, the
> > rainbow won't suffice.
> 
> LOL! I'm going to have to remember that one.
[...]

That's a classic. I'm st^H^H borrowing that for my random signatures
file. :)


T

-- 
There's light at the end of the tunnel. It's the oncoming train.


Re: A Discussion of Tuple Syntax

2013-08-20 Thread Meta

On Tuesday, 20 August 2013 at 13:57:49 UTC, Dicebot wrote:
Syntax sugar will only hide and eventually increase confusion, 
it won't solve the semantical issue. This is why we are having 
this topic IMHO, bunch of quite experienced D developers can't 
even agree on how existing feature behaves :) Including those 
who is it all the time! It is clear indicator that syntax is 
not the one to blame.


My suggestions are predicated on the fact that I think tuples are 
more or less fine as-is. They just need some syntactic sugar for 
literals and destructuring/pattern matching to make them more 
usable. Built-in tuples are confusing, I think, because they're 
named TypeTuple, which makes people conflate them with 
std.typecons.Tuple.


Another reason is that TypeTuple can contain both values and 
types at the same time, so it's confusing as to what you can do 
with them.


"Why can you only assign a TypeTuple to a variable if it contains 
values but not types? Why, then, can't you return TypeTuple!(1, 
2.3) from a function? Is it not really a variable? Why does 
`alias t = TypeTuple!(1, 2.3)` work, but `alias n = 3` not work? 
Is this f*$#ing thing a value or a type?" - D Newbie


Everything else aside, I think the best possible change that 
would make the whole tuple situation better is to limit or 
outright ban the mixing of values and types within TypeTuple. 
Even better is to always treat TypeTuple as a type, and not a 
value. That ship has already sailed, but we can at least try to 
enforce it through convention.


I am proposing something more radical. Deprecate _both_ 
TypeTuple and Tuple. Clearly define the difference between 
built-in type tuple and expression tuple (latter being instance 
of former). Preserve auto-expansion. Provide two different 
literals to remove ambiguity between referencing symbol as a 
value and referencing it as an alias. Make compiler 
auto-generate Tuple-like struct type for expression tuples that 
need to be returned from functions. Create some new type in 
std.typecons for those who don't want auto-expansion.


It won't even break stuff.


I think my position has changed to suggest nearly the same thing. 
There needs to be a clear separation between built-in tuples and 
tuple values. A runtime tuple literal syntax helps with that. 
Making typeof(tuple(1, 2.3)) == TypeTuple!(int, double) helps as 
well, because it is now clear that one is a value and one is a 
type. Limiting the mixing of values and types within TypeTuple 
helps with that.


This would allow both Tuple and TypeTuple to be deprecated. Tuple 
wouldn't be needed anymore, because we would have a literal 
syntax to replace it. It would only be there for backwards 
compatibility. With Tuple deprecated, std.typetuple.TypeTuple 
could be renamed Tuple, and we would then have only one thing 
with the name Tuple in the language.


Re: A Discussion of Tuple Syntax

2013-08-20 Thread Dicebot

On Tuesday, 20 August 2013 at 13:17:44 UTC, Meta wrote:
This is the reason I had originally thought Kenji's DIP was 
about run-time tuples. If it's just syntactic sugar over 
std.typecons.Tuple (plus some extra destructuring/pattern 
matching stuff), it would require no ABI changes and no changes 
to TypeTuple semantics. The one thing it wouldn't do is unify 
Tuple and TypeTuple.


Syntax sugar will only hide and eventually increase confusion, it 
won't solve the semantical issue. This is why we are having this 
topic IMHO, bunch of quite experienced D developers can't even 
agree on how existing feature behaves :) Including those who is 
it all the time! It is clear indicator that syntax is not the one 
to blame.


However, with compiler support, we can make this situation 
better. TypeTuple stays as-is, while Tuple becomes a value 
instead of a type, which has its own literal syntax. This means 
that typeof(tuple(1, "a")) is not Tuple!(int, string), as in 
the struct, but TypeTuple!(int, string), as in the compiler 
tuple.


I am proposing something more radical. Deprecate _both_ TypeTuple 
and Tuple. Clearly define the difference between built-in type 
tuple and expression tuple (latter being instance of former). 
Preserve auto-expansion. Provide two different literals to remove 
ambiguity between referencing symbol as a value and referencing 
it as an alias. Make compiler auto-generate Tuple-like struct 
type for expression tuples that need to be returned from 
functions. Create some new type in std.typecons for those who 
don't want auto-expansion.


It won't even break stuff.


Re: A Discussion of Tuple Syntax

2013-08-20 Thread Meta
This is the reason I had originally thought Kenji's DIP was about 
run-time tuples. If it's just syntactic sugar over 
std.typecons.Tuple (plus some extra destructuring/pattern 
matching stuff), it would require no ABI changes and no changes 
to TypeTuple semantics. The one thing it wouldn't do is unify 
Tuple and TypeTuple.


However, with compiler support, we can make this situation 
better. TypeTuple stays as-is, while Tuple becomes a value 
instead of a type, which has its own literal syntax. This means 
that typeof(tuple(1, "a")) is not Tuple!(int, string), as in the 
struct, but TypeTuple!(int, string), as in the compiler tuple.


You could still do all the stuff that can be done with TypeTuple 
currently, but it should be strongly discouraged to mix types and 
values within TypeTuple, or even limited by the compiler. This 
creates a clear distinction between runtime tuples and TypeTuple. 
It becomes much easier to reason about their semantics, as we can 
think of TypeTuple as a type, just like int, string, double, 
etc., and Tuple as a value, just like 1, "a", 2.3, etc. The only 
difference between TypeTuple and regular types is that there are 
a few special static operations that can be used to manipulate 
it. Otherwise it behaves as a type.


Re: A Discussion of Tuple Syntax

2013-08-20 Thread Timon Gehr

On 08/20/2013 12:38 PM, eles wrote:


What about:

!!(a, b)



This already has a meaning.



Re: A Discussion of Tuple Syntax

2013-08-20 Thread Wyatt

On Tuesday, 20 August 2013 at 09:02:29 UTC, Mr. Anonymous wrote:


Why not just leave an empty space, like php does:

$info = array('coffee', 'brown', 'caffeine');
// let's skip to only the third one
list( , , $power) = $info;
echo "I need $power!\n";


Bad idea.  It's a visual thing--  quick! How wide is this tuple!?:
#(,frontvar,)

How long did it take you to be SURE that it's a seven-tuple?  You 
probably aren't even equipped to measure that so don't worry 
about answering, but I'm guessing you start to appreciate why 
it's a fairly inhumane solution (how drearily typical for PHP).


Ah, but what if it was supposed to be #(,front,var,)?  Does 
that change your result, now that you're taking the sixth element 
rather than the seventh?  All you did was forget a comma!  By 
contrast:
#(?,front,?,?,?,var,?,?) //at least gives us a better chance of 
parsing it correctly.


My point here is we are human and we are fallible.  The sooner we 
acknowledge and internalise that, the better equipped we are to 
make systems that don't suck for humans to use.


In that sense, I don't even really like this format because it's 
still not especially resilient.  Walter's talk about design that 
eliminates patterns of human error resonated with me quite 
strongly, you see.  But in terms of language consistency it's not 
much different from array literals, so I could accept it as a 
compromise.


-Wyatt


Re: A Discussion of Tuple Syntax

2013-08-20 Thread Dicebot

On Tuesday, 20 August 2013 at 03:33:51 UTC, Kenji Hara wrote:
Sorry I cannot reply to each thread comments quickly, so I 
discharge my

opinions at once.


One thing that I think does not get deserved attention is that 
built-in expression tuple are not limited to compile-time values. 
Lets consider this simple example:


void foo(T...)(T args)
{
pragma(msg, args);
pragma(msg, typeof(args));
}

void main()
{
int a, b;
foo(a, b);
}


---

/d147/f686.d(3): Error: variable _param_0 cannot be read at 
compile time /d147/f686.d(3): Error: variable _param_1 cannot be 
read at compile time tuple(_param_0, _param_1) (int, int)


---

What we have here are two completely different _built-in_ tuple 
types. "T" is pure template arguments list and is pretty much 
equal TypeTuple!(int, int). But what is "args"? It uses the very 
same built-in tuple syntax but it is much closer to 
std.typecons.Tuple in its behavior (actually, latter is 
implemented in terms of it as I was pointed out) - it is an 
entity that provides abstraction of top of group of run-time 
values. It does not have any binary structure on its own (built 
on top of existing values) but observable semantic are very 
"run-time'ish".


What bothers me is the question "can we clean this up and bring 
those two worlds together, even at cost of minor breakage?". I am 
not speaking about literals here or unpacking or whatever. I am 
speaking about re-defining semantics so that struct-based Tuple 
and built-in syntax sugar in form of run-time expression tuple 
both get merged into one built-in construct which can be used in 
wider variety of places.


At least right now I can't find any technical objections why 
expression tuple can't use std.typecons.Tuple ABI when returned 
from function but still be automatically expanded when passed 
into functions. Kenji, what is your your opinion about complexity 
to implement something like that in DMD?


Re: A Discussion of Tuple Syntax

2013-08-20 Thread Jacob Carlborg

On 2013-08-20 05:33, Kenji Hara wrote:


If you want to return multiple values from a function, you must always
wrap them by std.typecons.Tuple, or other used-defined types. You cannot
directly return built-in tuple from a function.
(Built-in tuple return is mostly equivalent with multiple-value-return
issue. However it would be mostly impossible that defining calling
conversion scheme for that in portable)


If I recall correctly some ABI's passes small structs in registers, at 
least I think it does on Mac OS X.



My opinions agains various syntax proposals:

#(1, "str")
--> The character '#' is already used for the start of "Special Token
Sequences"
http://dlang.org/lex.html#Special Token Sequence

It is recognized in lexing phase, so adding semantic meaning to the '#'
character would be a contradict of D's principle.

Quote from http://dlang.org/lex.html
"The lexical analysis is independent of the syntax parsing and the
semantic analysis."


It depends on how it's lexed. If the compiler lexes "#line" as a single 
token I cannot see how it will be a problem. Then the "#" token would 
mean tuple literal.


--
/Jacob Carlborg


Re: A Discussion of Tuple Syntax

2013-08-20 Thread John Colvin

On Tuesday, 20 August 2013 at 03:33:51 UTC, Kenji Hara wrote:


My opinions agains various syntax proposals:

#(1, "str")
--> The character '#' is already used for the start of "Special 
Token

Sequences"
http://dlang.org/lex.html#Special Token Sequence

It is recognized in lexing phase, so adding semantic meaning to 
the '#'

character would be a contradict of D's principle.

Quote from http://dlang.org/lex.html
"The lexical analysis is independent of the syntax parsing and 
the semantic

analysis."

Kenji Hara



There are various other characters that could be substituted for #
e.g.
&(1, "string")

http://forum.dlang.org/post/cokiixatvjmngggpb...@forum.dlang.org


Re: A Discussion of Tuple Syntax

2013-08-20 Thread Mr. Anonymous

On Tuesday, 20 August 2013 at 10:38:30 UTC, eles wrote:

On Friday, 16 August 2013 at 21:07:52 UTC, Meta wrote:
A good, comprehensive design has the potential to make tuples 
easy to use and understand, and hopefully clear up the 
unpleasant situation we have currently. A summary of what has 
been discussed so far:


- (a, b) is the prettiest syntax, and it also completely 
infeasible


- {a, b} is not as pretty, but it's not that bad of an 
alternative (though it may still have issues as well)


- #(a, b) is unambiguous and would probably be the easiest 
option. I don't think it looks too bad, but some people might 
find it ugly and noisy


What about:

!!(a, b)

? Yes, is long, but is type-able quite fast.

Alternative would be:

??(a, b)

.


It's not only long, but also ugly (IMO of course).


Re: A Discussion of Tuple Syntax

2013-08-20 Thread eles

On Friday, 16 August 2013 at 21:07:52 UTC, Meta wrote:
A good, comprehensive design has the potential to make tuples 
easy to use and understand, and hopefully clear up the 
unpleasant situation we have currently. A summary of what has 
been discussed so far:


- (a, b) is the prettiest syntax, and it also completely 
infeasible


- {a, b} is not as pretty, but it's not that bad of an 
alternative (though it may still have issues as well)


- #(a, b) is unambiguous and would probably be the easiest 
option. I don't think it looks too bad, but some people might 
find it ugly and noisy


What about:

!!(a, b)

? Yes, is long, but is type-able quite fast.

Alternative would be:

??(a, b)

.


Re: A Discussion of Tuple Syntax

2013-08-20 Thread Mr. Anonymous

On Monday, 19 August 2013 at 18:43:37 UTC, Meta wrote:

On Monday, 19 August 2013 at 16:53:06 UTC, Wyatt wrote:
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.


Why not just leave an empty space, like php does:

$info = array('coffee', 'brown', 'caffeine');
// let's skip to only the third one
list( , , $power) = $info;
echo "I need $power!\n";

http://php.net/manual/en/function.list.php


Re: A Discussion of Tuple Syntax

2013-08-19 Thread Timon Gehr

On 08/20/2013 02:18 AM, Andrei Alexandrescu wrote:


Why would it be necessary to return an object of type TypeTuple (i.e.
template tuple)?



- Elegance. Eg:

auto seq(T...)(T arg){ return arg; }

auto fold(alias a,S,R)(S start, R range){ ... }


seq(0,[1,2,3]).fold!((a,b)=>a+b);


(Obviously you can get close by requiring expansion at the call site.)


- ABI

Multiple return values could use a more efficient ABI than struct 
instances because they do not have an address.



- Consistency

A type whose instances cannot be returned from a function is just weird 
language design.




It has no state.


It may alias variables that do.


Re: A Discussion of Tuple Syntax

2013-08-19 Thread deadalnix
On Monday, 19 August 2013 at 21:03:50 UTC, Andrei Alexandrescu 
wrote:
I'm saying that there's a mix of useful stuff and just 
syntactic additions that are arguably less so. In my opinion:


a) destructuring tuples in auto declarations - good to have:

auto (a, b, c) = 
functionReturningTupleOrStaticArrayWith3Elements();




I propose the following rewrite :

auto tmp = functionReturningTupleOrStaticArrayWith3Elements();
assert(tmp.length == 3);
auto a = tmp[0];
auto b = tmp[1];
auto c = tmp[2];

That way any type user can take advantage of the new syntax, and 
it is easy to implement as it is simple rewrite rules. Note that 
tmp do not need to be an lvalue to avoid uneeded copies.


I'd also like to see the term Tuple for variadic template 
parameter go away. This is confusing the hell out of everybody, 
as the current conversation is showing.


Re: A Discussion of Tuple Syntax

2013-08-19 Thread Jonathan M Davis
On Monday, August 19, 2013 13:45:33 Andrei Alexandrescu wrote:
> but once the bikeshed is up for painting, the
> rainbow won't suffice.

LOL! I'm going to have to remember that one.

- Jonathan M Davis


Re: A Discussion of Tuple Syntax

2013-08-19 Thread Kenji Hara
Sorry I cannot reply to each thread comments quickly, so I discharge my
opinions at once.


D's built-in tuple can contain following entities:
 - Type
int, long, array types, AA types, user-defined types, etc
 - Expressions
interger, string literal, etc
 - Symbol
user-defined types, templates, template instances, etc

Note that: an user-defined type would be treated as both Type and Symbol.

template Test() {}
alias X = std.typetuple.TypeTuple!(
int, long, char[], int[int], const Object,  // Types
1, "str", [1,2,3],  // Expressions (literal values)
object.Object, Test, Test!(),   // Symbols
);

If all of the elements in a built-in tuple are Type, today it is normally
called "Type Tuple".
If all of the elements in a built-in tuple are Expressions, today it is
normally called "Expression Tuple".

Note that: today we cannot create a built-in tuple without using
TemplateTupleParameter.
TemplateTupleParameter cannot take expressions non-literal expressions,
therefore
most of current built-in tuples would contains only literal values as the
Expressions.


std.typecons.Tuple is an artifact of built-in tuple + alias this.

struct Tuple(T...) {
T expand;   // 'expand' is a built-in tuple of
// the implicitly defined fields that
// typed T[0], T[1], ... T[$-1].
// In spec, this is called "TupleDeclaration".
alias expand this;  // forward indexing/slicing operators to
// the TupleDeclaration 'expand'
}
Tuple!(int, string) t;
t[];// t.expand[]
t[0..$];// t.expand[0..$]
t[1];   // t.expand[1]

So, std.typecons.Tuple _is not special_. You can define another Tuple
struct in the same way.
We should not define new syntax for the library utility std.typecons.Tuple.

If you want to return multiple values from a function, you must always wrap
them by std.typecons.Tuple, or other used-defined types. You cannot
directly return built-in tuple from a function.
(Built-in tuple return is mostly equivalent with multiple-value-return
issue. However it would be mostly impossible that defining calling
conversion scheme for that in portable)


The combination of built-in tuple and alias this would be one of the case
of built-in tuple of non-literal Expressions.
For example, `t.expand[1]` is equivalent with the dot expression
`t.__field_1` which cannot be taken by TemplateTupleParameter.
Therefore, `t.expand` would be the built-in tuple of the two dot
expressions `t.__field_0` and `t.__field_1`.

Therefore, calling built-in tuple "Alias Tuple" would not be correct so
built-in tuple can contain expressions that cannot be aliased.


My opinions agains various syntax proposals:

#(1, "str")
--> The character '#' is already used for the start of "Special Token
Sequences"
http://dlang.org/lex.html#Special Token Sequence

It is recognized in lexing phase, so adding semantic meaning to the '#'
character would be a contradict of D's principle.

Quote from http://dlang.org/lex.html
"The lexical analysis is independent of the syntax parsing and the semantic
analysis."

Kenji Hara


Re: A Discussion of Tuple Syntax

2013-08-19 Thread Kenji Hara
2013/8/20 H. S. Teoh 

> Actually, reading through DIP32 again, it sounds like Kenji is proposing
> the *same* syntax for both built-in tuples and std.typecons.Tuple. In
> the code example under "Generic type/expression tuple syntax", he refers
> to them respectively as "tuple type" and "tuple value". Mixing is also
> allowed (e.g., in the "alias Fields" line).
>

 Honestly, I had intended DIP32 to provide *uniform* syntax for both
built-in tuple and std.typecons.Tuple.
However, finally, I noticed that would be _impossible_.

I'll withdraw DIP32 and will open new DIP for only built-in tuple syntax
proposal.

Kenji Hara


Re: A Discussion of Tuple Syntax

2013-08-19 Thread Meta

Aggh, misposted. Let's try that again.

On Tuesday, 20 August 2013 at 02:51:20 UTC, Meta wrote:

On Tuesday, 20 August 2013 at 01:06:28 UTC, H. S. Teoh wrote:
Actually, reading through DIP32 again, it sounds like Kenji is 
proposing
the *same* syntax for both built-in tuples and 
std.typecons.Tuple. In
the code example under "Generic type/expression tuple syntax", 
he refers
to them respectively as "tuple type" and "tuple value". Mixing 
is also

allowed (e.g., in the "alias Fields" line).


Maybe mixing should be disallowed, then, unless your tuple was
constructed from a variadic template argument list.

//Error. Tuple containing types
//at runtime doesn't make any sense
auto tup = #(1, int);
//Error
auto tup = #(int, string);
//Ok
auto tup = #(1, "a", true);

T[0] Test(T...)(T ts)
{
//Okay, each element of T can
//be statically inspected to ensure
//that you don't do something weird
auto tup = T;
//Also okay
alias tup = T;
//Error
auto tup = #(int, string, bool);
//Ok
alias tup = #(int, string, bool);
}

There might be some areas where this conflation may cause 
trouble,

...

Actually, looking at this again, it seems the problem is with 
the "tup = {1; x}" line. Does {1; x} in the above code mean 
{1; 123}, or does it mean {1; {alias of x}}? For example, if 
you wrote this:


int x=123;
auto tup = {1; x};
x++;
writeln(tup);

What should be the output?


I'd say that x++ would not modify the x within the tuple. It's 
the same as:


int x = 123;
auto y = x;
x++;
writeln(y);

Y is not changed, of course. However, if the tuple contains a 
reference type, such as a slice, then it would be modified.


int[] x = [123];
auto tup = #(1, x);
x[]++;
//Prints #(1, [124])
writeln(tupe);


Should the output change if the second line
is changed to:

alias tup = {1; x};

?


I don't think this should be possible. It would be the same as 
doing:


alias two = 3; //Error

Unless the tuple contained only types. Then it would be possible.

alias intAndStr = #(int, string); //Ok

The semantics are fairly easy when a tuple contains only values 
and only types. The hard part is when it contains both values AND 
types, so that should be severely limited, maybe only within 
variadic templates.


I can't remember where this was mentioned... I think it was in 
one of the other tuple threads I linked, and I think you brought 
it up, Teo.


auto tup = #(1, "a");
alias tupType = typeof(tup);

While tup is a value, its type is #(int, string). In other words, 
the type of a tuple value is a TypeTuple (alias tuple, whatever). 
Which means the type of a tuple is a tuple itself, which is 
pretty nifty.


Re: A Discussion of Tuple Syntax

2013-08-19 Thread Meta

On Tuesday, 20 August 2013 at 01:06:28 UTC, H. S. Teoh wrote:
Actually, reading through DIP32 again, it sounds like Kenji is 
proposing
the *same* syntax for both built-in tuples and 
std.typecons.Tuple. In
the code example under "Generic type/expression tuple syntax", 
he refers
to them respectively as "tuple type" and "tuple value". Mixing 
is also

allowed (e.g., in the "alias Fields" line).


Maybe mixing should be disallowed, then, unless your tuple was 
constructed from a variadic template argument list.


auto tup = #(1, int); //ERROR

template TMP(T...)
{

auto tup = T;
}

So it sounds like this is similar to what bearophile was 
suggesting --
the unification of built-in tuples and Phobos Tuples. I suppose 
the
intention is that if a built-in tuple like (1, "a", 1.0) is 
used as a
value, it would be automatically translated into a runtime 
tuple value.
I'm not sure if the reverse is possible, though, since if the 
tuple
contains some runtime values, then it's not possible to 
translate it

back into a built-in tuple.

Actually, going in either direction requires some restrictions; 
for
example, if a tuple contains a type, like (1, int), then it's 
impossible
to translate it into a runtime tuple (types have no runtime 
value in and
of themselves). Similarly, if a tuple contains a runtime 
variable, then
it's impossible to use it as a compile-time tuple. But if a 
tuple
contains only compile-time known values, then it's in theory 
usable both

as a built-in tuple and a runtime tuple.

There might be some areas where this conflation may cause 
trouble,
though; for example, if you have a tuple (1, x) where x is a 
runtime
variable, then should it be treated as (1, {alias of x}) or (1, 
{runtime
value of x})? The former would happen if you pass it to a 
template that
expects an int and and alias parameter, for example, and the 
latter if
you try to store this tuple into a variable. It may lead to 
this weird

situation:

template Tmpl(int x, alias y) { ... }
int x=123;
auto tup = {1; x};
alias T = Tmpl!tup; // OK, 1 -> int x, x -> alias y
auto tup2 = tup;// store {1;123} into variable
	alias U = Tmpl!tup2;	// ERROR: cannot instantiate template 
with runtime variable


Actually, looking at this again, it seems the problem is with 
the "tup =
{1; x}" line. Does {1; x} in the above code mean {1; 123}, or 
does it

mean {1; {alias of x}}? For example, if you wrote this:

int x=123;
auto tup = {1; x};
x++;
writeln(tup);

What should be the output? Should the output change if the 
second line

is changed to:

alias tup = {1; x};

?


T




Re: A Discussion of Tuple Syntax

2013-08-19 Thread bearophile

Andrei Alexandrescu:


return tuple(1, "a");


About the same syntax should work for both packing and unpacking 
tuples.


Bye,
bearophile


Re: A Discussion of Tuple Syntax

2013-08-19 Thread Dicebot
Random idea - what do you thing about merging current Tuple and 
TypeTuple into one and than separating them back with new and 
clear semantics - "run-time tuple" vs "compile-time tuple" with 
two distinct literals? TypeTuple and Tuple then can remain as 
compatibility deprecated implementations.


Re: A Discussion of Tuple Syntax

2013-08-19 Thread H. S. Teoh
On Tue, Aug 20, 2013 at 02:40:00AM +0200, Meta wrote:
> On Tuesday, 20 August 2013 at 00:29:17 UTC, H. S. Teoh wrote:
> >Sounds like you're confused about what built-in tuples are (and
> >you wouldn't be the first -- they're rather confusing things).
> 
> I know the difference between std.typecons.Tuple and the built-in
> tuples. What I'm confused about is I thought that the main objective
> of the tuple literal syntax (destructuring/pattern matching aside)
> was a means to have first-class tuples. That is, tuples that have
> their own literal syntax, have a list of valid operations that can
> be done on them, can be passed to functions, and can be returned
> from functions.

Actually, reading through DIP32 again, it sounds like Kenji is proposing
the *same* syntax for both built-in tuples and std.typecons.Tuple. In
the code example under "Generic type/expression tuple syntax", he refers
to them respectively as "tuple type" and "tuple value". Mixing is also
allowed (e.g., in the "alias Fields" line).

So it sounds like this is similar to what bearophile was suggesting --
the unification of built-in tuples and Phobos Tuples. I suppose the
intention is that if a built-in tuple like (1, "a", 1.0) is used as a
value, it would be automatically translated into a runtime tuple value.
I'm not sure if the reverse is possible, though, since if the tuple
contains some runtime values, then it's not possible to translate it
back into a built-in tuple.

Actually, going in either direction requires some restrictions; for
example, if a tuple contains a type, like (1, int), then it's impossible
to translate it into a runtime tuple (types have no runtime value in and
of themselves). Similarly, if a tuple contains a runtime variable, then
it's impossible to use it as a compile-time tuple. But if a tuple
contains only compile-time known values, then it's in theory usable both
as a built-in tuple and a runtime tuple.

There might be some areas where this conflation may cause trouble,
though; for example, if you have a tuple (1, x) where x is a runtime
variable, then should it be treated as (1, {alias of x}) or (1, {runtime
value of x})? The former would happen if you pass it to a template that
expects an int and and alias parameter, for example, and the latter if
you try to store this tuple into a variable. It may lead to this weird
situation:

template Tmpl(int x, alias y) { ... }
int x=123;
auto tup = {1; x};
alias T = Tmpl!tup; // OK, 1 -> int x, x -> alias y
auto tup2 = tup;// store {1;123} into variable
alias U = Tmpl!tup2;// ERROR: cannot instantiate template with 
runtime variable

Actually, looking at this again, it seems the problem is with the "tup =
{1; x}" line. Does {1; x} in the above code mean {1; 123}, or does it
mean {1; {alias of x}}? For example, if you wrote this:

int x=123;
auto tup = {1; x};
x++;
writeln(tup);

What should be the output? Should the output change if the second line
is changed to:

alias tup = {1; x};

?


T

-- 
A mathematician is a device for turning coffee into theorems. -- P. Erdos


Re: A Discussion of Tuple Syntax

2013-08-19 Thread Meta

On Tuesday, 20 August 2013 at 00:29:17 UTC, H. S. Teoh wrote:
Sounds like you're confused about what built-in tuples are (and 
you wouldn't be the first -- they're rather confusing things).


I know the difference between std.typecons.Tuple and the built-in 
tuples. What I'm confused about is I thought that the main 
objective of the tuple literal syntax (destructuring/pattern 
matching aside) was a means to have first-class tuples. That is, 
tuples that have their own literal syntax, have a list of valid 
operations that can be done on them, can be passed to functions, 
and can be returned from functions.


Whether this is implemented as a syntactic sugar for 
std.typecons.Tuple, syntactic sugar for the built-in tuples, or a 
primitive type analogous to int, char, double[], etc. is not 
particularly important. It's becoming clear, now, that everyone 
has a different idea about what tuples should comprise, and I 
believe I have a better understanding of why this issue has yet 
to be solved.


The answer is, this code makes no sense, because you can't 
return
template arguments from a function. It makes as much sense as 
returning
a function's signature from a function. You can't do that, 
because a

function's signature isn't a runtime value that can be returned.

Similarly:

return TypeTuple!(int, 1);

doesn't really make sense. The tuple (int, 1) isn't a runtime 
value that
you can return from a function. It's a compile-time concept 
that doesn't

exist at runtime.


All which makes it not first-class.

Let's return, then, to Kenji's DIP, and ask how the semantics he 
described can be implemented in D, unless someone objects to some 
facet of the DIP, at which point it can be worked out.


Re: A Discussion of Tuple Syntax

2013-08-19 Thread Dicebot

On Tuesday, 20 August 2013 at 00:28:47 UTC, Meta wrote:
Yes, changing semantics is a bad thing, which is why I was 
originally thinking of the tuple syntax as sugar for 
std.typecons.Tuple. The proposed syntax takes a hit if it is 
just sugar for the compiler tuples. They will break in some 
cases when being passed to functions, and will still not be 
able to be returned from functions.


It is not about sugar. It is about having entity in standard 
library to express concept that is built in into language and 
confusion it creates. Fixing semantics to allow _even more 
auto-expansion_ is a nice possible side effect.


What you ask it is done by Tuple and there is nothing special 
about it - it is a struct, normal value type. One may be 
disappointed with relatively verbose syntax but it is not a real 
issue. But conflating it with built-in possible is simply 
impossible - if you even start thinking about syntax that does 
it, you probably need to re-read all documentation linked in this 
topic on tuple topic.


Of course, we could have changed language in that regard - but 
this is a huge change, so complex that thinking about literal 
syntax is last thing we should do. And it does not seem to have 
much supporters to start with.


Re: A Discussion of Tuple Syntax

2013-08-19 Thread Meta

On Tuesday, 20 August 2013 at 00:13:24 UTC, Dicebot wrote:
No. No. Absolutely no. What you want is simply syntax sugar for 
std.typecons.Tuple - it is not worth any language change, 
contrary to semantical issues with built-in tuples. 
Auto-expansion and integration with function/template parameter 
lists is what makes D built-in tuple that useful and it should 
stay so with hypothetical tuple literals.


Yes, changing semantics is a bad thing, which is why I was 
originally thinking of the tuple syntax as sugar for 
std.typecons.Tuple. The proposed syntax takes a hit if it is just 
sugar for the compiler tuples. They will break in some cases when 
being passed to functions, and will still not be able to be 
returned from functions.


Re: A Discussion of Tuple Syntax

2013-08-19 Thread H. S. Teoh
On Tue, Aug 20, 2013 at 02:14:28AM +0200, Meta wrote:
> On Tuesday, 20 August 2013 at 00:03:48 UTC, Andrei Alexandrescu
> wrote:
> >On 8/19/13 4:48 PM, Meta wrote:
> >>I don't necessarily want built-in syntax for a library type, but
> >>making tuples first-class would be nice. I mean, it's a bummer that
> >>they can't be returned from functions. That should definitely be
> >>changed.
> >
> >return tuple(1, "a");
> 
> That's not a TypeTuple, though, it's a built-in tuple.

Sounds like you're confused about what built-in tuples are (and you
wouldn't be the first -- they're rather confusing things). They are
perhaps best thought of as template argument lists. As such, they have
no runtime value or, as Andrej puts it, they have no ABI. So it doesn't
make sense to return them from a function. What should be the meaning,
for example, of:

template fun(A...) {
auto fun() {
return A;
}
}

?

The answer is, this code makes no sense, because you can't return
template arguments from a function. It makes as much sense as returning
a function's signature from a function. You can't do that, because a
function's signature isn't a runtime value that can be returned.

Similarly:

return TypeTuple!(int, 1);

doesn't really make sense. The tuple (int, 1) isn't a runtime value that
you can return from a function. It's a compile-time concept that doesn't
exist at runtime.


T

-- 
MACINTOSH: Most Applications Crash, If Not, The Operating System Hangs


Re: A Discussion of Tuple Syntax

2013-08-19 Thread Andrei Alexandrescu

On 8/19/13 5:14 PM, Meta wrote:

On Tuesday, 20 August 2013 at 00:03:48 UTC, Andrei Alexandrescu wrote:

On 8/19/13 4:48 PM, Meta wrote:

I don't necessarily want built-in syntax for a library type, but making
tuples first-class would be nice. I mean, it's a bummer that they can't
be returned from functions. That should definitely be changed.


return tuple(1, "a");


That's not a TypeTuple, though, it's a built-in tuple.

void main()
{
 writeln(func());
}

TypeTuple!(int, string) func()
{
 return tuple(1, "a"); //Error
}

Nor does it work the other way around:

Tuple!(int, string) func()
{
 return TypeTuple!(1, "a"); //Error
}

How would this work for some hypothetical built-in syntax?

#(int, string) func()
{
 return tuple(1, "a"); //Error?
}


Why would it be necessary to return an object of type TypeTuple (i.e. 
template tuple)? It has no state.


Andrei



Re: A Discussion of Tuple Syntax

2013-08-19 Thread Meta

On Tuesday, 20 August 2013 at 00:14:30 UTC, Meta wrote:

That's not a TypeTuple, though, it's a built-in tuple.


s/built-in tuple/library tuple


Re: A Discussion of Tuple Syntax

2013-08-19 Thread Meta
On Tuesday, 20 August 2013 at 00:03:48 UTC, Andrei Alexandrescu 
wrote:

On 8/19/13 4:48 PM, Meta wrote:
I don't necessarily want built-in syntax for a library type, 
but making
tuples first-class would be nice. I mean, it's a bummer that 
they can't

be returned from functions. That should definitely be changed.


return tuple(1, "a");


That's not a TypeTuple, though, it's a built-in tuple.

void main()
{
writeln(func());
}

TypeTuple!(int, string) func()
{
return tuple(1, "a"); //Error
}

Nor does it work the other way around:

Tuple!(int, string) func()
{
return TypeTuple!(1, "a"); //Error
}

How would this work for some hypothetical built-in syntax?

#(int, string) func()
{
return tuple(1, "a"); //Error?
}


Re: A Discussion of Tuple Syntax

2013-08-19 Thread Dicebot

On Monday, 19 August 2013 at 23:55:32 UTC, Meta wrote:

On Monday, 19 August 2013 at 23:48:36 UTC, Meta wrote:

...


An addendum:

void main()
{
//Prints 1
writeln(func(TypeTuple!(1, 2)));
}

int func(int i, int j)
{
return i;
}

This is bad and should never be allowed with some hypothetical 
tuple literal syntax. The desired behaviour is:


void main()
{
//Error: func is not callable using argument types (#(int, 
int))

writeln(func(#(1, 2));
}

*Unless* you use .expand/[] (pick your poison):

void main()
{
writeln(func(#(1, 2).expand)); //Or #(1, 2)[]
}


No. No. Absolutely no. What you want is simply syntax sugar for 
std.typecons.Tuple - it is not worth any language change, 
contrary to semantical issues with built-in tuples. 
Auto-expansion and integration with function/template parameter 
lists is what makes D built-in tuple that useful and it should 
stay so with hypothetical tuple literals.


Re: A Discussion of Tuple Syntax

2013-08-19 Thread Andrei Alexandrescu

On 8/19/13 4:48 PM, Meta wrote:

I don't necessarily want built-in syntax for a library type, but making
tuples first-class would be nice. I mean, it's a bummer that they can't
be returned from functions. That should definitely be changed.


return tuple(1, "a");


Andrei



Re: A Discussion of Tuple Syntax

2013-08-19 Thread Meta

On Monday, 19 August 2013 at 23:48:36 UTC, Meta wrote:

...


An addendum:

void main()
{
//Prints 1
writeln(func(TypeTuple!(1, 2)));
}

int func(int i, int j)
{
return i;
}

This is bad and should never be allowed with some hypothetical 
tuple literal syntax. The desired behaviour is:


void main()
{
//Error: func is not callable using argument types (#(int, 
int))

writeln(func(#(1, 2));
}

*Unless* you use .expand/[] (pick your poison):

void main()
{
writeln(func(#(1, 2).expand)); //Or #(1, 2)[]
}


Re: A Discussion of Tuple Syntax

2013-08-19 Thread Meta

On Monday, 19 August 2013 at 18:40:58 UTC, H. S. Teoh wrote:

Case in point. :)

So we're actually talking at cross purposes here. Bearophile & 
Meta et
al want native syntax for *runtime* tuples (i.e. 
std.typecons.Tuple --
sorry for the mixup with std.range in my earlier posts), but 
you're
talking about native syntax for alias tuples (aka TypeTuples). 
Two

completely different things.


Now that I reread Kenji's DIP for a third time, I see/recall that 
his intention was for this syntax to be for alias tuples. In that 
case, wouldn't this necessitate a change in semantics? Will these 
alias tuples using built-in syntax still auto-expand?


I agree that we shouldn't be making built-in syntax for a 
library type.
If anything, any dedicated syntax should be reserved for alias 
tuples
(aka std.typetuple.Typetuple). Or, at the very least, rename 
TypeTuple

to AliasTuple.


I don't necessarily want built-in syntax for a library type, but 
making tuples first-class would be nice. I mean, it's a bummer 
that they can't be returned from functions. That should 
definitely be changed.


Conflating these two concepts has led to endless confusion, 
which is why
I insisted on addressing this issue before we even begin to 
talk about

syntax. Otherwise we're going nowhere.


T




Re: A Discussion of Tuple Syntax

2013-08-19 Thread bearophile

ixid:


Are singleton tuples actually useful for anything?


They are not much useful, but unless you want to outlaw them, you 
have to keep them in account when you design a syntax.


Bye,
bearophile


Re: A Discussion of Tuple Syntax

2013-08-19 Thread ixid

On Monday, 19 August 2013 at 22:36:34 UTC, bearophile wrote:

ixid:


auto assoc_array = [1 : (2 : 3)]; // A tuple associative value
auto assoc_array2 = [(1 : 2) : 3]; // A tuple associative key

auto ternary = value? (1 : 2) : (3 : 4); // tuple values in a 
ternary operator


It's nicer looking than #().


Are singleton tuples represented with (1:) ?

Bye,
bearophile


Sure, why not? It looks happy enough. :) Are singleton tuples 
actually useful for anything?


Re: A Discussion of Tuple Syntax

2013-08-19 Thread Meta

On Monday, 19 August 2013 at 18:43:37 UTC, Meta wrote:

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 was being dumb, [1, 2] ~ 3 is of course valid for arrays, so 
that should work for tuples as well. Furthermore, #(1, 2) ~ "a" 
should be valid, and will result in #(1, 2, "a").


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.


The tricky part of this that I forgot to mention is that you 
can't do this with arrays, so we're in unknown territory, but I 
think this is sensible. Again, it's quite ugly, but oh well.


Re: A Discussion of Tuple Syntax

2013-08-19 Thread captaindet

On 2013-08-19 17:04, Meta wrote:

On Monday, 19 August 2013 at 21:03:50 UTC, Andrei Alexandrescu
wrote:

b) syntactic support for ignoring certain members in a
destructuring - is that really needed?

auto (a, ?, c) =
functionReturningTupleOrStaticArrayWith3Elements();


In fairness, it is very common in other languages with pattern
matching/destructuring. Off the top of my head I can think of
Haskell, ML, Racket, Javascript (destructuring only) and Rust.


same in matlab. once destruction->auto assignment is available, (future) 
library functions will make heavy use of it, e.g. statistics functions returning 
lots of parameters/characteristics for a dataset. more often than not one is only 
interested in a few.

/det


Re: A Discussion of Tuple Syntax

2013-08-19 Thread bearophile

ixid:


auto assoc_array = [1 : (2 : 3)]; // A tuple associative value
auto assoc_array2 = [(1 : 2) : 3]; // A tuple associative key

auto ternary = value? (1 : 2) : (3 : 4); // tuple values in a 
ternary operator


It's nicer looking than #().


Are singleton tuples represented with (1:) ?

Bye,
bearophile


Re: A Discussion of Tuple Syntax

2013-08-19 Thread ixid

On Friday, 16 August 2013 at 23:48:53 UTC, bearophile wrote:

Meta:

Andrei/Walter didn't want to merge that pull request without a 
full consideration of the different design issues involved, 
which in retrospect was a good decision.


I agree that before adding some new syntax you have to think 
well.



- {a, b} is not as pretty, but it's not that bad of an 
alternative (though it may still have issues as well)


It has technical issues, they were discussed in one of the last 
threads. Such problems should be added in a note in the DIP32, 
so they don't get lost in time.



- #(a, b) is unambiguous and would probably be the easiest 
option. I don't think it looks too bad, but some people might 
find it ugly and noisy


It looks nice (but I don't know if it's technically usable), I 
have added it at the end of the list of alternative syntaxes:

http://wiki.dlang.org/DIP32#Use_case_of_uniform_tuple_syntax


I personally think #(a, ?) or #(a, *) would be best, but all 
that's  really necessary is a symbol that cannot also be an 
identifier.


I think ? is clear, unambiguous, etc, and I like it. The * is 
already used for pointers, product, dereferencing, ** is used 
for pow, so it's better to not add further meanings to it.



- Concatenating tuples with ~. This is nice to have, but not 
particularly important.


In theory I like this operation, but in practice in my D code I 
don't need it often, so I think it should be left out, for 
later.
In Python I sometimes concatenate tuples, but in such use cases 
they are essentially immutable dynamically typed arrays, losing 
their positional meaning.



Tuples could also be used in switch/case statements, to support 
a very basic form of pattern matching. See also a standard 
method named "unapply" I have discussed a bit here, coming from 
Scala language, that is a very simple solution to solve a 
significant problem:

http://d.puremagic.com/issues/show_bug.cgi?id=596

Bye,
bearophile


What about using : as people had intended to use the comma 
operator?

uint a, b;
(a : b) = (1 : 2);
(a : b) = tupleReturningFunction;
auto c = (1 : (2 : 3)); // A tuple containing a tuple
auto d = (1 : ((2 : 3) : (4 : 5))); // a tuple with a tuple of 
tuples as a member


auto assoc_array = [1 : (2 : 3)]; // A tuple associative value
auto assoc_array2 = [(1 : 2) : 3]; // A tuple associative key

auto ternary = value? (1 : 2) : (3 : 4); // tuple values in a 
ternary operator


It's nicer looking than #().


Re: A Discussion of Tuple Syntax

2013-08-19 Thread Meta
On Monday, 19 August 2013 at 21:03:50 UTC, Andrei Alexandrescu 
wrote:
I'm saying that there's a mix of useful stuff and just 
syntactic additions that are arguably less so. In my opinion:


a) destructuring tuples in auto declarations - good to have:

auto (a, b, c) = 
functionReturningTupleOrStaticArrayWith3Elements();


b) syntactic support for ignoring certain members in a 
destructuring - is that really needed?


auto (a, ?, c) = 
functionReturningTupleOrStaticArrayWith3Elements();


In fairness, it is very common in other languages with pattern 
matching/destructuring. Off the top of my head I can think of 
Haskell, ML, Racket, Javascript (destructuring only) and Rust. 
This syntax is more important when pattern matching, but also 
seems to be almost universally used in destructuring. From the 
DIP:


switch (tup) {
case {1, 2}:
case {$, 2}: //Don't care what the first value is, only match 
on second

case {1, x}:
default:
}

You could just replace {$, 2} with {x, 2} and never use x, but 
this creates the problem that Bearophile mentioned.


auto t1 = #(5, "hello", 1.5); //Fine
auto #(_,  _, x) = t1; //Dammit, can't use _ twice as it's a 
variable


If you replace _ with throwaway variable names, it becomes much 
less clear (IMO) exactly what is going on. Any programmer reading 
your code would have to examine the function to see if the 
bindings introduced are ever used, or if they are just throwaways.


Maybe it's unproductive to argue over the colour of the bike 
shed, but we need to know whether it's worth adding windows.


Re: A Discussion of Tuple Syntax

2013-08-19 Thread Brad Anderson

On Monday, 19 August 2013 at 21:16:43 UTC, Brad Anderson wrote:

On Monday, 19 August 2013 at 19:24:32 UTC, Timon Gehr wrote:

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)


Nice short FAQ for one of the more confusing parts of D.  The 
name "template argument list" clears things up quite a bit 
actually (but is too long for a type name).  Is it your idea to 
use Seq instead of TypeTuple?


Pretty heavy on the snark though :P


Re: A Discussion of Tuple Syntax

2013-08-19 Thread Dicebot
On Monday, 19 August 2013 at 21:03:50 UTC, Andrei Alexandrescu 
wrote:
I'm saying that there's a mix of useful stuff and just 
syntactic additions that are arguably less so.


Wanted to note here that while discussing syntax at this moment 
is indeed mostly useless but playing with imaginary code snippets 
does help to understand what behavior people want to see and that 
can be used as a basis for formalizing semantics.


Re: A Discussion of Tuple Syntax

2013-08-19 Thread Brad Anderson

On Monday, 19 August 2013 at 19:24:32 UTC, Timon Gehr wrote:

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)


Nice short FAQ for one of the more confusing parts of D.  The 
name "template argument list" clears things up quite a bit 
actually (but is too long for a type name).  Is it your idea to 
use Seq instead of TypeTuple?


Re: A Discussion of Tuple Syntax

2013-08-19 Thread Dicebot
On Monday, 19 August 2013 at 20:51:47 UTC, Andrei Alexandrescu 
wrote:
Normal alias. Yah, perhaps "template tuples" are more 
descriptive.


And how would you call _instance_ of template tuple then? (which 
is also built-in tuple but not template tuple)


Re: A Discussion of Tuple Syntax

2013-08-19 Thread Andrei Alexandrescu

On Monday, 19 August 2013 at 20:46:02 UTC, Andrei Alexandrescu wrote:

It's stuff like this that's just useless and gives a bad
direction to the whole discussion. There's hardly anything
wrong with auto x = t1[2] or auto gr = t1[1], but once the
bikeshed is up for painting, the rainbow won't suffice.


I started this discussion to build on Kenji's DIP, which discusses 
destructuring and pattern matching syntax in addition to tuple literal 
syntax, as well as the previous discussion that's already gone on in the 
two "DIP discussion" threads. Are you saying that you dislike the 
destructuring/pattern matching discussion as a whole?


I'm saying that there's a mix of useful stuff and just syntactic 
additions that are arguably less so. In my opinion:


a) destructuring tuples in auto declarations - good to have:

auto (a, b, c) = functionReturningTupleOrStaticArrayWith3Elements();

b) syntactic support for ignoring certain members in a destructuring - 
is that really needed?


auto (a, ?, c) = functionReturningTupleOrStaticArrayWith3Elements();


Andrei


Re: A Discussion of Tuple Syntax

2013-08-19 Thread bearophile

Andrei Alexandrescu:

It's stuff like this that's just useless and gives a bad 
direction to the whole discussion. There's hardly anything 
wrong with auto x = t1[2] or auto gr = t1[1], but once the 
bikeshed is up for painting, the rainbow won't suffice.


I was just explaining why _ can't be used as wildcard (unless you 
also make _ a not valid variable name), it wasn't meant to be an 
example of why wildcards are useful in the first place.


Bye,
bearophile


Re: A Discussion of Tuple Syntax

2013-08-19 Thread Meta
On Monday, 19 August 2013 at 20:46:02 UTC, Andrei Alexandrescu 
wrote:
It's stuff like this that's just useless and gives a bad 
direction to the whole discussion. There's hardly anything 
wrong with auto x = t1[2] or auto gr = t1[1], but once the 
bikeshed is up for painting, the rainbow won't suffice.


I started this discussion to build on Kenji's DIP, which 
discusses destructuring and pattern matching syntax in addition 
to tuple literal syntax, as well as the previous discussion 
that's already gone on in the two "DIP discussion" threads. Are 
you saying that you dislike the destructuring/pattern matching 
discussion as a whole?




Re: A Discussion of Tuple Syntax

2013-08-19 Thread Andrei Alexandrescu

On 8/19/13 1:41 PM, Dicebot wrote:

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? ;)


Normal alias. Yah, perhaps "template tuples" are more descriptive.

Andrei



Re: A Discussion of Tuple Syntax

2013-08-19 Thread Andrei Alexandrescu

On 8/19/13 12:54 PM, bearophile wrote:

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


It's stuff like this that's just useless and gives a bad direction to 
the whole discussion. There's hardly anything wrong with auto x = t1[2] 
or auto gr = t1[1], but once the bikeshed is up for painting, the 
rainbow won't suffice.



Andrei



Re: A Discussion of Tuple Syntax

2013-08-19 Thread Dicebot
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.




Re: A Discussion of Tuple Syntax

2013-08-19 Thread Andrei Alexandrescu

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



Re: A Discussion of Tuple Syntax

2013-08-19 Thread Andrei Alexandrescu

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



Re: A Discussion of Tuple Syntax

2013-08-19 Thread bearophile

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


Re: A Discussion of Tuple Syntax

2013-08-19 Thread Meta

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

...


That too.


  1   2   >