www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Special Code String for mixins

reply Inquie <Inquie data1.com> writes:
I hate building code strings for string mixins as it's very ugly 
and seems like a complete hack.

How bout, instead, we have a special code string similar to a 
multiline string that allows us to represent valid D code. The 
compiler can then verify the string after compilation to make 
sure it is valid D code(since it ultimately is a compile time 
constant).

e.g.,

string s = "smile";
enum code1 =  #
void happyCode = "Makes me   s  ";
# 

enum code2 = code1 ~  #
int ImThisHappy =   s.length  ;
# 

mixin(code);

or

mixin(code.stringof); // possible to convert code string to a 
string and vice versa.


or whatever syntax one thinks is better. The point is that the 
code string is specified different and then is no longer 
ambiguous as a normal string. Compilers and IDE's can make more 
informed decisions.

There might be a much better way, but something should be done to 
clean up this area of D. It is a mess to have to use string 
building to create code. (it's amazingly powerful, but still a 
mess)
Mar 15 2017
next sibling parent Inquie <Inquie data1.com> writes:
On Wednesday, 15 March 2017 at 13:50:28 UTC, Inquie wrote:
 I hate building code strings for string mixins as it's very 
 ugly and seems like a complete hack.

 How bout, instead, we have a special code string similar to a 
 multiline string that allows us to represent valid D code. The 
 compiler can then verify the string after compilation to make 
 sure it is valid D code(since it ultimately is a compile time 
 constant).

 e.g.,

 string s = "smile";
 enum code1 =  #
 void happyCode = "Makes me   s  ";
 # 

 enum code2 = code1 ~  #
 int ImThisHappy =   s.length  ;
 # 

 mixin(code);

 or

 mixin(code.stringof); // possible to convert code string to a 
 string and vice versa.


 or whatever syntax one thinks is better. The point is that the 
 code string is specified different and then is no longer 
 ambiguous as a normal string. Compilers and IDE's can make more 
 informed decisions.

 There might be a much better way, but something should be done 
 to clean up this area of D. It is a mess to have to use string 
 building to create code. (it's amazingly powerful, but still a 
 mess)
Alternatively, maybe one could specify code in a template like mechanism: template Code(string s) { void happyCode = "Makes me "~s; int ImThisHappy = s.length; } then turn the template in to a code string: Code("smile").stringof = `\tvoid happyCode = "Makes me "~s;\n\tint ImThisHappy = s.length;\n`; and so mixin(Code("smile").stringof); would do the same as the first example. The only problem I see is passing variables might become a mess... but still better than original.
Mar 15 2017
prev sibling next sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Wednesday, 15 March 2017 at 13:50:28 UTC, Inquie wrote:
 I hate building code strings for string mixins as it's very 
 ugly and seems like a complete hack.
Me too, that's why I avoid doing it. Check out my tips of the week here: http://arsdnet.net/this-week-in-d/sep-20.html and here: http://arsdnet.net/this-week-in-d/2016-feb-21.html for some ways I minimize them.
 How bout, instead, we have a special code string similar to a 
 multiline string that allows us to represent valid D code. The 
 compiler can then verify the string after compilation to make 
 sure it is valid D code(since it ultimately is a compile time 
 constant).
Are you familiar with D's `q{ ... }` literals? They are lexed though not parsed. enum code1 = q{ void happyCode = "Makes me s "; }; then you'd have to do the `.replace(" s ", whatever)` yourself on it though. They also do not allow unbalanced { }. It is typed as string btw, no special type, just like if you used regular quotes, just looks nicer at the definition.
Mar 15 2017
parent Inquie <Inquie data1.com> writes:
On Wednesday, 15 March 2017 at 14:12:57 UTC, Adam D. Ruppe wrote:
 On Wednesday, 15 March 2017 at 13:50:28 UTC, Inquie wrote:
 I hate building code strings for string mixins as it's very 
 ugly and seems like a complete hack.
Me too, that's why I avoid doing it. Check out my tips of the week here: http://arsdnet.net/this-week-in-d/sep-20.html and here: http://arsdnet.net/this-week-in-d/2016-feb-21.html for some ways I minimize them.
 How bout, instead, we have a special code string similar to a 
 multiline string that allows us to represent valid D code. The 
 compiler can then verify the string after compilation to make 
 sure it is valid D code(since it ultimately is a compile time 
 constant).
