On 4/25/05, Guido van Rossum email@example.com wrote:
It could also be done (though not as cleanly) by making macros act as import hooks.
Brrr. What about imports that aren't at the top level (e.g. inside a function)?
Bad style already. :D If you want to use the macro, you have to ensure it was already imported.
That said, I did say it wasn't as clean; think of it like pre-caching which dictionary that resolved an attribute lookup. Don't start with the complexity, but consider not making the optimization impossible.
Why not just introduce macros?
Because I've been using Python for 15 years without needing them?
And also without anonymous blocks or generator finalizers or resource managers.
Sorry, but "why not add feature X" is exactly what we're trying to AVOID here.
If anything is added, it might be better to add a single generalized tool instead of several special cases -- unless the tool is so general as to be hazardous. Unlimited macros are that hazardous.
If the answer is "We don't want
xx sss (S\<! 2k3 ]
to ever be meaningful", then we need to figure out exactly what to prohibit.
I don't understand what the point is of using an example like "xx sss (S<! 2k3 ]".
The simplest way to implement macros is to add an import hook that can modify (replace) the string containing the source code. Unfortunately, that would allow rules like
"replace any line starting with 'xx' with the number 7"
Outside of obfuscators, almost no one would do something quite so painful as that ... but some people would start using regex substitutions or monkey-patching. I would hate to debug code that fails because a standard library module is secretly changed (on load, not on disk where I can grep for it) by another module, which doesn't even mention that library by name...
As Michael said, we have to think about what transformations we do not want happening out of sight. I would have said "Just use it responsibly" if I hadn't considered pathological cases like that one.
[yield works great for a single "anonymous block", but not so great for several blocks per macro/template.]
Pehaps you've missed some context here? Nobody seems to be able to come up with other [than resource wrappers] use cases, that's why "yield" is so attractive.
Sorry; to me it seemed obvious that you would occasionally want to interleave the macro/template and the variable portion. Robert Brewer has since provided good examples at
Or do we really just want a way to say that a function should share its local namespace with it's caller or callee? In that case, maybe the answer is a "lexical" or "same_namespace" keyword. Or maybe just a recipe to make exec or eval do the right thing.
But should the same_namespace modifier be part of the call site or part of the callee?
IMHO, it should be part of the calling site, because it is the calling site that could be surprised to find its own locals modified. The callee presumably runs through a complete call before it has a chance to be surprised.
I did leave the decision open because I'm not certain that mention-in-caller wouldn't end up contorting a common code style. (It effectively forces the macro to be in control, and the "meaningful" code to be callbacks.)