All very interesting, and Sean that first/or threading pattern is very 
helpful.

@puzzler - totally get that the language is extensible yup and appreciate 
the mainstream warning. When I read your cond-better version I got it; and 
I also thought "a return statement like thing could be useful in a 
construct something like this" and then remembered just how far the macro 
system in lisps lets you go, which was really instructive.

The patterns here are very useful. Thanks again to all of you who offered 
up tips so far.

On Wednesday, September 28, 2016 at 5:53:10 PM UTC-4, Sean Corfield wrote:
>
> Ooops, should be: 
>
>     (defn has-transmitters 
>       [^MidiDevice device] 
>       (<= 0 (.getMaxTransmitters device))) 
>
> And if we made a helper for open-device, we could make it return the 
> now-open device and then you wouldn’t need the doto – just call 
> (open-device). 
>
> Sean Corfield -- (970) FOR-SEAN -- (904) 302-SEAN 
> An Architect's View -- http://corfield.org/ 
>
> "If you're not annoying somebody, you're not really alive." 
> -- Margaret Atwood 
>
> On 9/28/16, 2:48 PM, "Sean Corfield" <[email protected] <javascript:>> 
> wrote: 
>
>     And for comparison, here’s a threaded version that uses -> (with ->> 
> embedded, and doto): 
>     
>       (-> (MidiSystem/getMidiDeviceInfo) 
>           (->> (filter #(= (.getName ^MidiDevice$Info %) name)) 
>                (map #(MidiSystem/getMidiDevice ^MidDevice$Info %)) 
>                (filter #(>= (.getMaxTransmitters ^MidiDevice %) 0))) 
>           (first) 
>           (or (throw (ex-info "No midi devices with recievers" {:name 
> name}))) 
>           (doto (.open)) 
>           (.getReceiver)) 
>     
>     Note that I replaced the empty? check by just calling first followed 
> by or/throw. Calling first on an empty sequence produces nil and (or x 
> (throw …)) will yield x if it is not nil (else throw the exception). 
>     
>     Also note that you lose the type hints here which may affect 
> performance and/or method resolution (if the calls are ambiguous without 
> the type hints). 
>     
>     If the code isn’t performance critical and the calls are still 
> resolvable without type hint, I’d probably omit them just to make the code 
> cleaner. If the hints are needed, then I’d probably defn helpers for the 
> interop calls (with type hinted arguments) to make the code cleaner: 
>     
>       (-> (MidiSystem/getMidiDeviceInfo) 
>           (->> (filter #(= (get-device-name %) name)) 
>                (map get-midi-device) 
>                (filter #(>= (get-max-transmitters %) 0))) 
>           (first) 
>           (or (throw (ex-info "No midi devices with recievers" {:name 
> name}))) 
>           (doto (open-device)) 
>           (get-receiver)) 
>     
>     I’d probably make predicates for the two filter calls: 
>     
>     (defn matches-device-name 
>       [name] 
>       (fn [^MidiDevice$Info info] 
>         (= name (.getName info)))) 
>     
>     (defn has-transmitters 
>       [^MidiDevice$Info info] 
>       (<= 0 (.getMaxTransmitters info))) 
>     
>       (-> (MidiSystem/getMidiDeviceInfo) 
>           (->> (filter (matches-device-name name)) 
>                (map get-midi-device) 
>                (filter has-transmitters)) 
>           (first) 
>           (or (throw (ex-info "No midi devices with recievers" {:name 
> name}))) 
>           (doto (open-device)) 
>           (get-receiver)) 
>     
>     Sean Corfield -- (970) FOR-SEAN -- (904) 302-SEAN 
>     An Architect's View -- http://corfield.org/ 
>     
>     "If you're not annoying somebody, you're not really alive." 
>     -- Margaret Atwood 
>     
>     On 9/28/16, 2:12 PM, "[email protected] <javascript:> on behalf 
> of [email protected] <javascript:>" <[email protected] <javascript:> 
> on behalf of [email protected] <javascript:>> wrote: 
>     
>     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. 
>     
>     
>     
>     
>     
>
>
>

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

Reply via email to