Created
September 4, 2013 13:15
-
-
Save anonymous/6436768 to your computer and use it in GitHub Desktop.
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
;; 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