Python Macros: Use Cases?
I believe that macros run counter to Python's culture. Macros in Lisp allow the big ball of mud approach; you get to redefine the language to become more suited to your problem domain. Conversely Pythonic code uses the most natural built in feature of Python to solve a problem, instead of solving it in a way that would be more natural in a different language.
Macros are inherently unpythonic.
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:
@caseclass Point(x, y)p = Point(1, 2)print p.x # 1print 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
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.