Created
July 8, 2013 12:29
-
-
Save gerritjvv/5948398 to your computer and use it in GitHub Desktop.
Partitioning Lazy Sequences
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Caution: Partitioning lazy sequence code freeze | |
(def l [1 2 3 4 5]) | |
;create a simple lazy sequence function testing only | |
;(rdr l) returns a lazy sequence from l | |
(def rdr (fn reader[x] (cons (first x) (lazy-seq (reader (rest x)))))) | |
;the line below will freeze | |
(doall (partition-all 2 (rdr l)) ) | |
;add-in a take-while statement do exit the lazy sequence on nil | |
(doall (partition-all 2 (take-while (complement nil?) (rdr l)))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Your issue here isn't that your sequence is lazy, it's that your sequence is infinite. Your
rdr
function returns an infinite list starting with the argument it's passed, then continuing withnil
s forever (try(take 100 (rdr l))
and you can see thenil
s; feel free to vary that100
however you like).If you redefined
rdr
like this then you wouldn't have any issues:The thing you missed is that your
rdr
must return an empty sequence for the end of the lazy sequence.(cons nil x)
is non-empty, no matter whatx
is (assuming thatcons
call makes sense), so yourrdr
always returns a non-empty sequence, and therefore never ends.This isn't your whole problem, though.
partition-all
can handle infinite lists, too.(take 10 (partition-all 2 (rdr l)))
will terminate as you'd expect, but yourdoall
is trying to force an infinite collection. This can't possibly terminate, because you'll never reach the end of the sequence.Your
take-while
solves the problem by truncating your sequence before thenil
s, but it won't work properly if yourl
is different. As an example, try using(def l [1 2 3 nil 4 5 6])
. Now your final line doesn't give me back my wholel
, like it should. Using therdr
function I provided above along with your line 9 solves this problem.