Skip to content

Instantly share code, notes, and snippets.

Created September 4, 2013 13:15
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/6436768 to your computer and use it in GitHub Desktop.
Save anonymous/6436768 to your computer and use it in GitHub Desktop.
;; Anything you type in here will be executed
;; immediately with the results shown on the
;; right.
;;
; Clojure uses maps to carry data around, instead of objects.
; So instead of creating a Name class, we might represent a name like so.
(def name {:first "Sean" :middle "Parker" :last "Brown"})
; It's common to use Clojure's keywords as keys in the map.
; One reason is that keywords are functions which take a map,
; look themselves up in it, and return the corresponding value.
; This seems to be the most commonly used way to pull data out of a map in Clojure, for whatever reason.
; (:first name) => "Sean"
; (:taco name) => nil
;;
; So if we wanted to write a function that took in a name and did some arbitrary stuff with it,
; we could do it like so.
(defn no-destructuring [name]
"""
Takes a name as a map with the keys :first, :middle and :last.
Prints the name in the form last, first and returns a vector
[first middle last].
"""
(let [first (:first name)
middle (:middle name)
last (:last name)]
(println (str last ", " first))
[first middle last]))
;(no-destructuring name) => ["Sean" "Parker" "Brown"]
;;
; However, since it's so common that we need to pick multiple pieces of
; data out of a map at the same time, Clojure provides destructuring as a
; shortcut.
;
; Here we've defined the same function using destructuring in the function
; argument list. This is a function which takes one argument. It's a map
; and it's expected to have the keys :first, :middle and :last. It will
; bind their values to the names first, middle and last.
(defn destructuring [{first :first middle :middle last :last}]
(println (str last ", " first))
[first middle last])
; This is shorter and once you're used to it, generally easier to read
; since it requires less scanning.
;(destructuring name) => ["Sean" "Parker" "Brown"]
;;
; Destructuring is its own mini-language inside of Clojure, so there are some
; other tricks. For instance, there's an even shorter version to write the
; above function using the :keys directive, which takes a vector of names. It
; assumes that there are keys that correspond to the names in the map it's trying
; to destructure, and binds to them.
(defn destructuring-shortcut [{:keys [first middle last]}]
(println (str last ", " first))
[first middle last])
; This seems to be the most commonly used form of destructuring, and I think it
; reads the cleanest.
;(destructuring-shortcut name) => ["Sean" "Parker" "Brown"]
;;
; There's more to destructuring, there are a several other directives that can be
; used for map destructuring, and it's also possible to destructure vectors. For
; instance:
(def point [5 5])
;;
; This says that print-point takes a single vector as an argument, and it binds
; whatever is in the first slot of the vector to x, and whatever is in the second
; slot of the vector to y
(defn print-point [[x y]]
(println (str "x: " x))
(println (str "y: " y)))
; In practice, this seems less useful, since you would never represent a point that way,
; you'd probably use a map.
(def point-as-mape {:x 5 :y 5})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment