Jump to page: 1 2
Thread overview
Tuple mixins
May 11, 2007
Max Samukha
May 11, 2007
Daniel Keep
May 11, 2007
Max Samukha
May 11, 2007
Max Samukha
May 11, 2007
Max Samukha
May 11, 2007
Daniel Keep
May 11, 2007
Max Samukha
May 11, 2007
Bill Baxter
May 11, 2007
Johan Granberg
May 11, 2007
The mixin form compiles and works in some cases (in others it fails). Is it legal at all? Is it mentioned anywhere in the specs?

The following declares an int array and initializes it to the last element encoded in the mixin string ([3]). Should the mixin fail with an appropriate error or initialize the array to [1, 2, 3]?

void main()
{
  int[] arrr = [mixin("1, 2, 3")];
  writefln(arrr);
}
May 11, 2007
Max Samukha wrote:
> The mixin form compiles and works in some cases (in others it fails). Is it legal at all? Is it mentioned anywhere in the specs?
> 
> The following declares an int array and initializes it to the last element encoded in the mixin string ([3]). Should the mixin fail with an appropriate error or initialize the array to [1, 2, 3]?
> 
> void main()
> {
>   int[] arrr = [mixin("1, 2, 3")];
>   writefln(arrr);
> }

The problem here is that mixins are not direct string mixins.  That is, they don't simply spit their argument into the AST like a C preprocessor macro would.

There are two kinds of string mixins: statement and expression.  The one above is an expression mixin.  Let's look at it a different way:

int[] arr = [( mixin("1,2,3") )];

If you look at it like that, you see that "1,2,3" is not a tuple at all; it's a comma-delimited list of expressions which itself evaluates to the *last* expression.

If you wanted to actually mix in a tuple, you'd have to be a bit more creative:

int[] arr = [mixin("Tuple!(1,2,3)")]; // Note: not tested

I ran across this when I was trying to generate functions with a particular name.  Turns out this *doesn't* work:

> void mixin(identName)()
> {
>     // Do stuff
> }

Basically, simple rule of thumb is: when mixing in an expression, mentally put a pair of parentheses around it; it helps you work out exactly what it's going to do.

	-- Daniel

-- 
int getRandomNumber()
{
    return 4; // chosen by fair dice roll.
              // guaranteed to be random.
}

http://xkcd.com/

v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP  http://hackerkey.com/
May 11, 2007
On Fri, 11 May 2007 18:43:06 +1000, Daniel Keep <daniel.keep.lists@gmail.com> wrote:

>
>Max Samukha wrote:
>> The mixin form compiles and works in some cases (in others it fails). Is it legal at all? Is it mentioned anywhere in the specs?
>> 
>> The following declares an int array and initializes it to the last element encoded in the mixin string ([3]). Should the mixin fail with an appropriate error or initialize the array to [1, 2, 3]?
>> 
>> void main()
>> {
>>   int[] arrr = [mixin("1, 2, 3")];
>>   writefln(arrr);
>> }
>
>The problem here is that mixins are not direct string mixins.  That is, they don't simply spit their argument into the AST like a C preprocessor macro would.
>
>There are two kinds of string mixins: statement and expression.  The one above is an expression mixin.  Let's look at it a different way:
>
>int[] arr = [( mixin("1,2,3") )];
>
>If you look at it like that, you see that "1,2,3" is not a tuple at all; it's a comma-delimited list of expressions which itself evaluates to the *last* expression.

Thanks, Daniel. I know about the expression and statement mixins. What I wanted to ask is why my example compiles? Is it a compiler bug or another type of mixin partially (or incorrectly) implemented?

Note, that the mixin compiles in other similar contexts:

void foo(int a/*, int b, int c */)
{
	writefln(a); // outputs 3
}

void main()
{
  foo(mixin("1, 2, 3"));
}



>
>If you wanted to actually mix in a tuple, you'd have to be a bit more creative:
>
>int[] arr = [mixin("Tuple!(1,2,3)")]; // Note: not tested

Then I'd do it like this:
int[] arr = mixin("[1,2,3]"); //ok, [1,2,3] is a complete expression