Are you familiar with D's `q{ ... }` literals? They are lexed though not parsed. enum code1 = q{ void happyCode = "Makes me s "; }; then you'd have to do the `.replace(" s ", whatever)` yourself on it though. They also do not allow unbalanced { }. It is typed as string btw, no special type, just like if you used regular quotes, just looks nicer at the definition.
Visual D doesn't seem to do much. Maybe it is lexed but most of the code is a solid purple. Better than a normal string. I was hoping to get something parsed though to find based errors a CT in a meaningful way(line numbers, etc).
Mar 15 2017
prev sibling next sibling parent Shachar Shemesh <shachar weka.io> writes:
On 15/03/17 15:50, Inquie wrote:
 I hate building code strings for string mixins as it's very ugly and
 seems like a complete hack.
What I usually do is use the q{} format. Vim does syntax highlighting on it: string code = q{ immutable int a = %s; }.format(something); ... mixin(code);
Mar 15 2017
prev sibling next sibling parent reply "Nick Sabalausky (Abscissa)" <SeeWebsiteToContactMe semitwist.com> writes:
On 03/15/2017 09:50 AM, Inquie wrote:
 e.g.,

 string s = "smile";
 enum code1 =  #
 void happyCode = "Makes me   s  ";
 # 

 enum code2 = code1 ~  #
 int ImThisHappy =   s.length  ;
 # 

 mixin(code);
import scriptlike; // https://github.com/Abscissa/scriptlike string s = "smile"; // http://semitwist.com/scriptlike/scriptlike/core/interp.html enum code1 = mixin(interp!q{ void happyCode = "Makes me ${s}"; }); enum code2 = code1 ~ mixin(interp!q{ int ImThisHappy = ${s.length}; }); mixin(code2); Wish I could get rid of the need for "mixin(...)" in interp though.
Mar 15 2017
parent reply Stefan Koch <uplink.coder googlemail.com> writes:
On Wednesday, 15 March 2017 at 15:39:38 UTC, Nick Sabalausky 
(Abscissa) wrote:
 On 03/15/2017 09:50 AM, Inquie wrote:
 e.g.,

 string s = "smile";
 enum code1 =  #
 void happyCode = "Makes me   s  ";
 # 

 enum code2 = code1 ~  #
 int ImThisHappy =   s.length  ;
 # 

 mixin(code);
import scriptlike; // https://github.com/Abscissa/scriptlike string s = "smile"; // http://semitwist.com/scriptlike/scriptlike/core/interp.html enum code1 = mixin(interp!q{ void happyCode = "Makes me ${s}"; }); enum code2 = code1 ~ mixin(interp!q{ int ImThisHappy = ${s.length}; }); mixin(code2); Wish I could get rid of the need for "mixin(...)" in interp though.
But you can. in interp you can evoke the function you generate however for that you need to pass s to it.
Mar 15 2017
parent "Nick Sabalausky (Abscissa)" <SeeWebsiteToContactMe semitwist.com> writes:
On 03/15/2017 11:50 AM, Stefan Koch wrote:
 Wish I could get rid of the need for "mixin(...)" in interp though.
But you can. in interp you can evoke the function you generate however for that you need to pass s to it.
Thus reinventing writef and defeating the whole point of interpolated strings.
Mar 15 2017
prev sibling next sibling parent "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Wed, Mar 15, 2017 at 01:50:28PM +0000, Inquie via Digitalmars-d wrote:
 I hate building code strings for string mixins as it's very ugly and seems
 like a complete hack.
 
 How bout, instead, we have a special code string similar to a multiline
 string that allows us to represent valid D code. The compiler can then
 verify the string after compilation to make sure it is valid D code(since it
 ultimately is a compile time constant).
