[Python-Dev] ANN: PEP 335: Overloadable Boolean Operators (original) (raw)

Robert Brewer fumanchu at amor.org
Tue Sep 14 20:39:54 CEST 2004


Kevin Jacobs:

>Both of your alternatives are being used in some form and >neither is really satisfactory. Literal representations require >complex parsers, when the Python parser is really what is >desired.

Phillip J. Eby:

Maybe you missed the earlier part of the thread, where I was suggesting that a Python "code literal" or "AST literal" syntax would be helpful. For example, if backquotes didn't already have a use, one might say something like:

db.query(x.y==z and foo*bar<27) To pass an AST object to the db.query() method. The advantage would be that the AST would be parsed and syntax checked at compile time, rather than runtime.

We already have a de facto "code literal syntax": lambdas.

db.query(lambda x: x.y==z and foo*bar<27)

I use this technique in my ORM, dejavu. When declared, the lambda gets passed immediately into a wrapper which early-binds as much as possible (using Raymond's cookbook technique). See http://www.aminus.org/rbre/python/logic.py and /codewalk.py for the guts. SQL is generated from the lambda as needed (not online at the moment, sorry, coming soon). The bonus is that you can pass ordinary Python objects into the lambda and evaluate them. The current downside is that it's a bytecode hack and therefore limited to CPython, certain versions. I'd love a generic early-binder mechanism at the language level to help get around that, but it's not critical for my users (= me).

After several experiments with using &, |, and ~ for query expressions, I've pretty much quit and gone to using string literals, since AST literals don't exist. But if AST literals did exist, I'd certainly use them in preference to strings.

I tried &|~ also and quit pretty quickly (sorry, Greg ;). Using the lambdas allowed me to do more of the parsing earlier, much of it at compile-time, the rest at declaration time (I can then pickle the lambdas so users can persist ones they create).

But, even if PEP 335 were implemented, creating a query system using Python expressions would still be kludgy, because you still need "seed variables" in the current scope to write a query expression. In my example above, I didn't need to bind 'x' or 'y' or 'z' or 'foo' or 'bar', because the db.query() method is going to interpret those in some context. If I were using a PEP 335-based query system, I'd have to initialize those variables to special querying objects first.

A lot of that becomes a non-issue if you bind early. Once the constants are bound, you're left with attribute access on your core objects (x.y) and special functions (see logic.ieq or logic.today for example). Again, too, I can use the lambda to evaluate Python objects, the 'Object' side of "ORM". In that situation, the binding is a benefit.

8

That's why I say that an AST literal syntax would be much more useful to me than PEP 335 for this type of use case.

I seem to recall my AST version was quite slow, in pure Python. Can't recall whether that was all the tuple-unpacking or just my naive function-call overhead at the time.

Anyway, for those reasons, I'm -0.5.

Robert Brewer MIS Amor Ministries fumanchu at amor.org



More information about the Python-Dev mailing list