September 24, 2012
On Sunday, 23 September 2012 at 21:51:35 UTC, Nick Sabalausky wrote:
> Ok, here's a crazy idea:
>
> Do the reasons for explicit tuple-expansion necessarily apply to
> zero- and one-element tuples? I'm not so sure. Suppose we allowed
> implicit expansion on those...
>
> Now I know what you're thinking: That would be an ugly inconsistency
> between tuples of sizes >1 vs <=1. Well, *mechanically* yes, but
> consider this:
>
> *Logically* speaking, is there really any difference between a
> one-element tuple and an ordinary single value? I don't think so, and
> here's why: What is a tuple, logically speaking? Multiple values being
> handled as if they were a single value. So what's a one-element tuple?
> *One* value being handled as if it were one value - which is *is*.
>
> Similarly, a zero-element tuple is logically equivalent to void (or the
> one value a void can have: the value void, a concept which has been
> argued in the past that might be useful for D, particularly in
> metaprogramming). (I admit this is a little weaker than my argument
> for one-element tuples.)
>
> So perhaps zero- and one-element tuples should be implicitly
> convertible back and forth with void and ordinary non-tuple values,
> respectively (polysemous values?), because that's what they essentially
> are.
>
> That means (at least I think it means) that things like () or (1) or
> ((1)) require no way to disambiguate between tuple and expression,
> because either way they're the same thing (or at least freely
> convertible).

Nope.
One of the ways in math to "build" the positive numbers based on set theory is via singletons:
n := |tuple of empty tuples|
so "1" is defined as { {} } whereas "0" is simply {}. That does not work with the above suggestion. Now, I realize this is an arguably convoluted math example but it does show that the treating { {} } as {} is limiting the expressive power of tuples.

September 24, 2012
On 2012-09-24 07:01, Nick Sabalausky wrote:

> I think one of us is missing something, and I'm not entirely sure
> who.
>
> As I explained (perhaps poorly), the zero- and one-element tuples *would
> still be* tuples. They would just be implicitly convertible to
> non-tuple form *if* needed, and vice versa. Do you see a reason why
> that would *necessarily* not be the case?

Would that mean you could start doing things like:

int a = 3;
int b = a[0];

That feels very weird.

-- 
/Jacob Carlborg
September 24, 2012
On 2012-09-23 22:40, Andrei Alexandrescu wrote:
> I discussed this with Walter, and we concluded that we could deprecate
> the comma operator if it helps tuples. So I started with this:
>
> http://www.prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs/DIP19

+1


-- 
/Jacob Carlborg
September 24, 2012
On 2012-09-24 00:11, bearophile wrote:
> This is a complex topic, and in this post I am not able to discuss
> everything that needs to be discussed. So I will discuss only part of
> the story.
>
> First: tuples are important enough. I think they should be built-in in a
> modern language, but maybe having them as half-built-in will be enough
> in D. Currently in D we have (deprecated) built-in complex numbers that
> I use only once in a while, and half-usable library defined tuples that
> I use all the time.
>
> Second: removing comma operator from D has some advantages unrelated to
> tuple syntax. Even disallowing bad looking C-like code that uses commas
> is an improvement by itself (but maybe it's not a big enough
> improvement...).
>
> Third: replacing the packing syntax tuple(x,y) with (x,y) is nice and
> maybe even expected in a partially functional language as D, but that's
> _not_ going to improve D usability a lot. What I am asking for is
> different: I'd like D tuples to support handy unpacking syntax:
>
> 1) In function signatures;
> 2) In foreach;
> 3) At assignment points;
> 4) In switch cases.

+1

-- 
/Jacob Carlborg
September 24, 2012
On Mon, 24 Sep 2012 10:56:40 +0200
Jacob Carlborg <doob@me.com> wrote:

> On 2012-09-24 07:01, Nick Sabalausky wrote:
> 
> > I think one of us is missing something, and I'm not entirely sure who.
> >
> > As I explained (perhaps poorly), the zero- and one-element tuples *would still be* tuples. They would just be implicitly convertible to non-tuple form *if* needed, and vice versa. Do you see a reason why that would *necessarily* not be the case?
> 
> Would that mean you could start doing things like:
> 
> int a = 3;
> int b = a[0];
> 
> That feels very weird.
> 

No, because there's nothing typed (int) involved there. But you could do
this:

    int a = 3;
    (int) b = a;
    a = b;

Or this:

    void foo((int) a)
    {
        int b1 = a[0];
        int b2 = a;
    }
    int c = 3;
    foo(c);



September 24, 2012
On Mon, 24 Sep 2012 10:47:38 +0200
"foobar" <foo@bar.com> wrote:
> 
> Nope.
> One of the ways in math to "build" the positive numbers based on
> set theory is via singletons:
> n := |tuple of empty tuples|
> so "1" is defined as { {} } whereas "0" is simply {}. That does
> not work with the above suggestion. Now, I realize this is an
> arguably convoluted math example but it does show that the
> treating { {} } as {} is limiting the expressive power of tuples.
> 

