cond->: Using of threading expression in tests?

144 views
Skip to first unread message

ru

unread,
Oct 2, 2015, 10:49:28 AM10/2/15
to Clojure
Hi,

Can I use in tests threading expression of cond->, and how?

Thanx in advance,
  Ru

Colin Yates

unread,
Oct 2, 2015, 10:55:21 AM10/2/15
to clo...@googlegroups.com
Hi Ru - I am not sure I understand the question - can you expand on the use-case a bit please.
--
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.

ru

unread,
Oct 2, 2015, 11:07:13 AM10/2/15
to Clojure
Hi, Colin

For example, (cond-> {:x 5} (> (get ??? :x) 3) (assoc :y 6))

пятница, 2 октября 2015 г., 17:49:28 UTC+3 пользователь ru написал:

Colin Yates

unread,
Oct 2, 2015, 11:09:47 AM10/2/15
to clo...@googlegroups.com
Ah I see - maybe https://clojuredocs.org/clojure.core/as-%3E will help (untried):

  (cond-> {:x 5} (as-> x1 (> (get x1 :x) 3)…)


ru

unread,
Oct 2, 2015, 11:33:55 AM10/2/15
to Clojure
Thank you, Colin.

This works:

user=> (as-> {:x 5} x1 (if (> (get x1 :x) 3) (assoc x1 :y 6) x1) (if (<= (get x1 :x) 3) (assoc x1 :y 12) x1))
{:y 6, :x 5}

But without cond-> at all :( :)

пятница, 2 октября 2015 г., 17:49:28 UTC+3 пользователь ru написал:
Hi,

Colin Yates

unread,
Oct 2, 2015, 12:00:20 PM10/2/15
to clo...@googlegroups.com
Alternatively you can do (cond-> {:x 1} (fn [x] (= (:x x) 1)) (assoc :x 2))

ru

unread,
Oct 2, 2015, 12:31:25 PM10/2/15
to Clojure
This is remarkable improvement and it shows that test is a function of the threading expression.

user=> (cond-> {:x 1} #(= (:x %) 1) (assoc :y 2))
{:y 2, :x 1}

also works.

Thanks a lot

пятница, 2 октября 2015 г., 17:49:28 UTC+3 пользователь ru написал:
Hi,

Jason Felice

unread,
Oct 2, 2015, 1:23:47 PM10/2/15
to clo...@googlegroups.com
This doesn't work, as (fn [x] (= (:x x) 1)) is never evaluated and the function itself is always truthy.  (Same for the #(= (:x %) 1) version).

Sean Corfield

unread,
Oct 2, 2015, 2:17:20 PM10/2/15
to clo...@googlegroups.com
We needed this functionality too and ended up writing our own utility macro:

(defmacro condp->
"Takes an expression and a set of predicate/form pairs. Threads expr (via ->)
through each form for which the corresponding predicate is true of expr.
Note that, unlike cond branching, condp-> threading does not short circuit
after the first true test expression."
[expr & clauses]
(assert (even? (count clauses)))
(let [g (gensym)
pstep (fn [[pred step]] `(if (~pred ~g) (-> ~g ~step) ~g))]
`(let [~g ~expr
~@(interleave (repeat g) (map pstep (partition 2 clauses)))]
~g)))

So (condp-> {:x 1} #(= (:x %) 1) (assoc :x 2)) produces {:x 2} as desired.

We have a condp->> version as well.

Sean Corfield -- (904) 302-SEAN
An Architect's View -- http://corfield.org/

"If you're not annoying somebody, you're not really alive."
-- Margaret Atwood

Colin Yates

unread,
Oct 2, 2015, 3:29:48 PM10/2/15
to clo...@googlegroups.com
Well I feel a numpty :-).

ru

unread,
Oct 3, 2015, 10:59:51 AM10/3/15
to Clojure
So am I! Sean, can you share code for condp->> too, please.


пятница, 2 октября 2015 г., 17:49:28 UTC+3 пользователь ru написал:
Hi,

Oliver Hine

unread,
Oct 3, 2015, 5:20:04 PM10/3/15
to Clojure
You may also find a use for condas-> which I describe in a mini blog post here: http://blog.juxt.pro/posts/condas.html

It combines cond-> and as-> which I find super useful when dealing with various fn type signatures.

Sean Corfield

unread,
Oct 4, 2015, 10:36:02 PM10/4/15
to clo...@googlegroups.com
So am I! Sean, can you share code for condp->> too, please.

Oh, sorry, I thought it was obvious from condp-> since the only difference is that it uses ->> instead of -> in one place:

(defmacro condp->>
  "Takes an expression and a set of predicate/form pairs. Threads expr (via ->>)
  through each form for which the corresponding predicate is true of expr.
  Note that, unlike cond branching, condp->> threading does not short circuit
  after the first true test expression."
  [expr & clauses]
  (assert (even? (count clauses)))
  (let [g (gensym)
        pstep (fn [[pred step]] `(if (~pred ~g) (->> ~g ~step) ~g))]
    `(let [~g ~expr
           ~@(interleave (repeat g) (map pstep (partition 2 clauses)))]
       ~g)))

Sean

ru

unread,
Oct 5, 2015, 9:50:47 AM10/5/15
to Clojure
Thank you very much, Sean and Oliver!

condas-> really awesome!


пятница, 2 октября 2015 г., 17:49:28 UTC+3 пользователь ru написал:
Hi,
Reply all
Reply to author
Forward
0 new messages