August 20, 2013
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?
}
August 20, 2013
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
August 20, 2013
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

August 20, 2013
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.
August 20, 2013
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
August 20, 2013
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.
August 20, 2013
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.
August 20, 2013
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
August 20, 2013
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.
August 20, 2013
Andrei Alexandrescu:

> return tuple(1, "a");

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

Bye,
bearophile