[Python-ideas] combining two threads: switch statements and inline functions

spir denis.spir at gmail.com
Wed Feb 12 11:27:20 CET 2014


On 02/12/2014 11:07 AM, Andrew Barnert wrote:
> From: Steven D'Aprano <steve at pearwood.info>
>
>
> I think neither Alex Rodrigues's initial idea nor Bruce Leban's side idea area any of these.
>
> [...]
>
> Meanwhile, Alex was proposing something very different. Really, what he wants is runtime computational (i.e., bytecode) macros. Look at his motivating example:
>
>      @inline
>      def element_wise(func):
>          func = inline(func)
>          for …:
>              func()
>
>      def is_symmetric(matrix):
>          element_wise(lambda: if matrix[i][j] != matrix[j][i]: return False)
>          return True
>
>
> Forget about how the variables work for the moment (and the fact that, on top of his main desire, he _also_ wants a statement inside his lambda…) and look at that "return False". Clearly it has to return from not just the lambda, but element_wise, and is_symmetric. That's the key here; that's what makes it "inline" in Alex's terms. It's not a function on the stack with its own frame, it's just code that gets compiled as a function, but then executed inline directly in the calling function's frame. This doesn't quite work for a few relatively minor reasons (functions get an implicit "return None", variables are referred to by index and may not have the right indices, etc.), but the idea isn't nonsense.
>
> Once you see that, dynamic vs. lexical scope is a red herring. Either way, the stack frame in which matrix gets evaluated is the stack frame of is_symmetric. The existing closure variable lookup does the right thing. (Note that the definition of the lambda forces matrix to be looked up via *_DEREF in is_symmetric, so the *_DEREF code in the lambda is correct when inlined.) And it would _have_ to be right for the return-through to make any sense. Dynamic scope doesn't seem to add any possibilities here that it wouldn't already add in regular functions; I think it's orthogonal, and irrelevant, to the proposal. But I could be wrong.
>
> Anyway, I don't think he really needs runtime macros; he only needs "func = inline(func)" because element_wise itself is defined as a function and converted to a macro with "@inline". If the latter were compile-time, the former could be as well. (Imagine a "defmacro" statement and a "lambdamacro" expression.) And that eliminates a whole lot of complexity (dynamically generating dynamic code-fixup code, etc.). And if you don't need runtime macros, you probably don't need computational macros, which eliminates even more (e.g., in the AST, "matrix" is a name, not an index). The key thing he wants is macros. But what he asked for is runtime computational macros.

How does this relate to Ruby blocks, procs, and lambdas? One of them is to 
solves the issue of which-is-the-actual-piece-of-code-to-return-from, IIRC 
(dunno much of Ruby), like your motivating example of "inline" funcs here.

d


More information about the Python-ideas mailing list