www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Proposal: Dedicated-string-mixin templates/functions

reply "Nick Sabalausky" <a a.a> writes:
Point #1: It's often been noted that string mixin syntax is ugly. Which is a 
bad thing in and of itself, but it also tends to discourage use of string 
mixins despite their high degree of usefulness.

Point #2: It seems to me that the vast majority of templates and functions 
are either designed specifically to be used as a string mixin or 
specifically designed to be used as something other than a string mixin. 
Only rarely does a single template or function seem to be particularly 
useful both ways.

Proposal:
So how about taking a cue from Nemerle:

Current:
-----------------------
template foo1 {
    const char[] foo1 = "int a;";
}
char[] foo2() {
    return "int b;";
}
mixin(foo1!());
mixin(foo2());
-----------------------

Proposed:
-----------------------
mixin template foo1 {
    const char[] foo1 = "int a;";
}
mixin char[] foo2() {
    return "int b;";
}
foo1!();
foo2();
-----------------------

One consequence of this worth noting is that the current string-mixin could 
be trivially recreated under the proposed syntax:

-----------------------
mixin char[] mixinString(char[] str) {
    return str;
}
mixinString("int a;");
-----------------------

Maybe someone not as half-asleep as I currently am can point out a 
clean/clever way to retrieve the string value of such a template/function 
without actually mixing it in, to cover the occasional cases where that 
actually would be useful.
Feb 05 2010
next sibling parent reply "Simen kjaeraas" <simen.kjaras gmail.com> writes:
Nick Sabalausky <a a.a> wrote:

 Point #1: It's often been noted that string mixin syntax is ugly. Which  
 is a
 bad thing in and of itself, but it also tends to discourage use of string
 mixins despite their high degree of usefulness.

 Point #2: It seems to me that the vast majority of templates and  
 functions
 are either designed specifically to be used as a string mixin or
 specifically designed to be used as something other than a string mixin.
 Only rarely does a single template or function seem to be particularly
 useful both ways.

 Proposal:
 So how about taking a cue from Nemerle:

 Current:
 -----------------------
 template foo1 {
     const char[] foo1 = "int a;";
 }
 char[] foo2() {
     return "int b;";
 }
 mixin(foo1!());
 mixin(foo2());
 -----------------------

 Proposed:
 -----------------------
 mixin template foo1 {
     const char[] foo1 = "int a;";
 }
 mixin char[] foo2() {
     return "int b;";
 }
 foo1!();
 foo2();
 -----------------------

 One consequence of this worth noting is that the current string-mixin  
 could
 be trivially recreated under the proposed syntax:

 -----------------------
 mixin char[] mixinString(char[] str) {
     return str;
 }
 mixinString("int a;");
 -----------------------

 Maybe someone not as half-asleep as I currently am can point out a
 clean/clever way to retrieve the string value of such a template/function
 without actually mixing it in, to cover the occasional cases where that
 actually would be useful.

