Here is the short form of the proposal below: 1. Make as-> in Clojure 1.5 have a syntax and semantic matching how fn is used in pipelines. 2. Rename as-> to fn-> reflecting its similarity to fn.
-- Terje Norderhaug On Sun, Dec 2, 2012 at 5:30 PM, Terje Norderhaug <te...@in-progress.com> wrote: > On Thu, Nov 15, 2012 at 5:17 PM, Alan Malloy <a...@malloys.org> wrote: >> The primary point of let-> is that you can insert it into an existing -> >> pipeline. >> >> (-> foo >> (stuff) >> (blah) >> (let-> foo-with-stuff >> (for [x foo-with-stuff] >> (inc x))) > > This use case of the macro now renamed as-> in Clojure 1.5 is already > covered by using fn in a pipeline: > > (-> foo > (stuff) > (blah) > ((fn [foo-with-stuff] > (for [x foo-with-stuff] > (inc x))))) > > A benefit of using fn here is that it also works with ->> just the > same. However, there is a place for a construct to simplify multiple > uses of fn in a pipeline like in: > > (-> foo > (stuff) > (blah) > ((fn [foo] > (for [x foo] > (inc x)))) > ((fn [foo] > (for [x foo] > (dec x))))) > > I propose fn-> as name for a construct similar to as-> used like this: > > (-> foo > (stuff) > (blah) > ((fn-> [foo] > (for [x foo] > (inc x)) > (for [x foo] > (dec x))))) > > The fn-> macro defines an anonymous function using the same syntax as > fn, with its forms threaded like in as-> where each evaluated form is > bound to a symbol. > > In the example above, the result of the first 'for' form is bound to > the 'foo' used by the second 'for' form. That is, within fn-> the > items in the list bound to foo is first incremented and the resulting > list bound to foo, then the items in the list bound to foo is > decremented with the resulting list returned (incidentally leaving the > list as before). > > Keeping the syntax and semantics of fn-> similar to fn provides an > smooth upgrade path from current uses of fn in pipelines. > > -- Terje Norderhaug > >> On Thursday, November 15, 2012 10:35:59 AM UTC-8, Alex Nixon wrote: >>> >>> Hi all, >>> >>> I find the proposed function let-> in Clojure 1.5 very useful, but a bit >>> ugly. The arguments are backwards when compared to vanilla let, and it >>> doesn't support destructuring where it easily could (which I believe would >>> be helpful when threading 'state-like' maps, as I find let-> very useful >>> for). >>> >>> I'd like to float an alternative implementation which improves on both >>> these issues. Thoughts? >>> >>> (defmacro new-let-> >>> "Establishes bindings as provided for let, evaluates the first form >>> in the lexical context of that binding, then re-establishes bindings >>> to that result, repeating for each successive form" >>> [bindings & forms] >>> (assert (vector? bindings) "binding must be a vector") >>> (assert (= 2 (count bindings)) "binding vector must contain exactly two >>> forms") >>> `(let [~@bindings >>> ~@(interleave (repeat (bindings 0)) (drop-last forms))] >>> ~(last forms))) >>> >>> (new-let-> [{:keys [foo bar] :as state} {:foo 1 :bar 2}] >>> (assoc state :foo (inc bar)) >>> (assoc state :bar (inc foo))) ; => {:foo 3, :bar 4} >>> >>> -- >>> Alex Nixon >>> >>> Software Engineer | SwiftKey >>> >>> al...@swiftkey.net | http://www.swiftkey.net/ -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en