foo => "bar" key/value literals in D!

Meta via Digitalmars-d-announce digitalmars-d-announce at puremagic.com
Mon May 23 18:11:39 PDT 2016


On Monday, 23 May 2016 at 19:00:40 UTC, Adam D. Ruppe wrote:
> Have I gone completely mad?!?!
>
> ---
> void main() {
>         import std.stdio;
>         writeln(obj!(
>                 foo => "bar",
>                 baz => 12
>         ));
> }
> ---
>
> Prints out:
>
> {
>         foo: bar
>         baz: 12
> }
>
>
>
> A few tweaks would make a whole loose typed hash thing more 
> akin to Ruby or PHP than D. What's obj? Behold:
>
>
> string obj(T...)() {
>         import std.conv, std.traits;
>         string jsonResult = "{";
>         foreach(arg; T) {
>                 jsonResult ~= "\n\t";
>
>                 // I don't know why the usual is(__parameters) 
> trick
>                 // won't work here, but a stringof hack will!
>                 string hack = typeof(arg!string).stringof;
>                 import std.string;
>                 hack = hack[hack.indexOf("function(string ") + 
> "function(string ".length .. $];
>                 hack = hack[0 .. hack.indexOf(")")];
>
>                 jsonResult ~= hack;
>                 jsonResult ~= ": ";
>                 jsonResult ~= to!string(arg(""));
>
>         }
>         jsonResult ~= "\n}";
>         return jsonResult;
> }
>
>
>
>
> As you probably know, D has a couple lambda literal syntaxes. 
> One of these is the fat arrow, with a valid form of argument => 
> return_expression.
>
> The compiler makes templates out of these when you pass them 
> around.... and those templates contain the parameters, 
> including the name, and are callable code (if instantiated with 
> a concrete type).
>
> I was disappointed to see the ordinary reflection tools didn't 
> work here - I know, I'm abusing the language - but the trusty 
> old .stringof hack did! Combined with the magic knowledge that 
> these things are templates, I instantiated them (tbh I was a 
> bit surprised it actually let me!) and extracted the name of 
> the argument.
>
> Then simply running it results in the value at runtime.
>
> Combining these with facilities for building values - here, I 
> just did a string but it could be whatever - results in an 
> array that almost looks like it was pulled from one of those 
> dynamic languages.
>
>
>
> Complete program here (may include bug fixes made after posting 
> this announcement):
>
> http://arsdnet.net/dcode/have_i_lost_my_marbles.d
>
>
> I might actually use this nasty trick in some of my ugly code.

Clever and terrible. Now just modify the code to generate a 
struct or class and you've invented new anonymous struct/object 
syntax.

Also, I think this has revealed a bug (or deficiency) in the 
compiler. If you put this inside the foreach loop:

		import std.traits;
		alias inst = arg!string;
		pragma(msg, ParameterIdentifierTuple!inst);

It prints out `tuple("")` both times, meaning that for some 
reason it sees these lambdas as having no parameter names.


More information about the Digitalmars-d-announce mailing list