Thread overview | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
May 11, 2007 Tuple mixins | ||||
---|---|---|---|---|
| ||||
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 Re: Tuple mixins | ||||
---|---|---|---|---|
| ||||
Posted in reply to Max Samukha | 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 Re: Tuple mixins | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Keep | 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 Re: Tuple mixins | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Keep | 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 Re: Tuple mixins | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Keep | 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 Re: Tuple mixins | ||||
---|---|---|---|---|
| ||||
Posted in reply to Max Samukha | 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 Re: Tuple mixins | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Keep | 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 Re: Tuple mixins | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Keep | 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 Re: Tuple mixins | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Keep | 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 Re: Tuple mixins | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bill Baxter | 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
|
Copyright © 1999-2021 by the D Language Foundation