# [Python-ideas] Fwd: quantifications, and tuple patterns

Guido van Rossum guido at python.org
Sat Jan 14 20:24:11 CET 2012

```On Sat, Jan 14, 2012 at 8:19 AM, Paul Moore <p.f.moore at gmail.com> wrote:

> On 14 January 2012 13:57, Annie Liu <liu at cs.stonybrook.edu> wrote:
>

Hi Annie! (*)

>  > For those two simplest examples, yes, "any" and "all" can be used.
> > However, there are two general problems.
> >
> > 1.  The order of coding using "any/all" is the opposite order of
> > thinking in one's head.  In our experience, those kinds of simple
> > examples are coded much more often using "len" than "any/all".  The
> > ordering problem gets worse when quantifications are needed in more
> > complex conditions or are nested.
>
> To be honest, that's a matter of opinion. I find any/all with a
> generator expression more readable than your syntax, because I am used
> to generator expressions as they are common in Python.
>

But Paul, aren't you missing the fact that for the algorithms that Annie
and her students want to write, the "witness" concept is essential? I.e.
they can't just use any(P(x) for x in xs) because if it returns True, they
want to know the x that made P(x) be true. Her ! notation is a (perhaps
unpythonic) attempt at exporting this witness from the quantification.

> 2.  The much worse problem is when a witness is needed from existential
> > quantification.  In my last/third example from a distributed algorithm,
> > this is the desired code (recall that ! indicates a bound variable):
> >
> >  while some (!slot_num,p1) in decisions:
> >     if some (!slot_num,p2) in proposals has p2 != p1:
> >        propose(p2)
> >     perform(p1)
>
> Wow, I find that unreadable!. The ! doesn't read as any sort of
> assignment to me. Don't forget that in Python, assignments are
> statements and don't get embedded in expressions.

I think she's well aware of that, and proposing to change it. :-)

There is no way
> you're going to get new syntax that creates an expression which embeds
> a hidden assignment accepted into Python.
>

That's your opinion. But this is python-ideas. :-)

I'd offer to re write this in idiomatic Python, but looking at it
> closer, I've no idea how to. I don't know what slot_num is meant to
> be, at first I thought p1 and p2 were predicates, but then I notice
> you are comparing them later.
>
> Can I suggest you write your example out in Python that works today,
> and then show how it looks with your proposed syntax alongside? If you
> can't find the "best" way of writing it in existing Python, just write
> it however works, no need to try to make it compact, or elegant.
> There'll be plenty of people here who will show you how to write
> idiomatic Python versions of what you post :-)
>

Actually she gave one in her first post. Here it is again:

while {p1 for (s0,p1) in decisions if s0==slot_num}:
p1 = {p1 for (s0,p1) in decisions if s0==slot_num}.pop()
for p2 in {p2 for (s0,p2) in proposals if s0==slot_num if p2 !=
p1}:

Note that the set {p1 for (s0,p1) in decisions if s0==slot_num} is computed
twice, once to decide whether to stop, and then again to compute the
witness (p1). Obviously this is inefficient, and that's what she's after.
To make this same code more efficient in Python, you'd have to do the
following, which is natural for us programmers (since we're so used to
working around limitations and inefficiencies in the systems we work with)
but unnatural for mathematicians, who count to infinity at the drop of a
hat:

while True:
temp = {p1 for (s0,p1) in decisions if s0==slot_num}
if not temp:
break
p1 = temp.pop()
for p2 in {p2 for (s0,p2) in proposals if s0==slot_num if p2 != p1}:
<whatever>

The 5 tedious lines from "while" through "pop()" would be collapsed into a
single line if you could write

while some s0, p1 in decisions if s0 == slot_num:
for p2 in {p2 for (s0,p2) in proposals if s0==slot_num if p2 != p1}:
<whatever>

TBH I'm not sure what the !slot_num notation is for -- it appears that

while some (!slot_num, p1) in decisions:

is equivalent in Annie's proposal to

while some s0, p1 in decisions if s0 == slot_num:

but I'm not sure and it doesn't feel necessary to me.

Also note that SOME and EACH quantifiers were present in ABC (Python's
predecessor: http://homepages.cwi.nl/~steven/abc/qr.html#TESTS); I dropped
them for simplicity, not because I didn't like them. If we wanted to we
could have them back (except for the problems of introducing new keywords).

__________
(*) See