And int's are limiting compared to mathematical integers. So what? So ok, maybe this is limiting from a theoretical standpoint. But practically speaking? I dunno. We're not making tuples to emulate set theory here, we're just looking for ad-hoc anonymous structs.

Besides, I only said they were logically the same thing, not mechanically. I'm only suggesting that a one-element tuple be implicitly convertible to/from the type of its element. So there would likely still be the different types, it just makes sense that you should be able to use one as the other.

September 24, 2012
On Mon, 24 Sep 2012 06:20:55 -0400
Nick Sabalausky <SeeWebsiteToContactMe@semitwist.com> wrote:

> On Mon, 24 Sep 2012 10:47:38 +0200
> "foobar" <foo@bar.com> wrote:
> > 
> > Nope.
> > One of the ways in math to "build" the positive numbers based on
> > set theory is via singletons:
> > n := |tuple of empty tuples|
> > so "1" is defined as { {} } whereas "0" is simply {}. That does
> > not work with the above suggestion. Now, I realize this is an
> > arguably convoluted math example but it does show that the
> > treating { {} } as {} is limiting the expressive power of tuples.
> > 
> 
> And int's are limiting compared to mathematical integers. So what? So ok, maybe this is limiting from a theoretical standpoint. But practically speaking? I dunno. We're not making tuples to emulate set theory here, we're just looking for ad-hoc anonymous structs.
> 
> Besides, I only said they were logically the same thing, not mechanically. I'm only suggesting that a one-element tuple be implicitly convertible to/from the type of its element. So there would likely still be the different types, it just makes sense that you should be able to use one as the other.
> 

I guess what I mean is: If you really need a strict separation between
a "tuple of one" and a non-tuple, then maybe it's an indication
that you're just using the wrong tool?

That said, I'm not necessarily opposed to the strict separation if we had a good candidate for built-in tuple literal syntax. But *if* the best we have is parens (and maybe there *is* something better?) then maybe this would be an acceptable way to achieve it?

Ie:

// (3) is polysemous: Either int or (int)
int   a = (3);  // Normal value
(int) b = (3);  // One-element tuple
auto  c = (3);  // Default to normal "int"?

void foo(int z) {}
void foo((int) z) {}

void takeInt(int z) {}
void takeTuple((int) z) {}

foo(a); // Calls first overload
foo(b); // Calls second overload

takeInt(a); // ok
takeInt(b); // ok

takeTuple(a); // ok
takeTuple(b); // ok

September 24, 2012
On 2012-09-24 12:06, Nick Sabalausky wrote:

> No, because there's nothing typed (int) involved there. But you could do
> this:
>
>      int a = 3;
>      (int) b = a;
>      a = b;

But you said:

"They would just be implicitly convertible
to non-tuple form *if* needed, and vice versa."

To me that sounds like a tuple of one element of the type int would be implicitly convertible to an int. And, an int would be implicitly convertible to a tuple of one element.

-- 
/Jacob Carlborg
September 24, 2012
On 09/24/2012 05:25 AM, Andrei Alexandrescu wrote:
> On 9/23/12 9:31 PM, deadalnix wrote:
>> Le 24/09/2012 03:14, Andrei Alexandrescu a écrit :
>>> On 9/23/12 7:20 PM, Adam D. Ruppe wrote:
>>>> On Sunday, 23 September 2012 at 22:55:33 UTC, Timon Gehr wrote:
>>>>> I believe it is currently left-to-right for D, in all kinds of
>>>>> expressions, but DMD does not implement it yet.
>>>>
>>>> Yeah, I thought it was already defined.
>>>
>>> Actually it's right to left for assignments. In expr1 = expr2, expr2
>>> gets evaluated first.
>>>
>>> Andrei
>>
>> Is it by implementation or by design ?
>
> Currently probably neither :o). I used to oppose it, then I figured it's
> actually nice because of things like:
>
> int[int] stuff;
> stuff[42] = stuff.length;
>
>
> Andrei

So you are arguing for computing the arguments for a method call before
the receiver is computed? (What about UFCS?) Or should opAssign behave
specially?
September 24, 2012
Le 24/09/2012 14:15, Jacob Carlborg a écrit :
> On 2012-09-24 12:06, Nick Sabalausky wrote:
>
>> No, because there's nothing typed (int) involved there. But you could do
>> this:
>>
>> int a = 3;
>> (int) b = a;
>> a = b;
>
> But you said:
>
> "They would just be implicitly convertible
> to non-tuple form *if* needed, and vice versa."
>
> To me that sounds like a tuple of one element of the type int would be
> implicitly convertible to an int. And, an int would be implicitly
> convertible to a tuple of one element.
>

I understand your example, but in it, no (int) are involved. So no conversion have to be done (and you get an error).

You see in example above that conversion is done when int is given where (int) is expected or vice versa, not whenever the compiler feels to.