November 02, 2010
%u wrote:
...
> 
> template T(A...) { alias A T; }
> 
> void main() {
>   auto a = true ? new B : new C;
> // these don't work - why?
> //  auto b = [new B, new C];
> //  auto c = { return [1: new B,2: new C]; };

I think it should, it works for arithmetic types. See this bug report:

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

>   T!(int,int) e = (1,2);

I am surprised this works since D doesn't have a tuple literal syntax.

>   e = T!(3,4);
> 
> // ah - so (1,2) syntax on initialization, T!(1,2) when assigning!
>   T!(int,int) d = T!(1,2);
> 
>   e = d;
> 
> // tuples aren't first class, why?
> //  auto f = { return e; };
> }

There has been discussion about this, as mentioned by bearophile.

In summary, the reason for not having first class tuples is that current language constructs provide sufficient means to express tuples as a library type, see http://www.digitalmars.com/d/2.0/phobos/std_typecons.html#Tuple.

You can do most - but not all - of what builtin tuples could do with that template.

November 02, 2010
Torarin Wrote:

> > // these don't work - why?
> > //  auto b = [new B, new C];
> > //  auto c = { return [1: new B,2: new C]; };
> 
> That seems to be just a matter of improving the compiler to make it find the common type. I don't think there's anything in the language stopping that from working.

I don't recall why it doesn't find the common type. But what it does do is use the last element to deduce the type, so there are two ways to make this work.

auto b = [new B, cast(A) new C];
auto b = [new B, new C, new A];

What I don't really like is that it can't be fixed with:

A[] b = [new B, new C];
November 02, 2010
Simen kjaeraas Wrote:

> Examples from the reftuple page:
> 
> 
> int a, b;
> _(a,b) = tuple(b,a); // swap
> _(a,b) = tuple(b,a+b); // fibonacci
> 
> int[] arr = [0,1,2,3,4];
> int [] c;
> _(a,b,c) = arr; // a = 0, b = 1, c = [2,3,4]

This is close to what I had in mind, thanks! I just find it odd..

arr is int[]
a, b are int and c is int[]

int[] becomes int, int, and int[]

Does the same work if I want to extract tuple elements in similar way? Does it support nested tuples well? Gotta try.
November 02, 2010
2010/11/2 Simen kjaeraas <simen.kjaras@gmail.com>:
> I believe it has been discussed numerous times before that the ?: test should be used to find the element type - not sure why it isn't.

That is indeed what TDPL says.
November 02, 2010
Simen kjaeraas wrote:

