

Macros in Python: quasiquotes, case classes, LINQ and more - mzl
https://github.com/lihaoyi/macropy

======
aldanor
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.

~~~
JackC
The "whatever" library looks really neat -- thanks for the reference:

[https://pypi.python.org/pypi/whatever](https://pypi.python.org/pypi/whatever)

------
davidshepherd7
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.

[0]:
[https://github.com/lihaoyi/macropy/issues/32](https://github.com/lihaoyi/macropy/issues/32)

~~~
scrollaway
Can I recommend the wonderful `q`?

[https://pypi.python.org/pypi/q](https://pypi.python.org/pypi/q)

"import q; q(var1, var2)" forces printing to $TMPDIR/q (usually /tmp/q) very
detailed output of what you are tracing and what it is.

The @q decorator does somewhat the same as the "with trace" context manager.

~~~
davidshepherd7
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.

------
est
AST transformation is nice but you can also have magic macros using `coding`
hack. It could add _arbitrary_ syntax to python

[https://github.com/syrusakbary/interpy](https://github.com/syrusakbary/interpy)

previously
[https://news.ycombinator.com/item?id=9340784](https://news.ycombinator.com/item?id=9340784)

~~~
eatonphil
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?

~~~
est
> If there were a macro framework that used `coding`

Does JSX-like template for Python count?

[https://github.com/dropbox/pyxl](https://github.com/dropbox/pyxl)

    
    
        # coding: pyxl
        print <html><body>Hello {my_var}!</body></html>
    

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.

~~~
eatonphil
Ah! Sorry about that. As I said, I was confused. That is very interesting.

------
ithkuil
A few years ago I wrote a similar thing:
[https://github.com/mmikulicic/metacontext](https://github.com/mmikulicic/metacontext)
(now unmaintained)

------
thomasahle
It's a cool project, but I think it needs more examples on the front page. The
class example might as well have been a namedtuple.

~~~
davidshepherd7
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).

[0]: [https://github.com/lihaoyi/macropy#skeletons-in-the-
closet](https://github.com/lihaoyi/macropy#skeletons-in-the-closet)

------
bberrry
Forgive my ignorant question but why do their examples only work in REPL?

~~~
ubernostrum
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.

