[Haskell-cafe] Prime sieve and Haskell demo

Doug McIlroy doug at cs.dartmouth.edu
Wed Apr 29 01:36:52 UTC 2015

With deep apologies for sending the wrong file, I try again.


>> How about simply changing `sieve` to `trialDiv`?  It's not that I
>> don't like the given example, because it gives a very small use case
>> for laziness that is difficult enough to reproduce in an eagerly
>> evaluated language.
> Is it really so difficult to reproduce in a strict language? Here is
> that Haskell example in OCaml
> let primes =
>   let rec trialDiv (Cons (p,xs)) =
>     Cons (p, lazy (trialDiv @@ filter (fun x -> x mod p <> 0) @@ Lazy.force xs))
>   in trialDiv @@ iota 2

I'm afraid I don't understand why the program isn't a sieve. Is
the concern that the sequence of integers is thinned by dropping
composites rather than by merely marking them and counting across
them? Or is it that a trace of lazy evaluation will show that all
the divisibility tests on a single integer are clustered together
in time? Or something I haven't thought of?

Of course the program can be written in any Turing-complete language,
but the effort is likely to cause beads of sweat, like "lazy",
"force", or "spawn" to be shed on the algorithmic pearl. The sieve
can even be written succinctly as a bash shell script (below),
which exhibits warts (e.g. five flavors of parentheses) but no sweat.

Though both the Ocaml and the shell code are compact, neither dulls
the luster that lazy evaluation imparts to the Haskell.

    sift() {
        while true; do
            read p
            if (( $p % $1 != 0 )); then echo $p; fi
        done }
    sink() { read p; echo $p; sift $p | sink }

    seq 2 1000000 | sink

More information about the Haskell-Cafe mailing list