Phillip J. Eby wrote: > 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. If it were fast enough, I would 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. Dejavu addresses that by separating the "table binding" from the expression. That is, given: z = "Hansel" e = logic.Expression(lambda x: x.Name.startswith(z)) books = recall(myapp.Book, e) authors = recall(myapp.Author, e) ...'x' isn't bound within the Expression declaration; it is supplied as the first param to recall(). For example, you could apply the same Expression to both a Book class/table and an Author class/table within the same application, as above. IMO, this is a natural way to map the lambda-calculus to a query language, where the bound variable = ORM-object instances (a "table row"). But any free variables need to be resolved ASAP; therefore, z gets evaluated completely and immediately; Expression() rewrites the lambda co_code, replacing the closure lookup with a LOAD_CONST (sticking the value of z into co_consts). > > > 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. Sure. > 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... Hmm, perhaps I'll look again. > >Anyway, for those reasons, I'm -0.5. > > On what? AST literals, or PEP 335? The PEP. ASTs would be better. A builtin early-binder would make me happiest, but I won't hold my breath. I don't think it would require new syntax, either, just something like codewalk.EarlyBinder() and .LambdaDecompiler() in a standard lib module somewhere. But I may go back and look at ASTs again. Robert Brewer MIS Amor Ministries fumanchu at amor.org
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4