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

Phillip J. Eby pje at telecommunity.com
Tue Sep 14 21:02:31 CEST 2004


At 11:39 AM 9/14/04 -0700, Robert Brewer wrote:
>We already have a de facto "code literal syntax": lambdas.
>
>db.query(lambda x: x.y==z and foo*bar<27)

Right, but that requires non-portable bytecode disassembly.  If there was a 
simple way to convert from a function object to an AST, I'd be happy with 
that too.


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

I'm not following what you mean by "bind early".  My point was that in 
order to have bindings for seeds like 'x' and 'z' and 'foo', most query 
languages end up with hacks like 'tables.tablename.columname' or 
'_.table.column' or other rigamarole, and that this is usually more awkward 
to deal with than the &/|/~ operator spelling.


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

When I say AST, I just mean "some kind of syntax representation", not 
necessarily the 'parser' module's current AST implementation.  However, I 
have found that it's possible to translate parser-module AST's to query 
specifications quite efficiently in pure Python, such that the overhead is 
minor compared to whatever actual computation you're doing.  The key is 
that the vast majority of AST nodes are a trivial wrapper around another 
AST node.  The core of my AST-handling engine, therefore, looks like this:

     def build(builder, nodelist):
         while len(nodelist)==2:
             nodelist = nodelist[1]
         return production[nodelist[0]](builder,nodelist)

Where 'production' is a table mapping symbol IDs to helper functions that 
invoke methods on 'builder', which then may recursively invoke 'build' on 
items in 'nodelist'.  The first two lines of this function eliminate 
enormous amounts of overhead by ignoring all the zillions of trivial 
wrapper nodes.  (Note that you must include line number information in the 
generated AST, or it will mistake tokens for unnecessary symbols.)


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

On what?  AST literals, or PEP 335?



More information about the Python-Dev mailing list