[Python-Dev] ANN: PEP 335: Overloadable Boolean Operators

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 (=

> 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.

> 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
Amor Ministries
fumanchu at amor.org

More information about the Python-Dev mailing list