On Sunday, 17 October 2021 at 05:26:25 UTC, Araq wrote:
> On Sunday, 17 October 2021 at 04:17:38 UTC, jfondren wrote:
> https://www.youtube.com/watch?v=d2VRuZo2pdA
About 50% of it is inadvertent praise for D. The rest is ARC and C++ interop.
Ha, good one. So where is D's hygienic AST macro system that lets you reflect over types? No, string mixins and experimental std.reflection in some offside branch don't count.
I like how Andrei talks about mixin in https://youtu.be/WsgW4HJXEAg?t=3354
"and like an idiot you get to put a string in and give it to the compiler to compile for you. Which sounds ridiculous, right?", while the slide adds that this "isn't glamorous".
But in Common Lisp you are also "like an idiot, putting a list in and giving it to the compiler to compile for you". Lists have structure but a typical macro is heavy on quoting and you can read the quoted parts to understand what the resulting code would look like. The 'code' of macros, the parts that aren't quoted but are doing work like constructing lists or modifying them, are generally also perfectly normal Common Lisp code, they just happen to be constructing lists of code rather than lists of numbers or strings.
If you want to write or maintain a simple macro in Common Lisp, you don't need specialized knowledge: it is enough to know Common Lisp.
What Nim has is more like browser DOM manipulation: knowing Nim is not enough, either to write a macro or maintain a macro. You must also know have copious specialized macro knowledge about nnkSmthng and nnkSmthngElseTy. The 'easy' way to approach Nim macros is to perform the equivalent of opening a browser's developer inspection tool on the desired Nim code.
Common Lisp's macros scale from absolutely trivial
(defmacro sleep-units (value unit)
`(sleep
(* ,value
,(case unit
((s) 1)
((m) 60)
((h) 3600)
((d) 86400)
((ms) 1/1000)
((us) 1/1000000)))))
to whatever this is: https://github.com/thephoeron/let-over-lambda/blob/master/let-over-lambda.lisp#L356
For trivial cases, Nim has templates. Why? Why not remove templates from the language and tell people to use macros for trivial cases as well?
Or suppose that during a presentation this code were put on the screen:
struct Object {
float[2] position, velocity, facing;
float size;
}
struct Player {
mixin parent!Object;
int hp;
}
mixin template parent(Struct) {
static foreach (i, alias f; Struct.tupleof) {
mixin("typeof(f) ", __traits(identifier, f), " = Struct.init.tupleof[i];");
}
}
void main() {
import std.stdio : writeln;
writeln(Player([0, 0], [0, 0], [0, -1], 5.0, 100));
}
I could say "as you can see, I'm looping here over the members of the given struct, and am injecting new field definitions that have the same types, names, and initial values that the struct has." And the "as you can see" would be literal, not ironic. People really can look at that mixin and see what it does.
Do you think deech could've said something like that about https://github.com/deech/NimNuggets/blob/master/backup/migrationmacros.nim#L11 ? Do you think including that code in his presentation would've done more or less to sell Nim to the audience?
Nim macros are more capable than string mixins, but Nim's metaprogramming story is really not that enviable.