let's start clojure!

# with 4 step
1. sudo docker run -it --name brave -v pathOnHost:pathOnContainer -d clojure tail -f /dev/null
2. sudo docker exec -it brave /bin/bash
3. lein repl (in the container terminal)

enjoy! :smile: 
Start learning from a awesome and free online book.　
http://www.braveclojure.com/getting-started

# Control Flow
## if
```clj
(if boolean-form
    then-form
    optional-else-form)
```
If you omit the _else_ branch and the Boolean expression is _false_, Clojure returns _nil_.
## do
The **do** operator lets you **wrap up multiple forms** in parentheses and run each of them.

```clj
(if true
  (do (println "Success!")
      "By Zeus's hammer!")
  (do (println "Failure!")
      "By Aquaman's trident!"))
```
##when
is like a **combination of if and do**, but without else branch.

```clj
(when boolean-form
    then-form1
    then-form2)
```
If condition is true, the _then-form1_ and _then-form2_ will run. 
If condition is false, nothing will run and return nil.

##nil, true false
Both **nil** and **false** are used to represent logical falsiness, whereas all other values are logically truthy.

##equality

```clj
(= 1 1)
(= nil nil)
```
##Boolean operators **and** and **or**
_or_  returns either the first truthy value or the last value.
_and_ returns either the first falsy  value or the last value.

##def
Best practice: you should treat **def** as if it's defining constants.

##Hash map
create hash maps

```clj
{:key1 "x" :key2 "y"}
(hash-map :key1 "x" :key2 "y")
```

## Get value from map

```clj
(get {:key1 "x" :key2 "y"} :key1)
(get {:key1 "x" :key2 "y"} :key3)
(get {:key1 "x" :key2 "y"} :key3 "default") ;with default value
({:key1 "x" :key2 "y"} :key3 (throw (Exception. "my exception message")))
(get-in {:a 0 :b {:c "ho hum"}} [:b :c]) ;get nested value
({:key1 "x" :key2 "y"} :key1) ; treat the map like a function
(:key1 {:key1 "x" :key2 "y"}) ; treat keyword like a function
```

##Vector
is similar to an Array.

```clj
[ 1 2 3 ]
(vector 1 2 3)
(get [3 2 1] 1) ; get the second element
(get [3 2 1] 4) ; return nil
(nth [3 2 1] 4) ; throw IndexOutOfBoundsException
(conj [1 2 3] 4) ; 4 is added to the end of a vector
```
##List


```clj
'(1 2 3 4)
(list 1 "two" {3 4})
(nth '(1 2 3 4) 3)
(get '(1 2 3 4) 3) ; this will return nil, never use get with list!!
(conj '(1 2 3 4) 5) ; 5 is added to the beginning of a list
```

