Looks like a fun project on its own, with a lot of syntax tree hackery going on, but I see no real (pragmatic) use since many of the AST hacks and use cases presented are in my opinion completely unwarranted and can already be solved by the existing machinery (perhaps with quite heavy use of the metaclasses).
As an example, instead of hacking the AST via macros:
@case
Point(x, y): pass
one could just do a (this example implies, of course, that there is a CaseClassMeta somewhere attached to CaseClass):
class Point(CaseClass):
fields = 'x', 'y'
Not only this is nicer, you retain full control of the MRO on the metaclass level and can adjust its behaviour as needed and when needed.
Enums, complex enums and class body nesting examples -- can also be solved via metaclasses quite easily.
Quick lambdas example -- is somewhat close to "whatever" Python library, this is probably the one case which cannot be reproduced as is without AST hacks.
Yes, the use of macros is not always justified in the examples, because Python is quite expressive already.
However, the ability to have macros is orthogonal with the feature set of the language. What is interesting is the ability to inspect and modify a Python AST.
Of course, meta-programming is a way to integrate otherwise absent features of a language as-if they were built-in.
Python is sufficiently dynamic that most things can be done using existing facilities, like reflection and metaobjects (the @case example, as you mention).
But there is a difference between using those facilites at runtime and producing some code at macro-expansion time (this might be relevant for Cython, for example).
You can, for example, define a domain-specific language that is directly translated as Python, and not interpreted like an API-based representation would. You can even apply custom type checking for that DSL.
Or, you could analyze an existing python source code and produce a translation in another language without having to reimplement a parser (see the Python-to-Javascript example, or Common-Lisp's Parenscript).
And one could use complex, or quaternions to represent points in order to not have to reinvent the wheels of rotation/translation/computing area/projections/polar to cartesian ...
I think the class point is the proof OOP is not able to give a real use case for itself other than reimplementing the wheel poorly.
OOP has proven to be confusing the youngs and lazy. It makes people confused about abstraction and the concrete world (map and territory).
It is pedantic, and inefficient.
EDIT: But the code of this guy is still amazing, even if totally pushing in wrong directions sometimes: memoization is the worst caching strategy possible. On the other hand the PEG parser is brilliant, like most of the code.
Some of these things look really nice. I'm particularly impressed by the tracing macro:
with trace:
sum = 0
for i in range(0, 5):
sum = sum + 5
prints
sum = 0
for i in range(0, 5):
sum = sum + 5
range(0, 5) -> [0, 1, 2, 3, 4]
sum = sum + 5
sum + 5 -> 5
sum = sum + 5
sum + 5 -> 10
sum = sum + 5
sum + 5 -> 15
sum = sum + 5
sum + 5 -> 20
sum = sum + 5
sum + 5 -> 25
This would save a huge amount of boring typing `print(...)` when debugging,
and since it's only for debugging you don't even need to have MacroPy as a
dependency!
Unfortunately python 3.4 support is not quite ready [0], and attempting to
install it with `pip3` just fails.
It seems nice, but not quite as powerful. I like the way the tracing macro automatically prints every intermediate value, but q doesn't seem to do that.
I'm a little confused where you are going with this. Could you elaborate a little? Its one thing for this to be possible using `coding`, but this is a macro builder available right now. Interpy just highlights the possibility of this, right? If there were a macro framework that used `coding` it would seem more relevant. Otherwise it looks like you're comparing apples and a knife. Am I missing something?
Combined with this, we can make Meteorjs-like applications in Python directly. Even AST transformation of backend DOM operations in Python directly rendered to Javascript to browser.
Their argument [0] against namedtuple is that the namedtuple implementation is basically a hackier macro anyway (format a string then eval it). But I agree that it's not the most impressive example of what you can do with macros (see my other post).
It works in or out of the REPL (in fact, they document "MacroPy also works in the REPL"). It's just standard-ish in Python documentation to give examples formatted the way the REPL would display them.
As an example, instead of hacking the AST via macros:
one could just do a (this example implies, of course, that there is a CaseClassMeta somewhere attached to CaseClass): Not only this is nicer, you retain full control of the MRO on the metaclass level and can adjust its behaviour as needed and when needed.Enums, complex enums and class body nesting examples -- can also be solved via metaclasses quite easily.
Quick lambdas example -- is somewhat close to "whatever" Python library, this is probably the one case which cannot be reproduced as is without AST hacks.