Python Macros: Use Cases?

后端 未结 17 2106
甜味超标
甜味超标 2021-01-30 18:37

If Python had a macro facility similar to Lisp/Scheme (something like MetaPython), how would you use it?

If you are a Lisp/Scheme programmer, what sorts of things do y

相关标签:
17条回答
  • 2021-01-30 18:59

    Some examples of lisp macros:

    • ITERATE which is a funny and extensible loop facility
    • CL-YACC/FUCC that are parser generators that generate parsers at compile time
    • CL-WHO which allows specifying html documents with static and dynamic parts
    • Parenscript which is a javascript code generator
    • Various simple code-wrappers, e.g., error handlers (I have a with-gtk-error-message-handler that executes code and shows GtkMessageDialog if unhandled error occurs), executors (e.g., given a code, execute it in different thread; I have a within-main-thread macro that executes code in different threads; PCall library uses macros to wrap code to be executed concurrently)
    • GUI builders with macros (e.g., specify widgets hierarchy and widgets' properties and have a macro generate code for creation of all widgets)
    • Code generators that use external resources during compilation time. E.g., a macro that processes C headers and generates FFI code or a macro that generates classes definitions based on database schema
    • Declarative FFI. E.g., specifying the foreign structures, functions, their argument types and having macros to generate corresponding lisp structures, functions with type mapping and marshaling code
    • Continuations-based web frameworks for Common Lisp use macros that transform the code into CPS (continuation passing style) form.
    0 讨论(0)
  • 2021-01-30 19:03

    This is a somewhat late answer, but MacroPy is a new project of mine to bring macros to Python. We have a pretty substantial list of demos, all of which are use cases which require macros to implement, for example providing an extremely concise way of declaring classes:

    @case
    class Point(x, y)
    
    p = Point(1, 2)
    print p.x   # 1
    print p     # Point(1, 2)
    

    MacroPy has been used to implement features such as:

    • Case Classes, easy Algebraic Data Types from Scala
    • Pattern Matching from the Functional Programming world
    • Tail-call Optimization
    • Quasiquotes, a quick way to manipulate fragments of a program
    • String Interpolation, a common feature in many languages, and Pyxl.
    • Tracing and Smart Asserts
    • PINQ to SQLAlchemy, a clone of LINQ to SQL from C#
    • Quick Lambdas from Scala and Groovy,
    • Parser Combinators, inspired by Scala's.

    Check out the linked page to find out more; I think I can confidently say that the use cases we demonstrate far surpass anything anyone's suggested so far on this thread =D

    0 讨论(0)
  • 2021-01-30 19:03

    In lisp, macros are just another way to abstract ideas.

    This is an example from an incomplete ray-tracer written in clojure:

    (defmacro per-pixel
      "Macro.
    Excecutes body for every pixel. Binds i and j to the current pixel coord."
      [i j & body]
      `(dotimes [~i @width]
         (dotimes [~j @height]
           ~@body)))
    

    If you want to do something to every pixel with coordinates (i,j), say, draw a black pixel if i is even, you would write:

    (per-pixel i,j
      (if (even? i)
        (draw-black i,j)))
    

    This is not possible to do without macros because @body can mean anything inside (per-pixel i j @body)

    Something like this would be possible in python as well. You need to use decorators. You can't do everything you can do with lisp macros, but they are very powerful

    Check out this decorator tutorial: http://www.artima.com/weblogs/viewpost.jsp?thread=240808

    0 讨论(0)
  • 2021-01-30 19:03

    Well, I'd like instead of

    print >> sys.stderr, "abc"
    

    to write

    err "abc"
    

    in some scripts which have many debug printout statements.

    I can do

    import sys
    err = sys.stderr
    

    and then

    print >> err, "abc"
    

    which is shorter, but that still takes too many characters on the line.

    0 讨论(0)
  • 2021-01-30 19:04

    Here's one real-world example I came across that would be trivial with macros or real metaprogramming support, but has to be done with CPython bytecode manipulation due to absence of both in Python:

    http://www.aminus.net/dejavu/chrome/common/doc/2.0a/html/intro.html#cpython

    This is how the problem is solved in Common Lisp using a combination of regular macros, and read-macros to extend the syntax (it could have been done without the latter, but not the former):

    http://clsql.b9.com/manual/csql-find.html

    The same problem solved in Smalltalk using closures and metaprogramming (Smalltalk is one of the few single-dispatch OO languages that actually gets message passing right):

    http://people.csail.mit.edu/gregs/ll1-discuss-archive-html/msg02096.html

    Here I tried to implement the Smalltalk approach in Common Lisp, which is a good illustration of how metaprogramming is poorly supported in the latter:

    http://carcaddar.blogspot.com/2009/04/closure-oriented-metaprogramming-via.html

    0 讨论(0)
提交回复
热议问题