Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to chain function calls in Clojure?

Tags:

clojure

Imagine I have a string which I want to transform as follows:

  1. Remove all spaces.
  2. Remove all dots.
  3. Make the string lower-case.

One way to do it is this:

(defn my-function
  [s]
  (let
      [
        clean-string1 (clojure.string/replace s " " "")
        clean-string2 (clojure.string/replace clean-string1 "." "")
        clean-string3 (clojure.string/lower-case clean-string2)
       ]
    ;; ...
    )
  )

How can I "chain" the functions clojure.string/replace and clojure.string/lower-case so that

  1. the output of (clojure.string/replace s " " "") is fed to the input of
  2. (clojure.string/replace clean-string1 "." "") and its output is fed to the input of
  3. (clojure.string/lower-case clean-string2)

so that I don't need intermediate variables clean-string1 and clean-string2?

like image 542
Dmitrii Pisarenko Avatar asked Jul 04 '26 05:07

Dmitrii Pisarenko


1 Answers

You just do it the same way you would in any language. You're asking for function composition, which in math or non-lisp languages looks like f(g(x)). In lisp of course that's (f (g x)), but the principle is the same.

(require '[clojure.string :as s])
(s/lower-case (s/replace (s/replace s " " "") "." ""))

is the most straightforward answer. But it's rather unpleasant to have this level of nesting where the function names are so far removed from their extra arguments, and so most people would instead write

(-> s
    (s/replace " " "")
    (s/replace "." "")
    (s/lower-case))

which is the same thing but just using -> to shuffle the forms around a bit for clarity.

like image 98
amalloy Avatar answered Jul 06 '26 12:07

amalloy



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!