Clojure: Partial Function (Currying)
partial is for creating a new function with a pre-filled argument(s) of a given function.
partial is a function that decompose a function by pre-fill n count its parameters. It returns a function g. When g is called with no arguments, it is equivalent to calling ƒ with n args. When g is given args, they are feed to ƒ starting with the unfilled args.
Let's use math notation here.
Suppose you have a function ƒ that takes 3 args. You have:
ƒ[x, y, z]
when you call
it returns a function, let's call it g.
When g is invoked
is equivalent to
All together, it's this:
(partial[ƒ,a]) = ƒ[a]
if g is given args, it is feed to ƒ, starting with ƒ's second arg. That is,
(partial[ƒ,a]) = ƒ[a] (partial[ƒ,a])[b] = ƒ[a,b] (partial[ƒ,a])[b,c] = ƒ[a,b,c]
partial is given more args, it consumes more args from ƒ.
(partial[ƒ,a,b]) = ƒ[a,b] (partial[ƒ,a,b])[x1] = ƒ[a,b,x1] (partial[ƒ,a,b])[x1,x2] = ƒ[a,b,x1,x2]
Let's use Clojure for example.
Suppose your function f[a,b,c] takes 3 args.
(defn f "join one or more strings" [& args] (apply str args)) (f "a" "b" "c") ; ⇒ "a b c" ;; define g. To be partial of f, feeding it 3 as first arg (def g (partial f "3")) (g) ; ⇒ "3" (g "4") ; ⇒ "34"
(comp f g)
(comp f g & fs)
Takes a set of functions and returns a fn that is the composition of those fns. The returned fn takes a variable number of args, applies the rightmost of fns to the args, the next fn (right-to-left) to the result, etc.
;; example of compose (defn f1 "append 1 to string x" [x] (str x "1")) (defn f2 "append 2 to string x" [x] (str x "2")) (defn f3 "append 3 to string x" [x] (str x "3")) (f1 "a") ; "a1" (def g (comp f3 f2 f1 )) (g "x") ; "x123" (g "a" "x") ;; 1. Unhandled clojure.lang.ArityException ;; Wrong number of args (2) passed to: user/f1 ;; because f1 only takes 1 arg
(apply f args)
(apply f x args)
(apply f x y args)
(apply f x y z args)
(apply f a b c d & args)
Applies fn f to the argument list formed by prepending intervening arguments to args.
;; example of apply ;; apply just takes all of its args, and feed to the function as multiple args, like unwrap the bracket (apply str ["a" "b"]) ; "ab" (apply str "1" ["a" "b"]) ; "1ab" (apply str "1" "2" ["a" "b"]) ; "12ab" ;; here's what str does ;; str takes 1 or more args of string, and return a joined string (str "a" "b") ; "ab" ;; can be just 1 arg (str "a" ) ; "a" ;; if arg is not a string, it's converted to string (str "a" ["a" "b"]) ; "a[\"a\" \"b\"]" (str "a" 1) ; "a1"
(trampoline f args) call f with args. If it returns a function, call it again (with no args). Repeat until it returns a value that is not a function, return that value. clojure.core/trampoline
(constantly x)→ Returns a function that takes any number of arguments and returns x. clojure.core/constantly
(complement f)→ Takes a fn f and returns a fn that takes the same arguments as f, has the same effects, if any, and returns the opposite truth value. clojure.core/complement
(memoize f)→ Returns a memoized version of a referentially transparent function. The memoized version of the function keeps a cache of the mapping from arguments to results and, when calls with the same arguments are repeated often, has higher performance at the expense of higher memory use.
Ask me question on patreon