www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Emulation macros and pattern matching on D

reply "Dennis Ritchie" <dennis.ritchie mail.ru> writes:
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?
Jun 05 2015
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
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
Jun 05 2015
parent reply "Dennis Ritchie" <dennis.ritchie mail.ru> writes:
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); }
Jun 05 2015
next sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
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
Jun 05 2015
parent "Dennis Ritchie" <dennis.ritchie mail.ru> writes:
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 ~ ` :)
Jun 05 2015
prev sibling parent reply "anonymous" <anonymous example.com> writes:
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;`.
Jun 05 2015
parent reply "Dennis Ritchie" <dennis.ritchie mail.ru> writes:
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...
Jun 05 2015
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
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
Jun 05 2015
parent reply "Dennis Ritchie" <dennis.ritchie mail.ru> writes:
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
Jun 05 2015
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
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
Jun 05 2015
parent "Dennis Ritchie" <dennis.ritchie mail.ru> writes:
On Friday, 5 June 2015 at 20:14:51 UTC, Steven Schveighoffer 
wrote:
 On 6/5/15 4:03 PM, Dennis Ritchie wrote:
 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.
I think that the developers of D will be able to write better if they take it! :D
Jun 05 2015