zcfrank1st
zcfrank1st

Reputation: 523

How does the following clojure code run?

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

Answers (2)

Arthur Ulfeldt
Arthur Ulfeldt

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

Thumbnail
Thumbnail

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

Related Questions