Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

clojure threading operator

Tags:

clojure

Lets say I want to use the threading operator to thread a map through a series of function calls. All the functions take the map as a first parameter (good) but one function does not conform to the correct signature (say it takes the map as the last parameter). What is the best way to "fix" the function signature?

like image 675
Kevin Avatar asked Oct 20 '11 14:10

Kevin


2 Answers

The reader macro #() for anonymus functions is a good candidate here:

(-> your-arg
  (fn1 arg2 arg3)
  (fn2 arg4 arg5)
  (#(fn3 arg6 arg7 %)) )

It is flexible and adds little visual noise. You can of course do many different things, in this case partial function application would also work:

(-> your-arg
  (fn1 arg2 arg3)
  ((partial fn2 arg4 arg5)))

There is also the ->> macro which threads the first expression into the last position. Of course in your use case this doesn't help much, as you would have to adjust some of the function calls. However if you are chaining many functions that should take the expression as the first argument and then many functions that take the expression as the last argument you could do something like

(->>
  (-> your-arg
    (fn1 arg2 arg3)
    (fn2 arg5 arg6))
  (fn3 arg7 arg8)
  (fn4 arg10 arg11))

EDIT: Added extra parenthesis in first example.

like image 117
Paul Avatar answered Sep 18 '22 19:09

Paul


I think people tend to underestimate the kind of threading operators available in clojure. So let me introduce you to as-> threading operator.

The as-> thread creates a variable which takes the value of the each function call in the threading steps. Example,

(as-> 2 x        ;; x = 2
      (+ 3 x)    ;; x = 5
      (- x 1)    ;; x = 4
      (/ x 2)    ;; x = 2
      (+ x x x)) ;; x = 6

The output of the above operation is x i.e. 6.

like image 26
Mrinal Saurabh Avatar answered Sep 19 '22 19:09

Mrinal Saurabh