##Set
```clj
#{1 2 3 3 3}
(hash-set 1 1 2 2)
(set [1 3 3]) ; create sets from vectors and lists
(set '(1 2 3))
(contains? #{:a :b} :b) ; return true or false
(:a #{:a :b}) ; get itself or nil
(get #{:a :b} nil)
(get #{:a nil} nil)
```
 **Do not use contains? to lists and vectors.** [see the doc](https://clojuredocs.org/clojure.core/contains_q)

##function call
_clojure evaluates all function arguments recursively before passing them to the function_.

##special forms(definitions and _if_ expressions)
_they don't always evaluate all of their operands_.

##define function(arity overloading)

```clj
(defn x-chop
  "Describe the kind of chop you're inflicting on someone"
  ([name chop-type]
     (str "I " chop-type " chop " name "! Take that!"))
  ([name]
     (x-chop name "karate")))
```

##variable-arity functions

```clj
(defn favorite-things
  [name & things]
  (str "Hi, " name ", here are my favorite things: "
       (clojure.string/join ", " things)))

(favorite-things "Doreen" "gum" "shoes" "kara-te")
```

##destructing(vector,list)

```clj
(defn my-first
[[first]]
first)

(my-first ["x" "2"])

(defn my-rest
[[first & rest]]
rest)

(my-first ["x" "2"])
```

##destructing(map)

```clj
(defn xxxx
[{lat :lat lng :lng}]
(println lat)
(println lng))

(defn xxxx
[{:keys[lat lng] :as location}]
(println lat)
(println lng))

(xxxx {:lat 32 :lng 45})
```

##Anonymous Functions
```clj
(fn [x y]
(+ x y))

#(+ %1 %2) ; %1 or % is the first argument
           ; %2 is the second argument, and so on.
           ; %& is the rest arguments

```

##let (_let it be_)
**let** will introduce a new scope.

```clj
(def x 0)
(let [x (inc x)] x) ; return 1
x ; return 0, not changed
```
main uses: 1.name things
           2.evaluate an expression only once and reuse the result.
             (like a network API call, the expression has side effects)

```clj
(let [[part & remaining] remaining-asym-parts]
  (recur remaining
         (into final-body-parts
               (set [part (matching-part part)]))))
```  

## loop


```clj
(loop [iteration 0]
  (println (str "Iteration " iteration))
  (if (> iteration 3)
    (println "Goodbye!")
    (recur (inc iteration))))
```

## Regular expressions

```clj
#"regular-expression"
(re-find #"^left-" "left-eye")
(clojure.string/replace "left-eye" #"^left-" "right-")
```

## sequence abstraction
As long as a data structure(like **list, vector, set, map**) responds to the core sequence operations (the functions **first, rest, and cons**, which we’ll look at more closely in a moment), it will work with **map, reduce**, and oodles of other sequence functions for free. 
## convert to seq

```clj
(seq '(1 2 3))
; => (1 2 3)

(seq [1 2 3])
; => (1 2 3)

(seq #{1 2 3})
; => (1 2 3)

(seq {:name "Bill Compton" :occupation "Dead mopey guy"})
; => ([:name "Bill Compton"] [:occupation "Dead mopey guy"])
```

## convert the seq back into a map
```clj
(into {} (seq {:a 1 :b 2 :c 3})); 
```
## map function
```clj
(map inc [1 2 3])
(map str ["a" "b" "c"] ["A" "B" "C"]) ; => ("aA" "bB" "cC")
(map #(% 12) [inc #(+ % 2)  #(+ % 3)]) ; functions is data!
```
## reduce function
```clj
(reduce (fn [new-map [key val]]
          (assoc new-map key (inc val)))
        {}
        {:max 30 :min 10})
; => {:max 31, :min 11}
```

# take drop take-while drop-while filter
take: take the first n elements of the sequence
drop: return the sequence with the first n elements removed
take-while: take until the predicate function is false
drop-while: drop until the predicate function is false, and return remained.
filter: return all elements that test true for a predicate function.
some: return the first truthy value returned by a predicate function.

```clj
(take 3 [1 2 3 4 5 6 7 8 9 10])
; => (1 2 3)

(drop 3 [1 2 3 4 5 6 7 8 9 10])
; => (4 5 6 7 8 9 10)
(take-while #(< (:month %) 3) food-journal)
(drop-while #(< (:month %) 3) food-journal)

(some #(> (:critter %) 3) food-journal) ; => true
(some #(and (> (:critter %) 3) %) food-journal); => {:month 3 :day 1 :human 4.2 :critter 3.3}
```

## sort sort-by

```clj
(sort [3 1 2])
(sort-by count ["aaa" "c" "bb"])
```

## concat
concat simply appends the members of one sequence to the end of another

```clj
(concat [1 2] [3 4])
```

## lazy Seqs
* A lazy seq is a seq whose members aren’t computed until you try to access them. Computing a seq’s members is called realizing the seq. 
* A lazy seq as consisting of two parts: a recipe for how to realize the elements of a sequence and the elements that have been realized so far. 

```clj
(defn heavy-compute
  [x]
  (Thread/sleep 1000)
  (inc x))
(def result (map heavy-compute (range 1 1000)))
(time (first result)) ; "Elapsed time: 32004.460656 msecs"
```
## infinite Sequences
```clj
(take 8 (repeat "na"))
(take 3 (repeatedly (fn [] (rand-int 10))))
(defn even-numbers
  ([] (even-numbers 0))
  ([n] (cons n (lazy-seq (even-numbers (+ n 2))))))
(defn even-numbers
  ([] (even-numbers 0))
  ([n] (lazy-seq (cons n (even-numbers (+ n 2))))))
```

## Collection Abstraction
The sequence abstraction is about operating on members individually, whereas the collection abstraction is about the data structure as a whole. For example, the collection functions **count, empty?, and every?** aren’t about any individual element; they’re about the whole:

### into
* Adding all the *elements* from the second to the first.
* As you now know, many seq functions return a seq rather than the original data structure. You’ll probably want to convert the return value back into the original value, and into lets you do that:

```clj
(map identity {:sunlight-reaction "Glitter!"})
; => ([:sunlight-reaction "Glitter!"])

(into {} (map identity {:sunlight-reaction "Glitter!"}))
; => {:sunlight-reaction "Glitter!"}

(map identity [:garlic :sesame-oil :fried-eggs])
; => (:garlic :sesame-oil :fried-eggs)

(into [] (map identity [:garlic :sesame-oil :fried-eggs]))
; => [:garlic :sesame-oil :fried-eggs]
```

###conj
```clj
(conj [0] [1]) ; => [0 [1]]
(into [0] [1]) ; => [0 1]
(conj [0] 1) ; => [0 1]

(conj [0] 1 2 3 4) ; => [0 1 2 3 4]
(conj {:time "midnight"} [:place "ye olde cemetarium"]) ; => {:place "ye olde cemetarium" :time "midnight"}

(defn my-conj
  [target & additions]
  (into target additions)) ; define conj in terms of into
```

## apply
apply explodes a seqable data structure so it can be passed to a function that expects a rest parameter. 

```clj
(max 0 1 2)
(apply max [0 1 2])
```

## partial
partial takes a function and any number of arguments. It then returns a new function. 
```clj
(def add10 (partial + 10))
(add10 3)

(defn my-partial
  [partialized-fn & args]
  (fn [& more-args]
    (apply partialized-fn (into args more-args))))
```

## complement
Takes a fn f and returns a fn that takes the same arguments as f,
has the same effects, if any, and returns the opposite truth value.

```clj
(def not-empty? (complement empty?))
```
## Pure Functions
A function is pure if it meets two qualifications:

* It always returns the same result if given the same arguments. This is called referential transparency.
* It can’t cause any side effects. That is, the function can’t make any changes that are observable outside the function itself—for example, by changing an externally accessible mutable object or writing to a file.

## comp
Composing functions is so common that Clojure provides a function, comp, for creating a new function from the composition of any number of functions. 
using comp on the functions f1, f2, ... fn, creates a new function g such that g(x1, x2, ... xn) equals f1( f2( fn(x1, x2, ... xn))). One detail to note here is that the first function applied—* in the code shown here—can take any number of arguments, **whereas the remaining functions must be able to take only one argument**.

```clj
((comp inc *) 2 3)

(def character
  {:name "Smooches McCutes"
   :attributes {:intelligence 10
                :strength 4
                :dexterity 5}})
(def c-int (comp :intelligence :attributes))
```

## memoize
Another cool thing you can do with **pure functions** is memoize them so that Clojure remembers the result of a particular function call.

## exclude **var** in cljs.core
```
(ns hello.core
    (:refer-clojure :exclude [map]))
```