mirror of
https://github.com/adambard/learnxinyminutes-docs.git
synced 2024-12-23 17:41:41 +00:00
Updated clojure doc
This commit is contained in:
parent
e5d2150714
commit
34c86dc958
@ -2,7 +2,7 @@
|
|||||||
language: clojure
|
language: clojure
|
||||||
author: Adam Bard
|
author: Adam Bard
|
||||||
author_url: http://adambard.com/
|
author_url: http://adambard.com/
|
||||||
filename: test.clj
|
filename: learnclojure.clj
|
||||||
---
|
---
|
||||||
|
|
||||||
Clojure is a Lisp family language developed for the Java Virtual Machine. It has
|
Clojure is a Lisp family language developed for the Java Virtual Machine. It has
|
||||||
@ -24,9 +24,9 @@ and often automatically.
|
|||||||
;
|
;
|
||||||
; The clojure reader assumes that the first thing is a
|
; The clojure reader assumes that the first thing is a
|
||||||
; function or macro to call, and the rest are arguments.
|
; function or macro to call, and the rest are arguments.
|
||||||
;
|
|
||||||
; Here's a function that sets the current namespace:
|
; The first call in a file should be ns, to set the namespace
|
||||||
(ns test)
|
(ns learnclojure)
|
||||||
|
|
||||||
; More basic examples:
|
; More basic examples:
|
||||||
|
|
||||||
@ -71,6 +71,7 @@ and often automatically.
|
|||||||
; Collections & Sequences
|
; Collections & Sequences
|
||||||
;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
; Lists are linked-list data structures, while Vectors are array-backed.
|
||||||
; Vectors and Lists are java classes too!
|
; Vectors and Lists are java classes too!
|
||||||
(class [1 2 3]); => clojure.lang.PersistentVector
|
(class [1 2 3]); => clojure.lang.PersistentVector
|
||||||
(class '(1 2 3)); => clojure.lang.PersistentList
|
(class '(1 2 3)); => clojure.lang.PersistentList
|
||||||
@ -79,16 +80,18 @@ and often automatically.
|
|||||||
; it to stop the reader thinking it's a function.
|
; it to stop the reader thinking it's a function.
|
||||||
; Also, (list 1 2 3) is the same as '(1 2 3)
|
; Also, (list 1 2 3) is the same as '(1 2 3)
|
||||||
|
|
||||||
|
; "Collections" are just groups of data
|
||||||
; Both lists and vectors are collections:
|
; Both lists and vectors are collections:
|
||||||
(coll? '(1 2 3)) ; => true
|
(coll? '(1 2 3)) ; => true
|
||||||
(coll? [1 2 3]) ; => true
|
(coll? [1 2 3]) ; => true
|
||||||
|
|
||||||
|
; "Sequences" (seqs) are abstract descriptions of lists of data.
|
||||||
; Only lists are seqs.
|
; Only lists are seqs.
|
||||||
(seq? '(1 2 3)) ; => true
|
(seq? '(1 2 3)) ; => true
|
||||||
(seq? [1 2 3]) ; => false
|
(seq? [1 2 3]) ; => false
|
||||||
|
|
||||||
; Seqs are an interface for logical lists, which can be lazy.
|
; A seq need only provide an entry when it is accessed.
|
||||||
; "Lazy" means that a seq can define an infinite series, like so:
|
; So, seqs which can be lazy -- they can define infinite series:
|
||||||
(range 4) ; => (0 1 2 3)
|
(range 4) ; => (0 1 2 3)
|
||||||
(range) ; => (0 1 2 3 4 ...) (an infinite series)
|
(range) ; => (0 1 2 3 4 ...) (an infinite series)
|
||||||
(take 4 (range)) ; (0 1 2 3)
|
(take 4 (range)) ; (0 1 2 3)
|
||||||
@ -97,8 +100,8 @@ and often automatically.
|
|||||||
(cons 4 [1 2 3]) ; => (4 1 2 3)
|
(cons 4 [1 2 3]) ; => (4 1 2 3)
|
||||||
(cons 4 '(1 2 3)) ; => (4 1 2 3)
|
(cons 4 '(1 2 3)) ; => (4 1 2 3)
|
||||||
|
|
||||||
; Use conj to add an item to the beginning of a list,
|
; Conj will add an item to a collection in the most efficient way.
|
||||||
; or the end of a vector
|
; For lists, they insert at the beginning. For vectors, they insert at the end.
|
||||||
(conj [1 2 3] 4) ; => [1 2 3 4]
|
(conj [1 2 3] 4) ; => [1 2 3 4]
|
||||||
(conj '(1 2 3) 4) ; => (4 1 2 3)
|
(conj '(1 2 3) 4) ; => (4 1 2 3)
|
||||||
|
|
||||||
@ -168,20 +171,26 @@ x ; => 1
|
|||||||
; => "Hello Finn, you passed 3 extra args"
|
; => "Hello Finn, you passed 3 extra args"
|
||||||
|
|
||||||
|
|
||||||
; Hashmaps
|
; Maps
|
||||||
;;;;;;;;;;
|
;;;;;;;;;;
|
||||||
|
|
||||||
|
; Hash maps and array maps share an interface. Hash maps have faster lookups
|
||||||
|
; but don't retain key order.
|
||||||
(class {:a 1 :b 2 :c 3}) ; => clojure.lang.PersistentArrayMap
|
(class {:a 1 :b 2 :c 3}) ; => clojure.lang.PersistentArrayMap
|
||||||
|
(class (hash-map :a 1 :b 2 :c 3)) ; => clojure.lang.PersistentHashMap
|
||||||
|
|
||||||
|
; Arraymaps will automatically become hashmaps through most operations
|
||||||
|
; if they get big enough, so you don't need to worry.
|
||||||
|
|
||||||
|
; Maps can use any hashable type as a key, but usually keywords are best
|
||||||
; Keywords are like strings with some efficiency bonuses
|
; Keywords are like strings with some efficiency bonuses
|
||||||
(class :a) ; => clojure.lang.Keyword
|
(class :a) ; => clojure.lang.Keyword
|
||||||
|
|
||||||
; Maps can use any type as a key, but usually keywords are best
|
(def stringmap {"a" 1, "b" 2, "c" 3})
|
||||||
(def stringmap (hash-map "a" 1, "b" 2, "c" 3))
|
|
||||||
stringmap ; => {"a" 1, "b" 2, "c" 3}
|
stringmap ; => {"a" 1, "b" 2, "c" 3}
|
||||||
|
|
||||||
(def keymap (hash-map :a 1 :b 2 :c 3))
|
(def keymap {:a 1, :b 2, :c 3})
|
||||||
keymap ; => {:a 1, :c 3, :b 2} (order is not guaranteed)
|
keymap ; => {:a 1, :c 3, :b 2}
|
||||||
|
|
||||||
; By the way, commas are always treated as whitespace and do nothing.
|
; By the way, commas are always treated as whitespace and do nothing.
|
||||||
|
|
||||||
@ -200,7 +209,8 @@ keymap ; => {:a 1, :c 3, :b 2} (order is not guaranteed)
|
|||||||
(stringmap "d") ; => nil
|
(stringmap "d") ; => nil
|
||||||
|
|
||||||
; Use assoc to add new keys to hash-maps
|
; Use assoc to add new keys to hash-maps
|
||||||
(assoc keymap :d 4) ; => {:a 1, :b 2, :c 3, :d 4}
|
(def newkeymap (assoc keymap :d 4))
|
||||||
|
newkeymap ; => {:a 1, :b 2, :c 3, :d 4}
|
||||||
|
|
||||||
; But remember, clojure types are immutable!
|
; But remember, clojure types are immutable!
|
||||||
keymap ; => {:a 1, :b 2, :c 3}
|
keymap ; => {:a 1, :b 2, :c 3}
|
||||||
@ -271,6 +281,7 @@ keymap ; => {:a 1, :b 2, :c 3}
|
|||||||
(require 'clojure.string)
|
(require 'clojure.string)
|
||||||
|
|
||||||
; Use / to call functions from a module
|
; Use / to call functions from a module
|
||||||
|
; Here, the module is clojure.string and the function is blank?
|
||||||
(clojure.string/blank? "") ; => true
|
(clojure.string/blank? "") ; => true
|
||||||
|
|
||||||
; You can give a module a shorter name on import
|
; You can give a module a shorter name on import
|
||||||
@ -314,4 +325,56 @@ keymap ; => {:a 1, :b 2, :c 3}
|
|||||||
(doto (Calendar/getInstance)
|
(doto (Calendar/getInstance)
|
||||||
(.set 2000 1 1 0 0 0)
|
(.set 2000 1 1 0 0 0)
|
||||||
.getTime) ; => A Date. set to 2000-01-01 00:00:00
|
.getTime) ; => A Date. set to 2000-01-01 00:00:00
|
||||||
|
|
||||||
|
; STM
|
||||||
|
;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
; Software Transactional Memory is the mechanism clojure uses to handle
|
||||||
|
; persistent state. There are a few constructs in clojure that use this.
|
||||||
|
|
||||||
|
; An atom is the simplest. Pass it an initial value
|
||||||
|
(def my-atom (atom {}))
|
||||||
|
|
||||||
|
; Update an atom with swap!.
|
||||||
|
; swap! takes a function and calls it with the current value of the atom
|
||||||
|
; as the first argument, and any trailing arguments as the second
|
||||||
|
(swap! my-atom assoc :a 1) ; Sets my-atom to the result of (assoc {} :a 1)
|
||||||
|
(swap! my-atom assoc :b 2) ; Sets my-atom to the result of (assoc {:a 1} :b 2)
|
||||||
|
|
||||||
|
; Use '@' to dereference the atom and get the value
|
||||||
|
my-atom ;=> Atom<#...> (Returns the Atom object)
|
||||||
|
@my-atom ; => {:a 1 :b 2}
|
||||||
|
|
||||||
|
; Here's a simple counter using an atom
|
||||||
|
(def counter (atom 0))
|
||||||
|
(defn inc-counter []
|
||||||
|
(swap! counter inc))
|
||||||
|
|
||||||
|
(inc-counter)
|
||||||
|
(inc-counter)
|
||||||
|
(inc-counter)
|
||||||
|
(inc-counter)
|
||||||
|
(inc-counter)
|
||||||
|
|
||||||
|
@counter ; => 5
|
||||||
|
|
||||||
|
; Other STM constructs are refs and agents.
|
||||||
|
; Refs: http://clojure.org/refs
|
||||||
|
; Agents: http://clojure.org/agents
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Further Reading
|
||||||
|
|
||||||
|
This is far from exhaustive, but hopefully it's enought o get you on your feet.
|
||||||
|
|
||||||
|
Clojure.org has lots of articles:
|
||||||
|
[http://clojure.org/](http://clojure.org/)
|
||||||
|
|
||||||
|
Clojuredocs.org has documentation with examples for most core functions:
|
||||||
|
[http://clojuredocs.org/quickref/Clojure%20Core](http://clojuredocs.org/quickref/Clojure%20Core)
|
||||||
|
|
||||||
|
4Clojure is a great way to build your clojure/FP skills:
|
||||||
|
[http://www.4clojure.com/](http://www.4clojure.com/)
|
||||||
|
|
||||||
|
Clojure-doc.org (yeah, really) has a number of getting started articles:
|
||||||
|
[http://clojure-doc.org/](http://clojure-doc.org/)
|
||||||
|
Loading…
Reference in New Issue
Block a user