Live data from Hacker News

Macros in Python

github.com

61–70 of 71 posts

Re: Macros in Python

#61
post #57
post #55

Earlier quoted context omitted.

Yeah, we haven't looked at performance at all. "The Wonderful Thing About A Dancing Bear Is Not How Well He Dances, But That He Dances At All" We'll get to teaching him to dance well later!

Speaking about concepts perhaps Norvig post "(How to Write a (Lisp) Interpreter (in Python))" http://norvig.com/lispy.html can be useful. The concept of a dotted pair (the car and the cdr are interesting historical facts. I wish you the best for your presentation for the Mit class, it seems interesting but perhaps it should have a link to some standard techniques like machine learning. I am curious about the small pr…

The homework assignments are all online; One of the project requirements is that the code be hosted somewhere public where people can go and see it, so it'd probably be pretty easy to get a list from the prof

Re: Macros in Python

#62
post #60
post #37

Earlier quoted context omitted.

I agree nice clean work, so many try to simply "out do" with elegance and "smart code". Clean and simple is a gem hard to find. I will gladly contribute going forward.

If you're serious about wanting to contribute, my email is on my GitHub profile, so ping me and I can help you get up to speed!

^ or me

Re: Macros in Python

#63
post #51

I see the docs mention that these only work when importing modules. The dev version of IPython lets you transform the AST of code that is typed in the REPL. It would be really cool to see an IPython AST transformer based on this. Here is an example from the test files in IPython: https://github.com/ipython/ipython/blob/master/IPython/core/...

Yep, there's an issue for that! https://github.com/lihaoyi/macropy/issues/14 I've also gotten a basic implementation working in the CPython REPL, which requires you to run a function `macro_repl()` before you can use them. A Macro powered REPL would be super cool!

MacroPy now works with the CPython REPL:

    PS C:\Dropbox\Workspace\6.945\Project> python
    Python 2.7 (r27:82525, Jul  4 2010, 07:43:08) [MSC v.1500 64 bit (AMD64)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import macropy.core.macros
    0=[]=====> MacroPy Enabled >> from macropy.macros2.tracing import macros, trace
    >>> trace%[x*2 for x in range(3)]
    range(3) -> [0, 1, 2]
    (x * 2) -> 0
    (x * 2) -> 2
    (x * 2) -> 4
    [(x * 2) for x in range(3)] -> [0, 2, 4]
    [0, 2, 4]
It's somewhat hacky, but it seems to work pretty well. I went through the examples and most of them work perfectly in the REPL, except for those whose have blank-lines-in-class-def confuse it

Re: Macros in Python

#66
I implemented a network-sort function generator, but the limited lambdas of Python seem to force me to make the macro declare a real function with magic name (see below). Also, I didn't figure out how to use the walker or quasiquotes, so I'm just generating source code and taking the AST of that.

  #run.py
  import macropy.core.macros
  import target

  #batcher.py
  # http://en.wikipedia.org/wiki/Batcher_odd%E2%80%93even_mergesort

  def oddeven_merge(lo, hi, r):
    step = r * 2
    if step = 1:
        mid = lo + ((hi - lo) // 2)
        for x in oddeven_merge_sort_range(lo, mid): yield x
        for x in oddeven_merge_sort_range(mid + 1, hi): yield x
        for x in oddeven_merge(lo, hi, 1): yield x

  def oddeven_merge_sort(n):
    return list(oddeven_merge_sort_range(0, n-1))

  #target.py
  from macro_module import macros, my_expr_macro
  import dis

  my_expr_macro%(8)

  print dis.dis(fun8)

  print fun8([2, 4, 3, 5, 6, 1, 7, 8])

  #macro_module.py
  from macropy.core.macros import Macros
  from macropy.core import *
  from ast import *
  macros = Macros()

  import macropy.macros

  from batcher import oddeven_merge_sort

  @macros.expr
  def my_expr_macro(tree):
   return parse_stmt("def fun" + str(tree.n) + "(a):\n" + 
   "\n".join(["  if a[{0}] > a[{1}]: tmp = a[{0}]; a[{0}] = a[{1}]; a[{1}] = tmp".format(x,y) for (x,y) in oddeven_merge_sort(tree.n)]) + 
   "\n  return a")
When running, it will spit out the Python bytecode disassembly to show the unrolled sorting loop.

Re: Macros in Python

#67
post #21

Something about classes that are nested inside other classes suddenly being available as top level classes seems wrong. I'm not super deep on the innards of Python, but that doesn't look right.

Other author here: Like lihaoyi said, it's true that the way we defined things doesn't match standard Python namespacing, but it saves some typing and I think it's easy to get used to the semantics of our case classes. Our macro just transforms the "namespace tree" that you would normally get from writing code like that into an "inheritance tree", where all the subclasses' names are at the level of the top class. If…

> it saves some typing

Your macropy is very interesting, but please do not use this argument. "Saving some typing" is the least interesting side-effect of some macros.

To clarify my point: in most of the industry, we all fight hard to garden big codebases with intricate dependency problems. I am convinced that code complexity management is very far from a solved problem, and I hope advanced tools like macros can help there.

But "saving a few keystrokes" is very often at the heart of the stupides issues we have with code complexity.

Two examples:

+ "from x import " + template.render(tpl_file, locals()) *locals()" in the Mako doc.

Re: Macros in Python

#69
post #45
post #17

Earlier quoted context omitted.

It definitely looks funny from a python point of view; it's inspired by ADTs and OCaml. Perhaps it would be better to leave them to be accessed via a qualified name (e.g. `List.Nil`, `List.Cons`). This is all up for debate.

A qualified name makes more sense to me. Having them exposed as top-level classes just doesn't feel right, given how they are defined.

True. The way it is now is counter-intuitive.

Re: Macros in Python

#70
post #49

Earlier quoted context omitted.

Decorators can do this? I did not know this. I thought decorators just get handed the object after initialization, so something like: @blah class Lol: pass is equivalent to: class Lol: pass blah(Lol) What am I missing?

isn't it equivalent to class Lol: pass Lol = blah(Lol)

Sorry, yes.
Post reply on HN