Created
November 5, 2015 16:19
-
-
Save Eleonore9/961bda5b93fa4726eeb4 to your computer and use it in GitHub Desktop.
Clojure thoughts and tips
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; 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