Nim Nuggets: Nim talk at Strange Loop 2021
jfondren
julian.fondren at gmail.com
Sun Oct 17 11:10:16 UTC 2021
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
```lisp
(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:
```d
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.
More information about the Digitalmars-d
mailing list