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 ([email protected]) 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 [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
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 [email protected].
For more options, visit https://groups.google.com/groups/opt_out.