PEP 289: universal and existential operators

Alex Martelli aleax at aleax.it
Thu Nov 6 21:45:28 CET 2003


rm wrote:

> austin at smartobject.biz (Jess Austin) wrote >
>> It seems like the consensus is "all" and "any".
>> 
> 
> which exists as well in SQL

...with a subtly different meaning...

> where x > any ( sub-select )

I can just imagine the fun somebody's going to have after
coding, e.g.:

    while x > any( ... ) :
        ...

> where exists ( sub-select )

That's another function, in Python terms.  We could
code the SQL any, all and exists (taking any iterator or
iterable argument) roughly as follows:


class any(object):

    def __init__(self, it):
        " invoked by any(it) "
        self.it = iter(it)

    def __lt__(self, x):
        " invoked by x > any(it) &c "
        for item in self.it:
            if x > item: return True
        else: return False
        # assuming x > any([]) is to be false

    # and similarly for other comparisons


class all(object):

    def __init__(self, it):
        " invoked by all(it) "
        self.it = iter(it)

    def __lt__(self, x):
        " invoked by x > all(it) &c "
        for item in self.it:
            if not (x > item): return False
        else: return True
        # assuming x > all([]) is to be true

    # and similarly for other comparisons


def exists(it):
    " invoked by exists(it) "
    for item in it: return True
    else: return False
    # assuming exists([]) is to be false


I don't think the SQL semantics for any and all merge _well_ with
those that people want around here, though it would technically be
possible to also define a __nonnull__ in each class to do the
obvious checks -- I think it would be rather confusing to allow
both "if x > all(...):" and "if all(...):" with 'all' meaning such
different things in the two cases.  Similarly for 'any'.  And
'exists' to mean 'has some true items' is of course very different
from the SQL meaning of 'exists' to mean "it's not empty"...!

I'd just love to have such meanings for any, all, and exists, but
I believe it's not going happen -- because people around here don't
like the spelling 'alltrue' to mean "all items are true" and so on.
Ah well, there will be other ways to spell similar semantics,
though goofy rather than elegant ones -- e.g., instead of:

if x > all(theitems):

we'll just have to code:

if all(x>item for item in theitems):


In any case, the SQL meaning isn't extensible to Python's chaining
of comparisons when we only have an iterator (not an iterable) --
in that case,

if x > all(itemsiterator) > y :

can't be made to mean what we'd obviously _like_ it to mean
without spending the memory to save all the items as they go,
since it's evaluated equivalently to:

_aux = all(itemsiterator)

if (x > _aux) and (_aux > y) :
    ...

and if it comes to the comparison after the implied and, the
itemsiterator is exhausted by that time.  So, maybe, it _is_
for the better that the apparently popular preference for 'all'
to mean 'alltrue' stops us from having 'all' work like in SQL
instead - it does save us from potentially non-obvious behavior
when both comparison chaining and iterators-as-opposed-to-
iterables are simultaneously involved.


Alex





More information about the Python-list mailing list