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.

Reply via email to