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.