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 > <javascript:>> 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 <javascript:> 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 >> <javascript:> >> 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 <javascript:> >> 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 <javascript:>. >> 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 >> <javascript:> >> 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 <javascript:> >> 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 <javascript:>. >> 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.