The idea of the `it->` operator in the Tupelo library <https://github.com/cloojure/tupelo#literate-threading-macro> is basically just a combination of the explicitness of swiss arrows and the pronoun `it` from Groovy. Alan
On Fri, Sep 30, 2016 at 2:00 PM, Stephen Spalding <[email protected]> wrote: > The semantic of the swiss-arrows <https://github.com/rplevy/swiss-arrows> > -<> macro are nice. It's like as-> except that the operator is > automatically specified as <>, and it has a default position. > > Your original example would become: > > (-<> blah > (do-this) > (do-that arg) > (do-the-other a1 <> a2)) > > The combination of a pre-specified operator and a default position makes > it so handy that I often wish there were a built-in equivalent. > > On Wednesday, September 28, 2016 at 6:10:05 PM UTC-4, [email protected] > wrote: >> >> 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]> 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] on behalf of >>> [email protected]" <[email protected] on behalf of [email protected]> >>> 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. > -- 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.