Have you looked up token string literals? enum myCode = q{ // This is actually a string that looks like code void func() { } // Of course it allows token sequences that aren't valid // D, but that's not important because mixin() will // complain if it's malformed. float void is double null {[ 0* }] }; T -- Not all rumours are as misleading as this one.
Mar 15 2017
prev sibling next sibling parent =?iso-8859-1?Q?Robert_M._M=FCnch?= <robert.muench saphirion.com> writes:
On 2017-03-15 13:50:28 +0000, Inquie said:

 I hate building code strings for string mixins as it's very ugly and 
 seems like a complete hack.
 ...
Even a bit old, I would like to pick-up this topic, as I totally agree with the statement. Thinking this a bit further, it would be very nice to have a way to specify DSL inside D code, without having to fallback to strings. Some (not fully thought through) ideas: 1. Why not use something like: mixin {...} and have normal D code between the braces? This D code is implicitly converted to a string and used accordingly. Variables etc. can all be used and have scope rules like D with the mixing {...} scope being the top-level scope for this code-block. Inside the mixin scope an AST could be build, which is than used as return value. 2. For a DSL two things are necessary: A parser for the DSL and an interface to access D identifiers. Something like: dsl (myparser, d_id1, d_id2, ..., d_idN) {... my-dsl-code ...} Inside the DSL parser I get access to the listed D identifiers while I'm mostly free to design the syntax of my DSL code as I like. Being able to switch to a fitting syntax for things like database access, declarative GUIs etc. can make the codebase so much more maintainable than having to stick to the main language syntax. There are very few languages that care about proper and simple DSL handling, IMO a much underestimated design principle. -- Robert M. Münch http://www.saphirion.com smarter | better | faster
Mar 14
prev sibling parent reply Jonathan Marler <johnnymarler gmail.com> writes:
On Wednesday, 15 March 2017 at 13:50:28 UTC, Inquie wrote:
 I hate building code strings for string mixins as it's very 
 ugly and seems like a complete hack.

 How bout, instead, we have a special code string similar to a 
 multiline string that allows us to represent valid D code. The 
 compiler can then verify the string after compilation to make 
 sure it is valid D code(since it ultimately is a compile time 
 constant).

 e.g.,

 string s = "smile";
 enum code1 =  #
 void happyCode = "Makes me   s  ";
 # 

 enum code2 = code1 ~  #
 int ImThisHappy =   s.length  ;
 # 

 mixin(code);

 or

 mixin(code.stringof); // possible to convert code string to a 
 string and vice versa.


 or whatever syntax one thinks is better. The point is that the 
 code string is specified different and then is no longer 
 ambiguous as a normal string. Compilers and IDE's can make more 
 informed decisions.

 There might be a much better way, but something should be done 
 to clean up this area of D. It is a mess to have to use string 
 building to create code. (it's amazingly powerful, but still a 
 mess)
I've got a PR for dmd (https://github.com/dlang/dmd/pull/7988) that implements "interpolated strings" which makes generating code with strings MUCH nicer, i.e. string generateFunction(string attributes, string returnType, string name, string args, string body) { import std.conv : text; return text(iq{ // This is an interpolated string! $(attributes) $(returnType) $(name)($(args)) { $(body) } }); } // Let's use it: mixin(generateFunction("pragma(inline)", "int", "add", "int a, int b", "return a + b;")); assert(100 == add(25, 75));
Mar 14
next sibling parent Stefan Koch <uplink.coder googlemail.com> writes:
On Wednesday, 14 March 2018 at 15:50:13 UTC, Jonathan Marler 
wrote:
 On Wednesday, 15 March 2017 at 13:50:28 UTC, Inquie wrote:
 [...]
I've got a PR for dmd (https://github.com/dlang/dmd/pull/7988) that implements "interpolated strings" which makes generating code with strings MUCH nicer, i.e. string generateFunction(string attributes, string returnType, string name, string args, string body) { import std.conv : text; return text(iq{ // This is an interpolated string! $(attributes) $(returnType) $(name)($(args)) { $(body) } }); } // Let's use it: mixin(generateFunction("pragma(inline)", "int", "add", "int a, int b", "return a + b;")); assert(100 == add(25, 75));
If you do that give the closing brace a suffix
Mar 14
prev sibling parent Sebastiaan Koppe <mail skoppe.eu> writes:
On Wednesday, 14 March 2018 at 15:50:13 UTC, Jonathan Marler 
wrote:
 I've got a PR for dmd (https://github.com/dlang/dmd/pull/7988) 
 that implements "interpolated strings" which makes generating 
 code with strings MUCH nicer, i.e.
Really nice. :thumbs-up:
Mar 14