
clojure - issue #97
partition-by does not work correctly when passed a function with side-effects
> What (small set of) steps will reproduce the problem?
(def coll '(a a b c nil nil nil d e f)) (partition-by #(or (nil? %) (gensym)) coll) ==> partition-by runs into an endless loop
> What is the expected output? What do you see instead?
From what the doc string says it seems that partition-by would return: ((a) (a) (a) (b) (c) (nil nil nil) (d) (e) (f)) The provided function returns for non-nil elements a new value.
> What version are you using?
r1327
> Please provide any additional information below.
A minimum change would be to update the doc strings, stating that f must not have side-effects. But if we would like to keep that door open, then the current behaviour could be patched. The problem is this: In partition-by fv gets assigned (f (first s)), and only a moment later (f (first s)) is evaluated again, in the binding for run, in the take-while. But as f has side effects we have: (= (f (first s)) (f (first s))) ==> false Now take-while will return an empty lazy-seq and the drop will remove zero elements, as run is empty.
Instead fv should always be an element of run, and take-while should run on the rest of s instead of on s itself.
Comment #1
Posted on Mar 16, 2009 by Massive Dogpartition-by is not part of Clojure core
Status: Invalid
Labels:
Type-Defect
Priority-Low