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.

Reply via email to