> %u <user@web.news> wrote:
> 
>> class A {}
>> class B : A {}
>> class C : A {}
>>
>> template T(A...) { alias A T; }
>>
>> void main() {
>>   auto a = true ? new B : new C;
>> // these don't work - why?
>> //  auto b = [new B, new C];
>> //  auto c = { return [1: new B,2: new C]; };
> 
> "The type of the first element is taken to be the type of all the elements, and all elements are implicitly converted to that type." (http://digitalmars.com/d/2.0/expression.html#ArrayLiteral)
> 
> I believe it has been discussed numerous times before that the ?: test should be used to find the element type - not sure why it isn't.

It is stated in TDPL that the ?: test should be used, and it already works:

auto a = [1,2,3.5];
pragma(msg, typeof(a).stringof); // prints double[], not int[]


> 
>>   T!(int,int) e = (1,2);
>>   e = T!(3,4);
>>
>> // ah - so (1,2) syntax on initialization, T!(1,2) when assigning!
>>   T!(int,int) d = T!(1,2);
>>
>>   e = d;
>>
>> // tuples aren't first class, why?
>> //  auto f = { return e; };
>> }
> 
> Compile-time argument tuples are something of a strange beast. They behave not very unlike tuples, but due to their ability to hold types, literals, expressions and aliases to whatever, they are not a very good match for what you'd expect tuples to be. (e.g, what do you expect T!(3,T) to be?)
> 
> For tuples, you should instead look into std.typecons' Tuple struct and tuple function:
> 
> Tuple!( int, "n", string, "s" ) tup;
> tup.n = 4;
> tup.s = "A string! My kingdom for a string!";
> 
> auto tup2 = tuple( 1, 2 );
> assert( is( typeof( tup2 ) == Tuple!( int, int ) ) );
> 
> 
> For even better support of tuples, you should have a look-see at Philippe Sigaud's dranges.tuple and dranges.reftuple (http://svn.dsource.org/projects/dranges/trunk/dranges/docs/tuple.html and http://svn.dsource.org/projects/dranges/trunk/dranges/docs/reftuple.html)
> 
> The latter is absolutely awesome, and should be made part of phobos ASAP, IMO (though according to the documentation, it is not in tip-top shape).
...

vote++


November 02, 2010
Lutger Wrote:

> %u wrote:
> ...
> > 
> > template T(A...) { alias A T; }
> > 
> > void main() {
> >   auto a = true ? new B : new C;
> > // these don't work - why?
> > //  auto b = [new B, new C];
> > //  auto c = { return [1: new B,2: new C]; };
> 
> I think it should, it works for arithmetic types. See this bug report:
> 
> http://d.puremagic.com/issues/show_bug.cgi?id=3543

Thanks. I understand it's a known bug now. The explicit casts shown in this thread are what annoy me. In code review you have to add a comment "// totally unnecessary cast, but see dmd bug #3543". Confuses new users. Not anything serious and there's a workaround. Just annoys. Especially if code guide tells to avoid casts. Especially now that I found it by accident and always remember it.

> 
> >   T!(int,int) e = (1,2);
> 
> I am surprised this works since D doesn't have a tuple literal syntax.

I actually found these examples when doing a google search. Wanted to see how tuples in D work. I didn't realize there's a library solution. We should probably remove the old newsgroup posts of this errorenous "tuple". If we can hide it well enough, new users won't even notice DMD accepts this confusing code.

> 
> >   e = T!(3,4);
> > 
> > // ah - so (1,2) syntax on initialization, T!(1,2) when assigning!
> >   T!(int,int) d = T!(1,2);
> > 
> >   e = d;
> > 
> > // tuples aren't first class, why?
> > //  auto f = { return e; };
> > }
> 
> There has been discussion about this, as mentioned by bearophile.
> 
> In summary, the reason for not having first class tuples is that current language constructs provide sufficient means to express tuples as a library type, see http://www.digitalmars.com/d/2.0/phobos/std_typecons.html#Tuple.
> 
> You can do most - but not all - of what builtin tuples could do with that template.

Crazy.. yes, the library solution is enough to make the language orthogonal in this way. It just confuses me why dmd almost accepts what I did.
November 02, 2010
On 11/2/10 7:53 AM, %u wrote:
> I found a slideshow called 'The Expressiveness of Go' recently. The conclusions are:
>
> * Go is not a small language but it is an expressive and comprehensible one.
>
> * Expressiveness comes from orthogonal composition of constructs.
>
> * Comprehensibility comes from simple constructs that interact in easily understood ways.
>
> * Build a language from simple orthogonal constructs and you have a language that will be easy and productive to use.
>
> * The surprises you discover will be pleasant ones.
>
> ----

The slides fared surprisingly poorly with reddit, though I'm not sure what that proves (if anything) :o).

> Is D orthogonal? Could it be more orthogonal?

Orthogonality has been long debated in the PL community. Clearly in reasonable quantities it's a desirable trait, but one must also know where to stop. There are many orthogonal languages that people didn't quite enjoy. The most orthogonal of all is Algol, but next to no one could bring themselves to actually use it.

Humans are not orthogonal, our linguistic and related abilities don't thrive on orthogonality, so it's a tenuous case that orthogonality must be a be-all end-all of programming languages.

> Two things come to my mind: removing special cases and making widely used things first class. For data types this means that they have literals, can be given to functions and returned from functions. I made a small test and found that the discoveries aren't pleasant to me:
>
>
> class A {}
> class B : A {}
> class C : A {}
>
> template T(A...) { alias A T; }
>
> void main() {
>    auto a = true ? new B : new C;
> // these don't work - why?
> //  auto b = [new B, new C];

Compiler bug. Must deduce common type as A.

> //  auto c = { return [1: new B,2: new C]; };

Compiler bug again.

>    T!(int,int) e = (1,2);
>    e = T!(3,4);

Variadic alias tuples (incorrectly called type tuples) are one of the more awkward features of the language. Though I agree they should ideally be made more palatable, I suggest using Tuple instead:

auto e = tuple(1, 2);
e = tuple(3, 4);

> // ah - so (1,2) syntax on initialization, T!(1,2) when assigning!
>    T!(int,int) d = T!(1,2);

auto d = tuple(1, 2);

>    e = d;
>
> // tuples aren't first class, why?
> //  auto f = { return e; };
> }

This should work with the library tuples.


Andrei
November 02, 2010
On 11/2/10 8:39 AM, Torarin wrote:
>> // these don't work - why?
>> //  auto b = [new B, new C];
>> //  auto c = { return [1: new B,2: new C]; };
>
> That seems to be just a matter of improving the compiler to make it
> find the common type. I don't think there's anything in the language
> stopping that from working.

Yah, in fact it's a recent addition that it even attempts to find the common type. While I was writing TDPL, the first draft mentioned the rule then in effect: the literal array type is exclusively determined by its first element. The common type rule was only introduced later (though in time to fix TDPL), so I'm not surprised there is a glitch in there.

Andrei
November 02, 2010
On 11/2/10 9:07 AM, Simen kjaeraas wrote:
> %u <user@web.news> wrote:
>
>> class A {}
>> class B : A {}
>> class C : A {}
>>
>> template T(A...) { alias A T; }
>>
>> void main() {
>> auto a = true ? new B : new C;
>> // these don't work - why?
>> // auto b = [new B, new C];
>> // auto c = { return [1: new B,2: new C]; };
>
> "The type of the first element is taken to be the type of all the
> elements, and all elements are implicitly converted to that type."
> (http://digitalmars.com/d/2.0/expression.html#ArrayLiteral)
>
> I believe it has been discussed numerous times before that the ?:
> test should be used to find the element type - not sure why it
> isn't.

Looks like outdated documentation to me.

>> T!(int,int) e = (1,2);
>> e = T!(3,4);
>>
>> // ah - so (1,2) syntax on initialization, T!(1,2) when assigning!
>> T!(int,int) d = T!(1,2);
>>
>> e = d;
>>
>> // tuples aren't first class, why?
>> // auto f = { return e; };
>> }
>
> Compile-time argument tuples are something of a strange beast. They
> behave not very unlike tuples, but due to their ability to hold
> types, literals, expressions and aliases to whatever, they are not
> a very good match for what you'd expect tuples to be. (e.g, what do
> you expect T!(3,T) to be?)
>
> For tuples, you should instead look into std.typecons' Tuple struct
> and tuple function:
>
> Tuple!( int, "n", string, "s" ) tup;
> tup.n = 4;
> tup.s = "A string! My kingdom for a string!";
>
> auto tup2 = tuple( 1, 2 );
> assert( is( typeof( tup2 ) == Tuple!( int, int ) ) );
>
>
> For even better support of tuples, you should have a look-see at
> Philippe Sigaud's dranges.tuple and dranges.reftuple
> (http://svn.dsource.org/projects/dranges/trunk/dranges/docs/tuple.html
> and
> http://svn.dsource.org/projects/dranges/trunk/dranges/docs/reftuple.html)
>
> The latter is absolutely awesome, and should be made part of
> phobos ASAP, IMO (though according to the documentation, it
> is not in tip-top shape).
>
> Examples from the reftuple page:
>
>
> int a, b;
> _(a,b) = tuple(b,a); // swap
> _(a,b) = tuple(b,a+b); // fibonacci
>
> int[] arr = [0,1,2,3,4];
> int [] c;
> _(a,b,c) = arr; // a = 0, b = 1, c = [2,3,4]

This was already contributed to in Phobos (under a different syntax) but I rejected it on grounds of safety: the value built by "_" must escape addresses of all of its arguments, so it's not safe.

My suggestion to address this issue was (and is) to make the assigned part of the function call:

int a, b;
scatter(tuple(b, a), a, b);
scatter(tuple(b, a + b), a, b);
int[] arr = [0, 1, 2, 3, 4];
int[] c;
scatter(arr, a, b, c);


Andrei
November 02, 2010
Gary Whatmore, el  2 de noviembre a las 09:40 me escribiste:
> The D way of returning tuples is:
> 
>   T!(int,int) ret;
>   auto f = (ref T!(int,int) r){ r = e; };
>   f(ret);
> 
> It doesn't look so bad if you think about it. The tuple is first stack allocated. It doesn't trigger heap allocation. High level scripting languages always cause extra heap allocation if you do
> 
> auto f = { return (1,2); };
> 
> It's much faster the D way.

What has returning a tuple has to do with heap allocation. Is like returning a struct, which you can. Not being able to return a tuple has no explanation performance-wide. If you are concerned about the copy, is the same with static arrays, which are value types in D2. So here something is not very consistent...

-- 
Leandro Lucarella (AKA luca)                     http://llucax.com.ar/
----------------------------------------------------------------------
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
----------------------------------------------------------------------
PROTESTA EN PLAZA DE MAYO: MUSICO SE COSIO LA BOCA
	-- Crónica TV