By the way, the order of arguments of as-> makes more sense when it’s used 
*within* one of the other threading macros. For example:
(-> x
  foo
  (bar y)
  (baz w z)
  (as-> mid-x
    (log/debug "The intermediate value:" mid-x)
    (if (color-requested? mid-x)
      (assoc mid-x :color "periwinkle")
      (do
        (log/warn "skipping the addition of color")
        mid-x)))
  (update :counter inc))


On Wednesday, September 28, 2016 at 4:11:42 PM UTC-4, pa...@pwjw.com wrote:
>
> Wow yes that's exactly the -%> macro I imagined just with "%" replaced 
> with "it". And it exists!  Plus I just converted my fragment to use as-> 
> and thought "aren't the first two arguments backwards (vs, say, "let"); and 
> what name should I use (I chose 's')". Thank you. Reading the tupelo docs 
> now.
>
> On Wednesday, September 28, 2016 at 4:02:38 PM UTC-4, Alan Thompson wrote:
>>
>> Hi Paul,
>>
>> Since you are interested in the threading macros, you might like to take 
>> a look at one of my favorite variants from the Tupelo library 
>> <https://github.com/cloojure/tupelo#literate-threading-macro>:
>>
>> Literate Threading Macro
>>
>> We all love to use the threading macros -> and ->> for certain tasks, 
>> but they only work if all of the forms should be threaded into the first or 
>> last argument.
>>
>> The built-in threading macro as-> can avoid this requirement, but the 
>> order of the first expression and the placeholder symbol is arguably 
>> backwards from what users would expect. Also, there is often no obvious 
>> name to use for the placeholder symbol. Re-using a good idea from Groovy, 
>> we simply use the symbol it as the placeholder symbol in each expression 
>> to represent the value of the previous result.
>>
>> (it-> 1
>>       (inc it)                                  ; thread-first or thread-last
>>       (+ it 3)                                  ; thread-first
>>       (/ 10 it)                                 ; thread-last
>>       (str "We need to order " it " items." )   ; middle of 3 arguments;=> 
>> "We need to order 2 items." )
>>
>> Here is a more complicated example. Note that we can assign into a local 
>> let block from the it placeholder value:
>>
>> (it-> 3
>>       (spy :msg :initial it)
>>       (let [x it]
>>         (inc x))
>>       (spy it :msg 222)
>>       (* it 2)
>>       (spyx it)); :initial => 3; 222 => 4; it => 88           ; return value
>>
>> Note that the :msg argument does not need to be a string. As shown 
>> above, keywords, integers, etc may be used.
>> Alan
>>
>>
>> On Wed, Sep 28, 2016 at 11:36 AM, Colin Yates <colin...@gmail.com> wrote:
>>
>>> Welcome to one of the best things about Clojure - the community. 
>>> However, if anyone starts using the phrase 'Clojurian' then it is time to 
>>> leave :-).
>>>
>>>
>>>
>>> On Wed, 28 Sep 2016, at 07:17 PM, pa...@pwjw.com wrote:
>>>
>>> Wow thank you all for the really useful responses. How great. I 
>>> appreciate the time.
>>>
>>> as-> cleans up a couple of ugly bits of my code already, yes. And I'm 
>>> sort of irritated with myself for not thinking of _ (if (throw)) in my let 
>>> but yes that's a perfect idiom.
>>>
>>>
>>> I totally get the minimalist approach in clojure.test and like it. In 
>>> fact, the ease of testing (and how easy it is to get coverage running with 
>>> cloverage) is one of the things I find the most impressive. expectations 
>>> looks interesting though too for a lot of my tests and I'll spend some time 
>>> with it too.
>>>
>>> The idiom of "most important is first unless its a sequence then it is 
>>> last" is really natural too; but I think it's what makes me end up 
>>> switching from ->> to ->. Putting a "first" in the middle of a ->> 
>>> expression is, I suppose, a hint that I'm switching.  Looking at my code, 
>>> it really seems to be a mix of ->> and "doto" that I'm looking for. Here's 
>>> a fragment, for instance, that returns me an opened instance of the first 
>>> core midi device with a name that can receive messages. (and I know I 
>>> should error check that there is one after that filter... that's on my todo 
>>> list). An "as-> doto" pair would help and I'll get right on that later on 
>>> this week.
>>>
>>> (->> (MidiSystem/getMidiDeviceInfo)
>>>
>>>         (filter #(= (.getName ^MidiDevice$Info %) name))
>>>
>>>         (map #(MidiSystem/getMidiDevice ^MidDevice$Info %))
>>>
>>>         (filter #(>= (.getMaxTransmitters ^MidiDevice %) 0))
>>>
>>>         first
>>>
>>>         (#(do (.open ^MidiDevice %) %))
>>>
>>>         (#(.getReceiver ^MidiDevice %))
>>>
>>>         )
>>>
>>> Anyway, wow thanks again for all the responses!
>>>
>>>
>>>
>>>
>>>
>>> On Wednesday, September 28, 2016 at 10:31:37 AM UTC-4, pa...@pwjw.com 
>>> wrote:
>>>
>>> Hi.
>>>
>>> I'm new to clojure, and it is quite lovely. The threading model is 
>>> great, the emacs integration is super, and the tasteful lisp extensions are 
>>> good. A very nice programming environment all around. 
>>>
>>> But as I write more code I find a couple of structures I'm using a lot 
>>> which seem related to me not knowing idioms for a couple of uses cases. So 
>>> thought I'd ask and see if you have any suggestions. 
>>>
>>> Apologies if this is covered elsewhere. And if I should read some 
>>> existing documentation I didn't find, I apologize for missing it. And 
>>> thanks in advance for your time reading!
>>>
>>> First the thrush operators (-> and ->>) are super handy. But I find 
>>> myself needing to 'move' arguments every now and then. So I get code which 
>>> looks like
>>>
>>> (->> blah
>>>      (do-this)
>>>      (do-that arg)
>>>      ((fn [s] (rearrange arg s arg))))
>>>
>>> quite a lot.The alternate is a big nested let like
>>>
>>>  (let  [ first   (blah)
>>>           second  (do-this first)
>>>           ...
>>>           result  (wrap-it-up fourteenth) ]
>>>     result)
>>>
>>> for sort of sequential application where arguments fall in different 
>>> 'spots'. So I sort of find myself wanting to write a 'positional-thrush' 
>>> macro like
>>>
>>> (-%> blah
>>>      (do-this %)
>>>      (do-that arg %)
>>>      (do-the-other a1 % a2))
>>>
>>> where % is replaced with the output of the prior. But no such operator 
>>> exists as far as I can see. So either I've had a good idea (which is 
>>> unlikely since I'm super new to the language) or there's some other idiom 
>>> you all use for this pattern which I've missed.
>>>
>>> The second is smaller, but is more a question. clojure.test seems to 
>>> only have 'is' so for things like equality I end up writing (is (= (...) 
>>> (...))) a lot. Or to test if an exception is thrown (is (thrown? ...)). 
>>> That's OK, but I'm wondering what led to that decision rather than having 
>>> is-eq and is-thrown and so on (considering the core language has shortcuts 
>>> like when and unless and if-not so the compound macros seem idiomatic).
>>>
>>> The last is sort of related to the first. Sometimes I'm assembling a 
>>> data structure in a set of operators and I write them with a let or a -> 
>>> and half way through I have an error condition I want to check. In a 
>>> mutable procedural language you would do something like
>>>
>>>   x = blah
>>>   y = bim
>>>   if (! (condition (y))) throw "y doesn't meet condition"
>>>   z = blob
>>>
>>> I don't see a good idiom for this. I have to split and nest lets for 
>>> instance
>>>
>>> (let [x (blah) y (bim) ]
>>>   (if (condition (y)) (throw ...)
>>>      (let [ z (blob) ] 
>>>       ))
>>>
>>> which seems a bit ugly.  I sort of want a let-with-test or a 
>>> thrush-with-test so something which looks like
>>>
>>> (-%?>  (init)
>>>      (operator-1 %)  (post-condition)
>>>      (operator-2 %)  (post-condition) )
>>>
>>> where if I don't have a post condition I could just use 'true'. Then 
>>> this expands to doing a quick '(if (not (postcondition 
>>> (intermedia-result)))) throw...)
>>>
>>> but that's a crazy thing to want. So curious how you all tackle this.
>>>
>>> Thank you all for your consideration. And apologies again if this is 
>>> covered elsewhere or I should have asked in a different forum.
>>>
>>> Best,
>>>
>>>   Paul
>>>
>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "Clojure" group.
>>> To post to this group, send email to clo...@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+u...@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+u...@googlegroups.com.
>>> 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 clo...@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+u...@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+u...@googlegroups.com.
>>> 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 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