Export to GitHub

clojure - issue #97

partition-by does not work correctly when passed a function with side-effects


Posted on Mar 15, 2009 by Swift Bird

> 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 Dog

partition-by is not part of Clojure core

Status: Invalid

Labels:
Type-Defect Priority-Low