Bringing macros to Python by abusing type annotations
tinkering.xyz
tinkering.xyz
This is why (if needs to be a special form if your language is eager, but you want to have short circuit conditionals. If you language is lazy, lots of things DON'T need to be macros.
I do agree macros could reduce boilerplate though, but add the extra complexity that someone has to understand AST transformations instead of just regular old Python type dynamic code.
Stepping back though, whether with macros or metaprogramming in the dynamic data model, the hugest rule of thumb is: don’t do this stuff. You aren’t going to need it. Don’t solve your problem (like arg parsing in the Rust example) with code gen.
Always just write a bit of unmysterious extra boilerplate code that your colleagues of mixed skill will thank you for. That verbose thing that is easier for a wide audience to quickly grok despite uglier code with more boilerplate, that is great software, with mature design decision making. It will live a lot longer and be way easier to incrementally modify than the esoteric code gen approach.
Not only do you have to understand AST transformations, but you also have mysterious stack traces pointing to non-existent code.
The amount of tooling to make it debuggable and understandable is significant; the Javascript folks have done that lift but that's a large community that was heavily dependent on it.
All that said, I think AST transforms have their uses. I wrote a library[1] for pyrsistent to allow normal mutable usage of pyrsistent's immutable data structures. But I think that works because the interface it presents and the behavior it's modeling is ordinary python.
Now this. Ugh. This is abusing an internal feature of one implementation.
ns.register(foo: int, bar: int)
@ns
def add_one(foo : ns.foo) -> ns.bar:
return foo + 1
It gets a good bit more complicated than this, but when you've got a whole mess of functions to chain together, this lets you do it _reasonably_ sanely and figure out the ordering.I think it should be possible to be compatible with a type checker like mypy as it could reannotate the decorated function with the types looked up from the namespace, but I haven't tested that.
https://gist.github.com/kryptn/2f91fdd9f4c5b2a272472d5e1a5af...