Skip to content

Instantly share code, notes, and snippets.

@upgradingdave
Last active December 11, 2015 06:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save upgradingdave/4559296 to your computer and use it in GitHub Desktop.
Save upgradingdave/4559296 to your computer and use it in GitHub Desktop.
Possible to use bound-fn inside for?
user> (def ^{:dynamic true} *my-var* nil)
#'user/*my-var*
user> (defn doStuff [] {:myvar *my-var*})
#'user/doStuff
user> (doStuff)
{:myvar nil} ;; so far so good
user> (binding [*my-var* "different"] (for [x [1]] (doStuff)))
({:myvar nil}) ;; makes sense because for yeilds a lazy seq
user> (binding [*my-var* "different"] (doall (for [x [1]] (doStuff))))
({:myvar "different"}) ;; forcing eval of lazy seq works as expected
;; beware of lazy seqs, this won't work because the bound-fn is realized afterwards and
;; outside of the binding form's scope.
user> (apply (first (binding [*my-var* "different"] (for [x [1]] (bound-fn* doStuff)))) nil)
({:my-var "different"})
;; this won't work for the same reason
user> (apply (first (apply (binding [*my-var* "different"] (bound-fn* (fn [] (for [x [1]] doStuff)))) nil)) nil)
({:my-var "different"})
;; but if the binding becomes part of the forms that are inside the lazy seq, then...
user> (for [x [1]] (binding [*my-var* "different"] (doStuff)))
({:my-var "different"}) ;; success!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment