Thread overview | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
June 05, 2015 Emulation macros and pattern matching on D | ||||
---|---|---|---|---|
| ||||
Macros and operation of pattern matching `=>` in Rust I can write something like this: macro_rules!foo { (x => $e:expr) => (println!("mode X: {}", $e)); (y => $e:expr) => (println!("mode Y: {}", $e)); } fn main() { foo!(y => 3); // mode Y: 3 foo!(x => 2); // mode X: 2 } How is it possible to simulate in D? |
June 05, 2015 Re: Emulation macros and pattern matching on D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dennis Ritchie | On 6/5/15 9:01 AM, Dennis Ritchie wrote:
> Macros and operation of pattern matching `=>` in Rust I can write
> something like this:
>
> macro_rules!foo {
> (x => $e:expr) => (println!("mode X: {}", $e));
> (y => $e:expr) => (println!("mode Y: {}", $e));
> }
>
> fn main() {
> foo!(y => 3); // mode Y: 3
> foo!(x => 2); // mode X: 2
> }
>
> How is it possible to simulate in D?
string foo(string mode, string value)
{
return `writefln("mode ` ~ mode ~ `: %s", ` ~ value ~ `);`;
}
void main()
{
mixin(foo("Y", "3"));
mixin(foo("X", "2"));
}
-Steve
|
June 05, 2015 Re: Emulation macros and pattern matching on D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Friday, 5 June 2015 at 13:13:15 UTC, Steven Schveighoffer wrote:
> string foo(string mode, string value)
> {
> return `writefln("mode ` ~ mode ~ `: %s", ` ~ value ~ `);`;
> }
>
> void main()
> {
> mixin(foo("Y", "3"));
> mixin(foo("X", "2"));
> }
Thanks. It looks really simple, but I still do not understand the concept of using mixins in full.
I do not understand why in this line:
return `writefln("mode ` ~ mode ~ `: %s", ` ~ value ~ `);`;
use the following syntax:
~ mode ~ , ~ value ~
For example, why here I can simply write:
void main() {
int b = 5;
mixin(`int a = b;`);
assert(a == 5);
}
Why should not I write like this:
void main() {
int b = 5;
mixin(`"int a = " ` ~ b ~ ` ";"`);
assert(a == 5);
}
|
June 05, 2015 Re: Emulation macros and pattern matching on D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dennis Ritchie | On 6/5/15 10:15 AM, Dennis Ritchie wrote: > On Friday, 5 June 2015 at 13:13:15 UTC, Steven Schveighoffer wrote: >> string foo(string mode, string value) >> { >> return `writefln("mode ` ~ mode ~ `: %s", ` ~ value ~ `);`; >> } >> >> void main() >> { >> mixin(foo("Y", "3")); >> mixin(foo("X", "2")); >> } > > Thanks. It looks really simple, but I still do not understand the > concept of using mixins in full. > > I do not understand why in this line: > return `writefln("mode ` ~ mode ~ `: %s", ` ~ value ~ `);`; > > use the following syntax: > ~ mode ~ , ~ value ~ Because what foo is constructing is a string that makes sense in the *caller*, not inside foo. What those statements do is concat the *value* of mode (i.e. "Y" or "X") and the *value* of value (i.e. "3" or "2") to the string. It's equivalent to rust using the ${e} to do variable substitution. > For example, why here I can simply write: > > void main() { > int b = 5; > mixin(`int a = b;`); > assert(a == 5); > } Because b makes sense in the context of main. > Why should not I write like this: > > void main() { > int b = 5; > mixin(`"int a = " ` ~ b ~ ` ";"`); > assert(a == 5); > } Because it won't compile :) Mixin strings must be constructable at compile time, the value of b depends on runtime. Not to mention that you can't concat strings with ints. -Steve |
June 05, 2015 Re: Emulation macros and pattern matching on D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dennis Ritchie | On Friday, 5 June 2015 at 14:15:09 UTC, Dennis Ritchie wrote: > For example, why here I can simply write: > > void main() { > int b = 5; > mixin(`int a = b;`); > assert(a == 5); > } > This becomes: int b = 5; int a = b; assert(a == 5); > Why should not I write like this: > > void main() { > int b = 5; > mixin(`"int a = " ` ~ b ~ ` ";"`); > assert(a == 5); > } This is a train wreck. If you want to use `b` in a mixin, it needs to be a compile time constant, e.g. an enum. You can't concatenate an int with strings. You messed up the quotes. You might be mistaking backticks for something special, but they're basically just quotes. Fixing it to compile: import std.conv: to; enum int b = 5; mixin("int a = " ~ b.to!string ~ ";"); /* alternatively: mixin(`int a = ` ~ b.to!string ~ `;`); */ assert(a == 5); After the mixin this becomes: enum int b = 5; int a = 5; assert(a == 5); Not that here it's `a = 5;`, whereas above it's `a = b;`. |
June 05, 2015 Re: Emulation macros and pattern matching on D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Friday, 5 June 2015 at 14:23:15 UTC, Steven Schveighoffer wrote:
> On 6/5/15 10:15 AM, Dennis Ritchie wrote:
>>
>> Thanks. It looks really simple, but I still do not understand the
>> concept of using mixins in full.
>>
>> I do not understand why in this line:
>> return `writefln("mode ` ~ mode ~ `: %s", ` ~ value ~ `);`;
>>
>> use the following syntax:
>> ~ mode ~ , ~ value ~
>
> Because what foo is constructing is a string that makes sense in the *caller*, not inside foo. What those statements do is concat the *value* of mode (i.e. "Y" or "X") and the *value* of value (i.e. "3" or "2") to the string.
>
> It's equivalent to rust using the ${e} to do variable substitution.
Thank you. Now everything is clear. Syntax `${e}` in Rust simpler than D ` ~ substitute the value ~ ` :)
|
June 05, 2015 Re: Emulation macros and pattern matching on D | ||||
---|---|---|---|---|
| ||||
Posted in reply to anonymous | On Friday, 5 June 2015 at 14:31:19 UTC, anonymous wrote:
> You messed up the quotes. You might be mistaking backticks for something special, but they're basically just quotes.
Yes, the sample program really made me think that gravis (backticks) - is something special...
|
June 05, 2015 Re: Emulation macros and pattern matching on D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dennis Ritchie | On 6/5/15 11:52 AM, Dennis Ritchie wrote:
> On Friday, 5 June 2015 at 14:31:19 UTC, anonymous wrote:
>> You messed up the quotes. You might be mistaking backticks for
>> something special, but they're basically just quotes.
>
> Yes, the sample program really made me think that gravis (backticks) -
> is something special...
It's just so I didn't have to escape the quotes :D
Otherwise it looks like this:
return "writefln(\"mode " ~ mode ~ ": %s\", " ~ value ~ ");"
I think we can probably do a compile-time substitution processor like rust (and other languages, including php and ruby) which just uses the variable name inside a string with some escape around it. `~var~` is not very succinct, I like $var better.
-Steve
|
June 05, 2015 Re: Emulation macros and pattern matching on D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Friday, 5 June 2015 at 19:08:19 UTC, Steven Schveighoffer wrote: > It's just so I didn't have to escape the quotes :D > > Otherwise it looks like this: > > return "writefln(\"mode " ~ mode ~ ": %s\", " ~ value ~ ");" But such an option is possible to do work? : D return `writefln(q"["mode]" ` ~ mode ~ `q"[: %s"]", ` ~ value ~ `);`; > I think we can probably do a compile-time substitution processor like rust (and other languages, including php and ruby) which just uses the variable name inside a string with some escape around it. `~var~` is not very succinct, I like $var better. It would be very good, because many have long been trying to implement this functionality handmade :) http://www.prowiki.org/wiki4d/wiki.cgi?DanielKeep/shfmt |
June 05, 2015 Re: Emulation macros and pattern matching on D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dennis Ritchie | On 6/5/15 4:03 PM, Dennis Ritchie wrote: > On Friday, 5 June 2015 at 19:08:19 UTC, Steven Schveighoffer wrote: >> It's just so I didn't have to escape the quotes :D >> >> Otherwise it looks like this: >> >> return "writefln(\"mode " ~ mode ~ ": %s\", " ~ value ~ ");" > > But such an option is possible to do work? : D > > return `writefln(q"["mode]" ` ~ mode ~ `q"[: %s"]", ` ~ value ~ `);`; This looks horrid :) > >> I think we can probably do a compile-time substitution processor like >> rust (and other languages, including php and ruby) which just uses the >> variable name inside a string with some escape around it. `~var~` is >> not very succinct, I like $var better. > > It would be very good, because many have long been trying to implement > this functionality handmade :) > > http://www.prowiki.org/wiki4d/wiki.cgi?DanielKeep/shfmt Yes, unfortunately that version is BSD licensed, won't make it into phobos. -Steve |
Copyright © 1999-2021 by the D Language Foundation