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" <s...@corfield.org> 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, "clojure@googlegroups.com on behalf of p...@pwjw.com" <clojure@googlegroups.com on behalf of p...@pwjw.com> 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 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.