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
rdrfunction returns an infinite list starting with the argument it's passed, then continuing withnils forever (try(take 100 (rdr l))and you can see thenils; feel free to vary that100however you like).If you redefined
rdrlike this then you wouldn't have any issues:The thing you missed is that your
rdrmust return an empty sequence for the end of the lazy sequence.(cons nil x)is non-empty, no matter whatxis (assuming thatconscall makes sense), so yourrdralways returns a non-empty sequence, and therefore never ends.This isn't your whole problem, though.
partition-allcan handle infinite lists, too.(take 10 (partition-all 2 (rdr l)))will terminate as you'd expect, but yourdoallis trying to force an infinite collection. This can't possibly terminate, because you'll never reach the end of the sequence.Your
take-whilesolves the problem by truncating your sequence before thenils, but it won't work properly if yourlis 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 therdrfunction I provided above along with your line 9 solves this problem.