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.