<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Style-Type" content="text/css">
<title></title>
<meta name="Generator" content="Cocoa HTML Writer">
<meta name="CocoaVersion" content="1404.34">
<style type="text/css">
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; line-height: 15.0px; font: 12.0px Helvetica}
p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; line-height: 15.0px; font: 12.0px Helvetica; min-height: 14.0px}
p.p3 {margin: 0.0px 0.0px 0.0px 12.0px; font: 12.0px Helvetica; color: #011892}
p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; line-height: 14.0px; font: 12.0px Helvetica; min-height: 14.0px}
p.p5 {margin: 0.0px 0.0px 0.0px 0.0px; line-height: 14.0px; font: 12.0px Helvetica}
p.p6 {margin: 0.0px 0.0px 0.0px 0.0px; line-height: 14.0px; font: 12.0px Helvetica; color: #011892; min-height: 14.0px}
p.p7 {margin: 0.0px 0.0px 0.0px 24.0px; font: 12.0px Helvetica; color: #008e00}
p.p8 {margin: 0.0px 0.0px 0.0px 12.0px; font: 12.0px Helvetica; color: #011892; min-height: 14.0px}
p.p9 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px}
p.p10 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; color: #929292}
</style>
</head>
<body>
<p class="p1">On 2016-01-31 14:35:13 +0000, cym13 said:</p>
<p class="p2"><br></p>
<p class="p3">I see things differently. First of all I don't see everyone trying</p>
<p class="p3">to do meta-programming with the same language. C++ for example has</p>
<p class="p3">a quite specific syntax between its arcane templates and the</p>
<p class="p3">preprocessor.</p>
<p class="p4"><br></p>
<p class="p5">Well, ok, maybe a "using the same concepts as the underlaying language" might hit it better.</p>
<p class="p6"><br></p>
<p class="p3">I see having the same language as a *huge* advantage. If a function</p>
<p class="p3">doesn't have side effects then it can be used at runtime or at</p>
<p class="p3">compile-time and integrated with your logic easily.</p>
<p class="p4"><br></p>
<p class="p5">The thing I mean is not that you shouldn't be able to reference or use things from the "target language" but how to write down what you want to do.<span class="Apple-converted-space"> </span></p>
<p class="p4"><br></p>
<p class="p5">Code generation by building strings using the D operators for example is something I think is not very elegant. If I could use a list and build it up without having to care about the code / data difference, that would simplify things a lot.</p>
<p class="p4"><br></p>
<p class="p5">Imagine we could use Lua during compile time and have access to the AST etc.</p>
<p class="p4"><br></p>
<p class="p6"><br></p>
<p class="p3">D's metaprogramming success is IMHO directly linked to it not having</p>
<p class="p3">a separate language for it, because it lowers the cost of learning</p>
<p class="p3">and using metaprogramming.</p>
<p class="p4"><br></p>
<p class="p5">But limits you to a subset that doesn't feel very natural for doing a lot of common things in code-generation.</p>
<p class="p4"><br></p>
<p class="p3">It's saying "metaprogramming isn't different from any other kind of programming, you can use the same tools".</p>
<p class="p4"><br></p>
<p class="p5">Yes, and I don't think this statement holds. It's very different because the goal is totally different. I need a tool that allows me to manipulate my underlying code during compilation. The main aspect is: Manipulate D code.</p>
<p class="p6"><br></p>
<p class="p7">Why not have a CTL (compile-time-language) that has access to some compiler internals, that follows a more functional concept? We are evaluating sequences of things to generate code, include / exclude code etc.</p>
<p class="p8"><br></p>
<p class="p3">Having access to some compiler internals is already what is done, or I don't understand exactly what you mean by that.</p>
<p class="p4"><br></p>
<p class="p5">Sure, but the question is how do to deal with it. IMO it's not very straight forward at the moment.</p>
<p class="p4"><br></p>
<p class="p3">I think you should put some sort of example of how you'd want it,</p>
<p class="p3">because right now I don't understand. D has some nice functional</p>
<p class="p3">tools and they already show their strength at compile-time.</p>
<p class="p4"><br></p>
<p class="p5">Ok, here is a simple example: I want to ensure that specific switch statements handle all cases for a given enum, list, etc. This is a common pattern and often a source of problems because you change a collection but miss to update all side-effecting places.</p>
<p class="p4"><br></p>
<p class="p5">This is an example how I have done it (maybe there is a much better way to do it, but I didn't come up with one):</p>
<p class="p4"><br></p>
<p class="p5">==> BEGIN</p>
<p class="p4"><br></p>
<p class="p5">import std.conv;</p>
<p class="p5">import std.stdio;</p>
<p class="p5">import std.string;</p>
<p class="p5">import std.traits;</p>
<p class="p4"><br></p>
<p class="p5">// @@example code should work with classes as well</p>
<p class="p5">enum A {afoo, bfoo, cfoo};</p>
<p class="p4"><br></p>
<p class="p5">enum members1 = __traits(allMembers, A); // returns TypeTuple</p>
<p class="p5">auto members2 = __traits(allMembers, A);</p>
<p class="p4"><br></p>
<p class="p5">pragma(msg, typeof(members1));</p>
<p class="p5">// pragma(msg, typeid(members1)); // run-time only</p>
<p class="p5">// static assert(is(members1 : enum)); // Error: basic type expected, not enu</p>
<p class="p4"><br></p>
<p class="p5">pragma(msg, typeof(members2));</p>
<p class="p5">// pragma(msg, typeid(members2)); // run-time only</p>
<p class="p4"><br></p>
<p class="p4"><br></p>
<p class="p5">// function that generates a string which is used as a mixin at compile time</p>
<p class="p5">// result string must conform to syntax as it was hand-written code</p>
<p class="p5">string generateEnums(T...)(string type){</p>
<p class="p5"><span class="Apple-converted-space">    </span>string code = "enum " ~ type ~ " {";</p>
<p class="p4"><br></p>
<p class="p5"><span class="Apple-converted-space">    </span>// this is a static foreach (compile time)</p>
<p class="p5"><span class="Apple-converted-space">    </span>foreach(m; T){</p>
<p class="p5"><span class="Apple-converted-space">      </span>debug pragma(msg, m ~ ","); // check what code we get at compile time</p>
<p class="p5"><span class="Apple-converted-space">      </span>code ~= m ~ ",";</p>
<p class="p5"><span class="Apple-converted-space">    </span>}</p>
<p class="p4"><br></p>
<p class="p5"><span class="Apple-converted-space">    </span>return(code ~ "}");</p>
<p class="p5">}</p>
<p class="p4"><br></p>
<p class="p5">int main(){</p>
<p class="p5"><span class="Apple-converted-space">    </span>A switch_var_a;</p>
<p class="p5"><span class="Apple-converted-space">    </span>final switch(switch_var_a){</p>
<p class="p5"><span class="Apple-converted-space">      </span>case A.afoo:</p>
<p class="p5"><span class="Apple-converted-space">      </span>case A.bfoo:</p>
<p class="p5"><span class="Apple-converted-space">      </span>case A.cfoo:</p>
<p class="p5"><span class="Apple-converted-space">    </span>}</p>
<p class="p4"><br></p>
<p class="p5"><span class="Apple-converted-space">    </span>string user_input = readln();</p>
<p class="p4"><br></p>
<p class="p5"><span class="Apple-converted-space">    </span>mixin(generateEnums!members1("B"));</p>
<p class="p5"><span class="Apple-converted-space">    </span>B switch_var_b = chomp(user_input).to!B; // get rid of terminating chars</p>
<p class="p4"><br></p>
<p class="p5"><span class="Apple-converted-space">    </span>final switch (switch_var_b) {</p>
<p class="p5"><span class="Apple-converted-space">      </span>case B.afoo:</p>
<p class="p5"><span class="Apple-converted-space">      </span>{</p>
<p class="p5"><span class="Apple-converted-space">        </span>writeln("a");</p>
<p class="p5"><span class="Apple-converted-space">        </span>break;</p>
<p class="p5"><span class="Apple-converted-space">      </span>}</p>
<p class="p5"><span class="Apple-converted-space">      </span>case B.bfoo: // if commeted will cause a compiler error</p>
<p class="p5"><span class="Apple-converted-space">      </span>{</p>
<p class="p5"><span class="Apple-converted-space">        </span>writeln("b");</p>
<p class="p5"><span class="Apple-converted-space">        </span>break;</p>
<p class="p5"><span class="Apple-converted-space">      </span>}</p>
<p class="p5"><span class="Apple-converted-space">      </span>case B.cfoo: {writeln("c");}</p>
<p class="p5"><span class="Apple-converted-space">    </span>}</p>
<p class="p4"><br></p>
<p class="p5"><span class="Apple-converted-space">    </span>return(0);</p>
<p class="p5">}</p>
<p class="p4"><br></p>
<p class="p5"><== END</p>
<p class="p4"><br></p>
<p class="p5">How about being able to write something like "ensure_final_switch B;" and have this call a CTF that generates the necessary code and has access to tool for building D structured code, AST etc.? And has a compile-time state I can later access in a upcoming CTF.</p>
<p class="p4"><br></p>
<p class="p9"><br></p>
<p class="p10">--<span class="Apple-converted-space"> </span></p>
<p class="p10">Robert M. Münch</p>
<p class="p10">http://www.saphirion.com</p>
<p class="p10">smarter | better | faster</p>
</body>
</html>