>
>I ran across this when I was trying to generate functions with a particular name.  Turns out this *doesn't* work:
>
>> void mixin(identName)()
>> {
>>     // Do stuff
>> }
>
>Basically, simple rule of thumb is: when mixing in an expression, mentally put a pair of parentheses around it; it helps you work out exactly what it's going to do.
>
>	-- Daniel
May 11, 2007
On Fri, 11 May 2007 18:43:06 +1000, Daniel Keep <daniel.keep.lists@gmail.com> wrote:

>int[] arr = [mixin("Tuple!(1,2,3)")]; // Note: not tested

BTW, this one works. Thanks
May 11, 2007
On Fri, 11 May 2007 18:43:06 +1000, Daniel Keep <daniel.keep.lists@gmail.com> wrote:

>
>Max Samukha wrote:
>> The mixin form compiles and works in some cases (in others it fails). Is it legal at all? Is it mentioned anywhere in the specs?
>> 
>> The following declares an int array and initializes it to the last element encoded in the mixin string ([3]). Should the mixin fail with an appropriate error or initialize the array to [1, 2, 3]?
>> 
>> void main()
>> {
>>   int[] arrr = [mixin("1, 2, 3")];
>>   writefln(arrr);
>> }
>
>The problem here is that mixins are not direct string mixins.  That is, they don't simply spit their argument into the AST like a C preprocessor macro would.
>
>There are two kinds of string mixins: statement and expression.  The one above is an expression mixin.  Let's look at it a different way:
>
>int[] arr = [( mixin("1,2,3") )];
>
>If you look at it like that, you see that "1,2,3" is not a tuple at all; it's a comma-delimited list of expressions which itself evaluates to the *last* expression.
>
>If you wanted to actually mix in a tuple, you'd have to be a bit more creative:
>
>int[] arr = [mixin("Tuple!(1,2,3)")]; // Note: not tested
>
>I ran across this when I was trying to generate functions with a particular name.  Turns out this *doesn't* work:
>
>> void mixin(identName)()
>> {
>>     // Do stuff
>> }
>
>Basically, simple rule of thumb is: when mixing in an expression, mentally put a pair of parentheses around it; it helps you work out exactly what it's going to do.
>
>	-- Daniel

Using your rule of thumb I discovered that expressions separated by comma, in parentheses, can be used in contexts where tuples are allowed. Seems like D is going to have built-in expression tuple literals. Cool. Has it been discussed anywhere?

void foo(int a /*, int b, int c*/)
{
}

void main()
{
 auto tuple = (1, 2, 3);
 auto arr = [tuple]; // arr = [(1, 2, 3)] compiles too
 foo(tuple);
}
May 11, 2007

Max Samukha wrote:
> [...]
> 
> Using your rule of thumb I discovered that expressions separated by comma, in parentheses, can be used in contexts where tuples are allowed. Seems like D is going to have built-in expression tuple literals. Cool. Has it been discussed anywhere?
> 
> void foo(int a /*, int b, int c*/)
> {
> }
> 
> void main()
> {
>  auto tuple = (1, 2, 3);
>  auto arr = [tuple]; // arr = [(1, 2, 3)] compiles too
>  foo(tuple);
> }

I think you're confused as to what's happening.  From the D spec:

"""
Expressions

Expression:
	AssignExpression
	AssignExpression , Expression

The left operand of the , is evaluated, then the right operand is
evaluated. The type of the expression is the type of the right operand,
and the result is the result of the right operand.
"""

What's happening is that (1, 2, 3) evaluates to *3*.  If you did this:
(writefln("foo"), writefln("bar"), 42), it would print out "foo" and
"bar" and evaluate to 42.

They're not tuples, otherwise your foo(tuple) call would have failed, since you would have had three values for a function that only takes one.  If you print out "arr", I think you'll find it's equal to [3] :P

This is one thing I've never especially liked about C, C++ and now D.  I personally thing that the comma should be used to construct tuples like it is in Python, which is a hell of a lot more useful.  Plus, this behaviour is really friggin' weird :P

	-- Daniel

-- 
int getRandomNumber()
{
    return 4; // chosen by fair dice roll.
              // guaranteed to be random.
}

