digitalmars.D.learn - Tuple mixins
- Max Samukha (10/10) May 11 2007 The mixin form compiles and works in some cases (in others it fails).
- Daniel Keep (28/44) May 11 2007 The problem here is that mixins are not direct string mixins. That is,
- Max Samukha (17/52) May 11 2007 Thanks, Daniel. I know about the expression and statement mixins. What
- Max Samukha (3/4) May 11 2007 BTW, this one works. Thanks
- Max Samukha (15/50) May 11 2007 Using your rule of thumb I discovered that expressions separated by
- Daniel Keep (31/48) May 11 2007 I think you're confused as to what's happening. From the D spec:
- Max Samukha (6/44) May 11 2007 I missed that one, thanks. Is there any use cases of the comma
- Bill Baxter (13/20) May 11 2007 Amen to that brutha.
- Johan Granberg (2/26) May 11 2007 We can hope that this is something Walter considers for D2.0
- Jarrett Billingsley (4/8) May 11 2007 That's how it works in MiniD ;) I really hate the comma operator. It's...
- Jari-Matti =?ISO-8859-1?Q?M=E4kel=E4?= (3/7) May 11 2007 votes++
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: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")); }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 testedThen I'd do it like this: int[] arr = mixin("[1,2,3]"); //ok, [1,2,3] is a complete expressionI 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 testedBTW, 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: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); }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
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:I missed that one, thanks. Is there any use cases of the comma separated expressions?[...] 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] :PI 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 :PAbsolutely 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 :PAmen 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
Bill Baxter wrote:Daniel Keep wrote:We can hope that this is something Walter considers for D2.0This 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 :PAmen 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
"Bill Baxter" <dnewsgroup billbaxter.com> wrote in message news:f21rdg$2spg$1 digitalmars.com...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.That's how it works in MiniD ;) I really hate the comma operator. It's just a waste.
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 :Pvotes++ At least some kind of built-in tuple literals are needed.
May 11 2007