[plt-scheme] On continuations...

From: Eli Barzilay (eli at barzilay.org)
Date: Sun Dec 19 21:46:57 EST 2004

On Dec 20, Alexander Schmolck wrote:
> B) Which trivially transformed into a (of course no longer
>    functional) generator version:
>     def lazyPartitions(n):
>         return (n == 0 and iter([]) or
>                 ([head] + tail for head in range(1, n+1) 
>                                for tail in partitions(n-head) 
>                                if not tail or tail[0] <= head))

Why is this not functional?

(And why is it lazy?  (and why is lazyPartitions calling partitions?))

> This also translates pretty directly into (non-idiomatic) Haskell:
>     partitions n = if n == 0 then 
>                        [[]]
>                    else 
>                        [h:t | h <- [1..n], 
>                               t <- partitions(n-h), 
>                               t == [] || (head t) <= h]
> And frankly though the generators might be evil/imperative etc. --
> in practice I'd be rather more quickly convinced of the correctness
> of the above python and haskell versions than of that of the
> list-based scheme versions posted so far (because I find it more
> readable).

Readability is an illusion.  I find the python code very confusing and
full of little pitfalls (is `iter' a keyword? is iter([]) a boolean?
is `tail' a boolean?)

The only point that seem to make the above code more readable is the
list comprehension syntax.  In Swindle, I write the exact same code as
the haskell code:

  (define (partitions n)
    (if (= n 0)
      (list-of (cons h t)
        (h <- 1 .. n)
        (t <- (partitions (- n h)))
        (or (null? t) (<= (head t) h)))))

Defining a `stream-of' for a lazy list comprehension is trivial.

          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                  http://www.barzilay.org/                 Maze is Life!

Posted on the users mailing list.