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.

Reply via email to