Oh, and the implementation is clean and simple. Just cleaned it up a bit from all the clutter:
;;; The DUH..IT'S SO SIMPLE! macro (defmacro duh-> ([x alias form] `(let [~alias ~x] ~form)) ([x alias form & more] `(duh-> (duh-> ~x ~alias ~form) ~@more))) This gives YOU the full power of destructuring and threading through functions with ANY parameter order. Full `let` power! Why not use let then? True, the only difference is the restriction to a single thread of bindings, not allowing for mixing things up. As David Nolen points out below though, that is a HUGE benefit, the reason why all the threading macros exist. Beside that restriction, this fine macro above won't struggle to take away any of the `let` goodies, unlike ->, ->>, as->, or anything. I need a beer. On Friday, July 19, 2013 3:18:15 PM UTC+1, Daniel Dinnyes wrote: > > > > On Monday, July 15, 2013 11:53:09 PM UTC+1, Jeremy Heiler wrote: >> >> On July 15, 2013 at 6:30:28 PM, Daniel Dinnyes (dinn...@gmail.com) wrote: >> >> Hmm, good point, especially the `let` one... What is `as->`? I can't find >> anything about that. >> >> http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/as-%3E >> >> There is one benefit over `let` though: it is more explicit. Let allows >> you to define independent bindings mixed together with multiple threads of >> dependent bindings (which can be mixed in random combinations). As the >> number of bindings increase it becomes quite messy, and hard to decipher >> which line depends on which. I have seen, even written myself (shame on >> me), such code. I feel that this is the main reason for the `core` >> threading macros too ("why not use let instead?" would still apply then). >> On the other hand as my simple example code demonstrates (off the top of my >> hat, cuz ya need to show da code!), in a functional language the parameter >> order shouldn't matter, and there shouldn't be privileged (main!?) >> parameter positions (Clojure is the landguage of multimethods after all!) >> >> Your ->>> is a bit awkward because the symbol to the left represents the >> value of the previous expression, not the value of the following expression >> as is the case with most "bindings forms" in Clojure. Also, as-> simplifies >> your use case by only needing to identify one name that is used in all the >> threaded forms. Honestly, if I'm going to do anything more complicated that >> as->, I would rethink how I want to express my code. >> > You are trying to pick it up on the wrong end. Check this out: > > (-> "test-string-with-lots-of-dashes" > (fn [x] (s/split x #"-")) > (fn [y] (interleave y (range))) > (fn [z] (s/join #"_" z)) > (fn [z] (s/join " * " ["I am serious" z "Not Kidding!!" z]))) > > The above code is not valid, as the -> macro sees the function > declarations as lists, and tries to thread the argument through it. It is > quite intuitive though IMHO. Now with that in mind, check this baby once > more: > > (->>> "test-string-with-lots-of-dashes" > x (s/split x #"-") > y (interleave y (map count y)) > z (apply assoc {} z) > {:strs [test string with lots of dashes]} > (s/join " " ["test is" test ";" "string is" string ";" "with is" > with ";" "lots is" lots ";" "of is" of ";" "dashes is" dashes ";" "TOTAL:" > (+ test string with lots of dashes)])) > > > "test is 4 ; string is 6 ; with is 4 ; lots is 4 ; of is 2 ; dashes is 6 > ; TOTAL: 26" > > Yee-haw !!! > > Anyway, I see the reason for -> and ->> macros and indeed the first and >> last positions are special in some sense. The -> is good for navigating >> protocols, and ->> is good for functions expected/designed to be partially >> applied. Is that correct? >> >> The threading macros operate on the forms directly, so I'm not sure what >> you mean by "partially applied" here. The big win for ->> is that the >> sequence functions in Clojure core expect the sequence to be last. This is >> handy for threading a sequence through multiple transformations. >> > By partially applied I mean using the `partial` function on them to > partially apply all parameters except the last few. If a function can be > partially applied so that only the last parameter is not applied, where it > could accept the argument in question, then it would work well with ->> > macro. > > (let [myfun (partial apply assoc {})] > (->> ["test" "string" "with" "lots" "of" "dashes"] > myfun)) > > (->> ["test" "string" "with" "lots" "of" "dashes"] > (apply assoc {})) > > Hope that makes it clearer what I meant. > > Regards, > > Daniel > > -- -- 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 --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.