Reputation: 523
I read the doc about condp
from clojuredoc. And in the doc I found the following code:
(condp some [1 2 3 4]
#{0 6 7} :>> inc
#{4 5 9} :>> dec
#{1 2 3} :>> #(+ % 3))
The result of the above code is 3. But I don't understand why.
If someone could help me figure it out ? Tell me how does the code run.
Thank you~
Upvotes: 2
Views: 78
Reputation: 91607
Sure let's start with a simpler case:
user> (condp some [1 2 3 4]
#{5} :>> inc
:the-default-value)
:the-default-value
Builds this test:
user> (some #{5} [1 2 3 4])
nil
Because the test returns something falsy (nil is falsy) it skips this clause and returns the default value at the end because there are no more clauses to check.
If we use a test that passes
user> (condp some [1 2 3 4] #{1} :>> inc :the-default-value)
2
It builds the test:
user> (some #{1} [1 2 3 4])
1
Which results in something truthy (1) so the search stops and this clause is accepted. The :>>
tells condp to take the result of the test and pass it to the function that follows, in this case inc
. Resulting in 2
So in the original example the first test is:
(some #{0 6 7} [1 2 3 4])
Which is nil
so this case is not accepted and the search continues. The second test is:
user> (some #{4 5 9} [1 2 3 4])
4
Which results in the truthy value 4, so it calls the provided function dec
on the value 4:
user> (dec 4)
3
and the search stops.
Upvotes: 8
Reputation: 13483
In this example, condp
tries the predicate some
on each test expression in turn, with [1 2 3 4]
as the second argument.
(some #{0 6 7} [1 2 3 4])
fails, returning nil
.(some #{4 5 9} [1 2 3 4])
succeeds, returning 4
.condp
then returns the result of applying the function corresponding to the succeeding test expression, in this case dec
, to the test value 4
.
Upvotes: 5