Skip to content

Instantly share code, notes, and snippets.

@Eleonore9
Created November 5, 2015 16:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Eleonore9/961bda5b93fa4726eeb4 to your computer and use it in GitHub Desktop.
Save Eleonore9/961bda5b93fa4726eeb4 to your computer and use it in GitHub Desktop.
Clojure thoughts and tips
;; comp vs juxt
;; they both take in function(s) as arguments and associate then in a way
;; juxt (http://clojuredocs.org/clojure.core/juxt) returns a function that is a juxtaposition of other functions:
(map #((juxt name str/capitalize) %) [:name :location :unit]) ;;=> (["name" ":name"] ["location" ":location"] ["unit" ":unit"])
;; Let's have a pick at the source code:
(defn juxt
"Takes a set of functions and returns a fn that is the juxtaposition
of those fns. The returned fn takes a variable number of args, and
returns a vector containing the result of applying each fn to the
args (left-to-right).
((juxt a b c) x) => [(a x) (b x) (c x)]"
{:added "1.1"
:static true}
([f]
(fn
([] [(f)])
([x] [(f x)])
([x y] [(f x y)])
([x y z] [(f x y z)])
([x y z & args] [(apply f x y z args)])))
([f g]
(fn
([] [(f) (g)])
([x] [(f x) (g x)])
([x y] [(f x y) (g x y)])
([x y z] [(f x y z) (g x y z)])
([x y z & args] [(apply f x y z args) (apply g x y z args)])))
([f g h]
(fn
([] [(f) (g) (h)])
([x] [(f x) (g x) (h x)])
([x y] [(f x y) (g x y) (h x y)])
([x y z] [(f x y z) (g x y z) (h x y z)])
([x y z & args] [(apply f x y z args) (apply g x y z args) (apply h x y z args)])))
([f g h & fs]
(let [fs (list* f g h fs)]
(fn
([] (reduce1 #(conj %1 (%2)) [] fs))
([x] (reduce1 #(conj %1 (%2 x)) [] fs))
([x y] (reduce1 #(conj %1 (%2 x y)) [] fs))
([x y z] (reduce1 #(conj %1 (%2 x y z)) [] fs))
([x y z & args] (reduce1 #(conj %1 (apply %2 x y z args)) [] fs))))))
;; comp (https://clojuredocs.org/clojure.core/comp) returns a function that is a composition of other functions:
(map #((comp name str/capitalize) %) [:name :location :unit]) ;;=> (":name" ":location" ":unit")
;; The output is actually not what I wanted. I had to llok at the source code to understand:
(defn comp
"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."
{:added "1.0"
:static true}
([] identity)
([f] f)
([f g]
(fn
([] (f (g)))
([x] (f (g x)))
([x y] (f (g x y)))
([x y z] (f (g x y z)))
([x y z & args] (f (apply g x y z args)))))
([f g & fs]
(reduce1 comp (list* f g fs))))
;; -> the first function to be called is the furthest on the right. So I had to change my code:
(map #((comp str/capitalize name) %) [:name :location :unit]) ;;=> ("Name" "Location" "Unit")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment