Stackless & String-processing

Greg Ewing greg.ewing at compaq.com
Wed Jul 28 16:16:00 EDT 1999


Christian Tismer wrote:
> 
> def backtrack():
>     a = next_alternative(list)
>     b = next_alternative(otherlist)
>     c = next_alternative(listwhatever)
>     if specialcondition(a, b, c):
>         return 42
>     fail()

This might not do what you seem to think
it will do under Icon semantics. For each value
generated for a, you will get all the values of
b, etc., so you'll get the cross product of
the three lists. If you were expecting a parallel
iteration, that's not what you'll get.

This illustrates why I don't like this sort of
implicit generator syntax -- often it's not obvious
what it's going to do. Switching languages for a
moment, rewriting the above in Scheme it comes
out as:

(define (backtrack cont)
  (for-each-alternative list
    (lambda (a)
      (for-each-alternative otherlist
        (lambda (b)
          (for-each-alternative listwhatever
            (lambda (c)
              (if (specialcondition a b c)
                (cont 42)
                '()))))))))

which makes it perfectly clear that you have
three nested loops.

Currently there is no elegant way to write that
sort of thing in Python. Either you have to split
the thunks off into separate procedures, or put up
with a seriously crippled lambda syntax. Either
way, you get namespace problems. That's why I
suggested an extension, which would allow you to
write

def backtrack(cont):
  for_each_alternative(list) -> (a):
    for_each_alternative(otherlist) -> (b):
      for_each_alternative(listwhatever) -> (c):
        if specialcondition(a, b, c):
          cont(42)

which is actually one line shorter than the
generator version, and (to my way of thinking)
the control flow is clearer.

Greg




More information about the Python-list mailing list