[Python-ideas] History on proposals for Macros?

Ron Adam ron3200 at gmail.com
Sun Mar 29 19:21:00 CEST 2015



On 03/28/2015 09:51 PM, Steven D'Aprano wrote:
> But we might be able to rescue this proposal by dropping the requirement
> that the compiler knows when to pass the syntax tree and when to
> evaluate it. Suppose instead we had a lightweight syntax for generating
> the AST plus grabbing the current context:
>
>      x = 23
>      spam(x + 1, !(x+1))  #  macro syntax !( ... )
>
>
> Now the programmer is responsible for deciding when to use an AST and
> when to evaluate it, not the compiler, and "macros" become regular
> functions which just happen to expect an AST as their argument.

Something related to this that I've wanted to experiment with, but is hard 
to do in python to be able to split a function signature and body, and be 
able to use them independently. (But in a well defined way.)


A signature object could have a default body that returns the closure.

And a body (or code) could have a default signature that *takes* a namespace.


Then a function becomes ...

      code(sig(...))    <--->   function(...)



The separate parts could be created with a decorator.

     @signature
     def sig_x(x): pass

     @code
     def inc_x(): x += 1

     @code
     def dec_x(): x -= 1


In most cases it's best to think of applying code bodies to names spaces.

     names = sig_x(0)
     inc_x(names)
     dec_x(names)

That is nicer than continuations as each code block is a well defined unit 
that executes to completion and doesn't require suspending the frame.

(Yes, it can be done with dictionaries, but that wouldn't give the macro 
like functionality (see below) this would.  And there may be other benifits 
to having it at a lower more efficient level.)


To allow macro like ability a code block needs to be executable in the 
current scope.  That can be done just by doing...

     code(locals())      #  Dependable?


And sugar to do that could be...

     if x < 10:
        ^^ inc_x   #just an example syntax.
     else:
        ^^ dec_x   # Note the ^^ looks like the M in Macro. ;-)


Possibly the decorators could be used with lambda directly to get inline 
functionality.

     code(lambda : x + 1)


And a bit of sugar to shorten the common uses if needed.

     spam(x + 1, code(lambda : x + 1))

     spam(x + 1, ^^: x + 1)


Cheers,
    Ron








































More information about the Python-ideas mailing list