This is a super interesting thread. Thank you all for your input

I think you are right, @puzzler, that for my case a let may be better. The 
original code is above. Using as-> it looks like this (using 'it' as the 
name)

  (as-> (MidiSystem/getMidiDeviceInfo) it
     (filter #(= (.getName ^MidiDevice$Info %) name) it)
     (map #(MidiSystem/getMidiDevice ^MidDevice$Info %) it)
     (filter #(>= (.getMaxTransmitters ^MidiDevice %) 0) it)
     (if (empty? it) (throw (ex-info "No midi devices with recievers" 
{:name name})) it)
     (first it)
     (do (.open ^MidiDevice it) it)
     (.getReceiver ^MidiDevice it)
     )
   )

using let it looks like this

(let [device-info       (MidiSystem/getMidiDeviceInfo) 
         named-device-info (filter #(= (.getName ^MidiDevice$Info %) name) 
device-info)
         devices           (map #(MidiSystem/getMidiDevice ^MidDevice$Info 
%) named-device-info)
         receivables       (filter #(>= (.getMaxTransmitters ^MidiDevice %) 
0) devices)
         _                 (when (empty? receivables) (throw (ex-info "No 
midi devices with recievers" {:name name})))
         receivable        (first receivables)
         result            (do 
                             (.open ^MidiDevice receivable)
                             (.getReceiver ^MidiDevice receivable))]
     result)

and if I were doing a code review, I think I would like the last one better.

How very interesting. Thanks all for your constructive answers. What a 
great community.

On Wednesday, September 28, 2016 at 4:47:22 PM UTC-4, puzzler wrote:
>
> A common convention with as-> is to use the symbol $ because it is 
> recognized as a Clojure identifier but looks distinctive, so it stands out 
> as the placeholder of where to thread.
>
> Personally, when reading code, I don't really like to see long uses of the 
> threading operator, and I'd argue that if you find yourself using such long 
> chains of computations that the "important" argument is switching to 
> different positions, that's a sign that maybe you shouldn't be using 
> threading operators in the first place, because it can be hard to mentally 
> follow what intermediate data structure you have at each stage of the 
> computation.  Instead, I'd argue that you should be using `let`, because 
> `let` allows you to give each stage of computation a meaningful name, 
> making it easy for others (or yourself in two months) to read and reason 
> about your code.  `let` allows you to communicate intent.
>
> I think one reason people sometimes shy away from using `let` is that it 
> can't easily be used at all positions within one's code.  For example, if 
> you are inside a `cond`  doing some conditional logic, adding a `let` means 
> you have to also start a new `cond`, and your code ends up awkwardly nested 
> and indented, drifting to the right.   The better-cond library removes this 
> limitation, making it easy to write clear functions which intermingle long 
> chains of computations with conditional logic: 
> https://github.com/Engelberg/better-cond
>

-- 
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/d/optout.

Reply via email to