http://xkcd.com/

v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP  http://hackerkey.com/
May 11, 2007
On Fri, 11 May 2007 21:52:17 +1000, Daniel Keep <daniel.keep.lists@gmail.com> wrote:

>
>
>Max Samukha wrote:
>> [...]
>> 
>> Using your rule of thumb I discovered that expressions separated by comma, in parentheses, can be used in contexts where tuples are allowed. Seems like D is going to have built-in expression tuple literals. Cool. Has it been discussed anywhere?
>> 
>> void foo(int a /*, int b, int c*/)
>> {
>> }
>> 
>> void main()
>> {
>>  auto tuple = (1, 2, 3);
>>  auto arr = [tuple]; // arr = [(1, 2, 3)] compiles too
>>  foo(tuple);
>> }
>
>I think you're confused as to what's happening.  From the D spec:
>
>"""
>Expressions
>
>Expression:
>	AssignExpression
>	AssignExpression , Expression
>
>The left operand of the , is evaluated, then the right operand is
>evaluated. The type of the expression is the type of the right operand,
>and the result is the result of the right operand.
>"""
I missed that one, thanks. Is there any use cases of the comma separated expressions?

>What's happening is that (1, 2, 3) evaluates to *3*.  If you did this:
>(writefln("foo"), writefln("bar"), 42), it would print out "foo" and
>"bar" and evaluate to 42.
>
>They're not tuples, otherwise your foo(tuple) call would have failed, since you would have had three values for a function that only takes one.  If you print out "arr", I think you'll find it's equal to [3] :P
>
I printed it out but thought it was a compiler bug.

>This is one thing I've never especially liked about C, C++ and now D.  I personally thing that the comma should be used to construct tuples like it is in Python, which is a hell of a lot more useful.  Plus, this behaviour is really friggin' weird :P

Absolutely agree.
May 11, 2007
Daniel Keep wrote:
> 
> 
> This is one thing I've never especially liked about C, C++ and now D.  I
> personally thing that the comma should be used to construct tuples like
> it is in Python, which is a hell of a lot more useful.  Plus, this
> behaviour is really friggin' weird :P
> 

Amen to that brutha.
It's main use in C and C++ is hackish macro tricks.  In C++ it also finds use as an overloadable operator you can use to confuse the heck out of people.

Are there any good uses for it?  Maybe the lists of initializers in for loops are using that rule?    like  -- for(x=3,y=10; x<y; x++) { ... }.
Seems like you could make that part of the for loop grammar instead of a really useless works anywhere rule.  Besides if it worked as a tuple maker, and multiple assigment worked then you could do
   for (x,y=3,10; x<y; x++) { . . . }

Definitely seems like a waste.

--bb
May 11, 2007
Daniel Keep wrote:

> This is one thing I've never especially liked about C, C++ and now D.  I personally thing that the comma should be used to construct tuples like it is in Python, which is a hell of a lot more useful.  Plus, this behaviour is really friggin' weird :P

votes++

At least some kind of built-in tuple literals are needed.
May 11, 2007
Bill Baxter wrote:

> Daniel Keep wrote:
>> 
>> 
>> This is one thing I've never especially liked about C, C++ and now D.  I personally thing that the comma should be used to construct tuples like it is in Python, which is a hell of a lot more useful.  Plus, this behaviour is really friggin' weird :P
>> 
> 
> Amen to that brutha.
> It's main use in C and C++ is hackish macro tricks.  In C++ it also
> finds use as an overloadable operator you can use to confuse the heck
> out of people.
> 
> Are there any good uses for it?  Maybe the lists of initializers in for
> loops are using that rule?    like  -- for(x=3,y=10; x<y; x++) { ... }.
> Seems like you could make that part of the for loop grammar instead of a
> really useless works anywhere rule.  Besides if it worked as a tuple
> maker, and multiple assigment worked then you could do
>     for (x,y=3,10; x<y; x++) { . . . }
> 
> Definitely seems like a waste.
> 
> --bb

We can hope that this is something Walter considers for D2.0
« First   ‹ Prev
1 2