Actually, this is already in Bugzilla. ( http://d.puremagic.com/issues/show_bug.cgi?id=3666 ) And it will probably come as no surprise that I, as creator of that request, very much support this. -- Simen
Feb 05 2010
parent reply "Nick Sabalausky" <a a.a> writes:
"Simen kjaeraas" <simen.kjaras gmail.com> wrote in message 
news:op.u7nl710qvxi10f biotronic-pc.home...
 Nick Sabalausky <a a.a> wrote:

 Point #1: It's often been noted that string mixin syntax is ugly. Which 
 is a
 bad thing in and of itself, but it also tends to discourage use of string
 mixins despite their high degree of usefulness.

 Point #2: It seems to me that the vast majority of templates and 
 functions
 are either designed specifically to be used as a string mixin or
 specifically designed to be used as something other than a string mixin.
 Only rarely does a single template or function seem to be particularly
 useful both ways.

 Proposal:
 So how about taking a cue from Nemerle:

 Current:
 -----------------------
 template foo1 {
     const char[] foo1 = "int a;";
 }
 char[] foo2() {
     return "int b;";
 }
 mixin(foo1!());
 mixin(foo2());
 -----------------------

 Proposed:
 -----------------------
 mixin template foo1 {
     const char[] foo1 = "int a;";
 }
 mixin char[] foo2() {
     return "int b;";
 }
 foo1!();
 foo2();
 -----------------------

 One consequence of this worth noting is that the current string-mixin 
 could
 be trivially recreated under the proposed syntax:

 -----------------------
 mixin char[] mixinString(char[] str) {
     return str;
 }
 mixinString("int a;");
 -----------------------

 Maybe someone not as half-asleep as I currently am can point out a
 clean/clever way to retrieve the string value of such a template/function
 without actually mixing it in, to cover the occasional cases where that
 actually would be useful.

Actually, this is already in Bugzilla. ( http://d.puremagic.com/issues/show_bug.cgi?id=3666 ) And it will probably come as no surprise that I, as creator of that request, very much support this.

Wow, that's kinda crazy, the same exact suggestion, and honestly I swear I never saw that ticket before. It doesn't mention functions though. With CTFE becoming more and more powerful, CTFE is getting used more and more to generate the strings to be mixin in. So it should probably apply to functions, too. Do you think that should go in the same ticket or in a separate one? Well, considering two people independantly came up with essentially the same exact idea and the exact same reasoning, hopefully that puts more weight behind it.
Feb 05 2010
parent "Nick Sabalausky" <a a.a> writes:
"Simen kjaeraas" <simen.kjaras gmail.com> wrote in message 
news:op.u7n9c0nnvxi10f biotronic-pc.home...
 Nick Sabalausky <a a.a> wrote:

 Actually, this is already in Bugzilla.
 ( http://d.puremagic.com/issues/show_bug.cgi?id=3666 )
 And it will probably come as no surprise that I, as creator of that
 request, very much support this.

Wow, that's kinda crazy, the same exact suggestion, and honestly I swear I never saw that ticket before. It doesn't mention functions though. With CTFE becoming more and more powerful, CTFE is getting used more and more to generate the strings to be mixin in. So it should probably apply to functions, too. Do you think that should go in the same ticket or in a separate one?

I'd say put it in the same one. It is basically the same request.

Done: http://d.puremagic.com/issues/show_bug.cgi?id=3666
Feb 05 2010
prev sibling next sibling parent reply =?ISO-8859-1?Q?Pelle_M=E5nsson?= <pelle.mansson gmail.com> writes:
On 02/05/2010 12:13 PM, Nick Sabalausky wrote:
 Point #1: It's often been noted that string mixin syntax is ugly. Which is a
 bad thing in and of itself, but it also tends to discourage use of string
 mixins despite their high degree of usefulness.

 Point #2: It seems to me that the vast majority of templates and functions
 are either designed specifically to be used as a string mixin or
 specifically designed to be used as something other than a string mixin.
 Only rarely does a single template or function seem to be particularly
 useful both ways.

 Proposal:
 So how about taking a cue from Nemerle:

 Current:
 -----------------------
 template foo1 {
      const char[] foo1 = "int a;";
 }
 char[] foo2() {
      return "int b;";
 }
 mixin(foo1!());
 mixin(foo2());
 -----------------------

 Proposed:
 -----------------------
 mixin template foo1 {
      const char[] foo1 = "int a;";
 }
 mixin char[] foo2() {
      return "int b;";
 }
 foo1!();
 foo2();
 -----------------------

 One consequence of this worth noting is that the current string-mixin could
 be trivially recreated under the proposed syntax:

 -----------------------
 mixin char[] mixinString(char[] str) {
      return str;
 }
 mixinString("int a;");
 -----------------------

 Maybe someone not as half-asleep as I currently am can point out a
 clean/clever way to retrieve the string value of such a template/function
 without actually mixing it in, to cover the occasional cases where that
 actually would be useful.

I agree, for the mixin template part at least. Then we just need a cleaner way to "return" things from templates, and we'll be all good.
Feb 05 2010
parent bearophile <bearophileHUGS lycos.com> writes:
Pelle Månsson:
 Then we just need a cleaner way to "return" things from templates, and 
 we'll be all good.

I am not sure I like the "mixin" keyword used like that, but I like the idea of a better return syntax for templates (and private attribute for names inside templates). Bye, bearophile
Feb 08 2010
prev sibling next sibling parent "Simen kjaeraas" <simen.kjaras gmail.com> writes:
Nick Sabalausky <a a.a> wrote:

 Actually, this is already in Bugzilla.
 ( http://d.puremagic.com/issues/show_bug.cgi?id=3666 )
 And it will probably come as no surprise that I, as creator of that
 request, very much support this.

Wow, that's kinda crazy, the same exact suggestion, and honestly I swear I never saw that ticket before. It doesn't mention functions though. With CTFE becoming more and more powerful, CTFE is getting used more and more to generate the strings to be mixin in. So it should probably apply to functions, too. Do you think that should go in the same ticket or in a separate one?

I'd say put it in the same one. It is basically the same request.
 Well, considering two people independantly came up with essentially the  
 same
 exact idea and the exact same reasoning, hopefully that puts more weight
 behind it.

Let's hope so. -- Simen
Feb 05 2010
prev sibling next sibling parent reply Trass3r <un known.com> writes:
 Proposed:
 -----------------------
 mixin template foo1 {
     const char[] foo1 = "int a;";
 }
 mixin char[] foo2() {
     return "int b;";
 }
 foo1!();
 foo2();
 -----------------------

Well, it's a little bit indistinctive, hard to tell if it's a normal function call or a mixin without e.g. using a mixin prefix for the function name (which is nothing better than it is now) But an advantage would be that these functions could be omitted in the final executable since they are only used at compile-time.
Feb 05 2010
parent reply Yigal Chripun <yigal100 gmail.com> writes:
On 05/02/2010 23:24, Trass3r wrote:
 Proposed:
 -----------------------
 mixin template foo1 {
 const char[] foo1 = "int a;";
 }
 mixin char[] foo2() {
 return "int b;";
 }
 foo1!();
 foo2();
 -----------------------

Well, it's a little bit indistinctive, hard to tell if it's a normal function call or a mixin without e.g. using a mixin prefix for the function name (which is nothing better than it is now) But an advantage would be that these functions could be omitted in the final executable since they are only used at compile-time.

IMO, this is a bad idea. The most important thing we should get from Nemerle regarding this is the much better compilation model and not just the syntax. The syntax idea itself is iffy at best especially in the D version. To contrast with the Nemerle solution: the "function" foo2 above would be put in a separate file and would be compiled *once* into a lib. Than, at a separate phase, this lib can be loaded by the compiler and used in the client code. Also, In Nemerle, foo2 is a regular function which means, unlike D, it isn't restricted compared to "regular" functions and for example can call stdlib functions like the equivalent of "writef" (no need for special pragma(msg, ..) constructs).
Feb 06 2010
parent "Nick Sabalausky" <a a.a> writes:
"Yigal Chripun" <yigal100 gmail.com> wrote in message 
news:hkjnp8$ms9$1 digitalmars.com...
 On 05/02/2010 23:24, Trass3r wrote:
 Proposed:
 -----------------------
 mixin template foo1 {
 const char[] foo1 = "int a;";
 }
 mixin char[] foo2() {
 return "int b;";
 }
 foo1!();
 foo2();
 -----------------------

Well, it's a little bit indistinctive, hard to tell if it's a normal function call or a mixin without e.g. using a mixin prefix for the function name (which is nothing better than it is now) But an advantage would be that these functions could be omitted in the final executable since they are only used at compile-time.

IMO, this is a bad idea. The most important thing we should get from Nemerle regarding this is the much better compilation model and not just the syntax. The syntax idea itself is iffy at best especially in the D version.

You don't see the current "mixin(foo(fooArgs));" as being iffy syntax?
 To contrast with the Nemerle solution:
 the "function" foo2 above would be put in a separate file and would be 
 compiled *once* into a lib.
 Than, at a separate phase,  this lib can be loaded by the compiler and 
 used in the client code.
 Also, In Nemerle, foo2 is a regular function which means, unlike D, it 
 isn't restricted compared to "regular" functions and for example can call 
 stdlib functions like the equivalent of "writef" (no need for special 
 pragma(msg, ..) constructs).

Absolutely agree with you here. That would be a fairly involved change though, and I suspect D being natively compiled may raise more difficulties and cross-platform issues than it does in Nemerle as Nemerle is VM-only. Would certainly be nice to have that at some point though.
Feb 06 2010
prev sibling next sibling parent reply Chad J <chadjoan __spam.is.bad__gmail.com> writes:
Nick Sabalausky wrote:
 ...

I for one really want something like that. I think I posted a suggestion like this as well: http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=digitalmars.D&artnum=95579 This also came up in another thread and was warmly received, in the context of using the syntax on sql queries: http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=digitalmars.D&artnum=102085 I like your syntax too. Mostly I just want to see this happen somehow. I also realized such syntax allows us to do this: int foo = 42; string bar = "answer"; writefln("The $bar is $foo."); // Prints "The answer is 42." I'd love to be able to do that. I'd settle for writefln#("The $bar is $foo."); as well if we really need to be able to grep mixin usage. The # could be any token of our choosing. This all still leaves the problem of parentheses matching. Parentheses make a terrible nesting element. mixin Foo! (` someDslCodeHere `); // Yes, don't forget the terribly asymmetrical semicolon. versus mixin Foo!() { // Valid D tokens only, and {} must be matched. someDslCodeHere } I think the latter is worth investing in as well.
Feb 05 2010
parent reply "Nick Sabalausky" <a a.a> writes:
"Chad J" <chadjoan __spam.is.bad__gmail.com> wrote in message 
news:hkic29$ug7$1 digitalmars.com...
 Nick Sabalausky wrote:
 ...

I for one really want something like that. I think I posted a suggestion like this as well: http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=digitalmars.D&artnum=95579 This also came up in another thread and was warmly received, in the context of using the syntax on sql queries: http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=digitalmars.D&artnum=102085 I like your syntax too. Mostly I just want to see this happen somehow. I also realized such syntax allows us to do this: int foo = 42; string bar = "answer"; writefln("The $bar is $foo."); // Prints "The answer is 42."

Great point! Of course, that could probably be done today as: mixin(writefln("The $bar is $foo.")); but....eeeewww!
 I'd love to be able to do that.

 I'd settle for writefln#("The $bar is $foo."); as well if we really need
 to be able to grep mixin usage.  The # could be any token of our choosing.

Yea, frankly I'm not certain which way would be better. But personally I'd be very happy either way. However, we should probably take a look around the Nemerle community regarding this issue. AIUI, This proposal is essentially how Nemerle's mixins work (except they call them macros and have AST features), so it could be helpful to see if any of them have found issue with it.
 This all still leaves the problem of parentheses matching.  Parentheses
 make a terrible nesting element.

 mixin Foo!
 (`
 someDslCodeHere
 `);
 // Yes, don't forget the terribly asymmetrical semicolon.

 versus

 mixin Foo!()
 {
 // Valid D tokens only, and {} must be matched.
 someDslCodeHere
 }

 I think the latter is worth investing in as well.

D2 has q{}: mixin Foo!( q{ someDslCodeHere }); But yea, that's is still a good point. Although I think it might be better considered part of the more general problem of passing code literals (even though it's as delegates in one case and as strings in the other). For instance, even without any mixins involved, we still have this kind of mess: void repeat(int num, IForgetTheSyntaxOffhandButLetsJustSayADgThatTakesVoidAndReturnsVoid dg) { for(int i; 0..num) dg(); } // Eeew: repeat(3, { // Stuff here });
Feb 05 2010
parent Chad J <chadjoan __spam.is.bad__gmail.com> writes:
Nick Sabalausky wrote:
 ...
 
 But yea, that's is still a good point. Although I think it might be better 
 considered part of the more general problem of passing code literals (even 
 though it's as delegates in one case and as strings in the other). For 
 instance, even without any mixins involved, we still have this kind of mess:
 
 void repeat(int num, 
 IForgetTheSyntaxOffhandButLetsJustSayADgThatTakesVoidAndReturnsVoid dg)
 {
     for(int i; 0..num)
         dg();
 }
 
 // Eeew:
 repeat(3,
 {
     // Stuff here
 });
 
 

Yep. My thoughts exactly.
Feb 06 2010
prev sibling parent reply Joel Anderson <ask me.com> writes:
On 2/5/2010 3:13 AM, Nick Sabalausky wrote:
 Point #1: It's often been noted that string mixin syntax is ugly. Which is a
 bad thing in and of itself, but it also tends to discourage use of string
 mixins despite their high degree of usefulness.

 Point #2: It seems to me that the vast majority of templates and functions
 are either designed specifically to be used as a string mixin or
 specifically designed to be used as something other than a string mixin.
 Only rarely does a single template or function seem to be particularly
 useful both ways.

 Proposal:
 So how about taking a cue from Nemerle:

 Current:
 -----------------------
 template foo1 {
      const char[] foo1 = "int a;";
 }
 char[] foo2() {
      return "int b;";
 }
 mixin(foo1!());
 mixin(foo2());
 -----------------------

 Proposed:
 -----------------------
 mixin template foo1 {
      const char[] foo1 = "int a;";
 }
 mixin char[] foo2() {
      return "int b;";
 }
 foo1!();
 foo2();
 -----------------------

 One consequence of this worth noting is that the current string-mixin could
 be trivially recreated under the proposed syntax:

 -----------------------
 mixin char[] mixinString(char[] str) {
      return str;
 }
 mixinString("int a;");
 -----------------------

 Maybe someone not as half-asleep as I currently am can point out a
 clean/clever way to retrieve the string value of such a template/function
 without actually mixing it in, to cover the occasional cases where that
 actually would be useful.

I like having nicer mixing. My proposal was to allow templates to take a string. That would make the mixin both visible but still make it look neat. void mixinString(string T)() { mixin(func(T)); } On the call site... mixinString!("int a;"); The extra ! indicates that the string must be compile time constant because its going into a template.
Feb 11 2010
parent "Nick Sabalausky" <a a.a> writes:
"Joel Anderson" <ask me.com> wrote in message 
news:hl1cdn$2fkn$1 digitalmars.com...
 I like having nicer mixing.  My proposal was to allow templates to take a 
 string.  That would make the mixin both visible but still make it look 
 neat.

 void mixinString(string T)()
 {
 mixin(func(T));
 }

 On the call site...

 mixinString!("int a;");

 The extra ! indicates that the string must be compile time constant 
 because its going into a template.

While that wouldn't be my preferred solution, I could certainly live with that and be very happy.
Feb 11 2010