Skip to content

Instantly share code, notes, and snippets.

@SauloSilva
Last active May 30, 2016 04:33
Show Gist options
  • Save SauloSilva/081c1b94f395e473f6972cb98f4b3ca2 to your computer and use it in GitHub Desktop.
Save SauloSilva/081c1b94f395e473f6972cb98f4b3ca2 to your computer and use it in GitHub Desktop.
Clojure Get Started

listas

São simples

'(1 2 3)

Vetores

Melhores para trabalhar com indices

[1 2 3]

Mapas

Útil para armazenar dados e valores

{:foo 1 :bar 2}

Sets

Útil para armazenar dados não repetidos

#{1 2 3 4}

Variáveis

Globais

(def foo "bar")

Temporárias

(let [foo "whatever"] foo)

Funções

Anonimas

(fn [] (str "foo"))
(#(str "foo" %1 %2) "foo" "deu")

Funções Por Contexto

(defn foo [arg1 arg2] )

Namespace

create

(ns foo)

list

*ns*

Requires

Normal

(require 'foo')

With alias

(require '[namespace :as foo])

(ns foo
  (:require [namespace :as foo]))

Hello world

(ns wonderland
  (:require [clojure.set :as s]))

(defn common-fav-foods [foods1 foods2]
  (let [food-set1 (set foods1)
        food-set2 (set foods2)
        common-foods (s/intersection food-set1 food-set2)]
    (str "Common Foods: " common-foods)))

(common-fav-foods [:jam :brownies :toast]
                  [:lettuce :carrots :jam])

Test conditionals

Bollean

(= 1 2)
(not= 1 2)

(true? 'foo')
(false? 'foo')
(nil? 'foo')

Empty?

(empty? [])

Every?

(every? (fn [x] (= x :drinkme)) [:drinkme :drinkme])

(every? #(= % :drinkme) [:drinkme :drinkme])

Not-any?

(not-any? #(= % :drinkme) [:poison :poison])

Some?

(some #(> % 3) [1 2 3 4 5])

If

(if (= :drinkme :drinkme)
  "Try it"
  "Don't try it")

If-let

(if-let [need-to-grow-small (> 5 1)]
  "drink bottle"
  "don't drink bottle")

When

(defn drink [need-to-grow-small]
  (when need-to-grow-small "drink bottle"))

(drink true)

(drink false)

Cond

(let [bottle "mystery"]
  (cond
   (= bottle "poison") "don't touch"
   (= bottle "drinkme") "grow smaller"
   (= bottle "empty") "all gone"
   :else "unknown"))

Case

(let [bottle "drinkme"]
  (case bottle
   "poison" "don't touch"
   "drinkme" "grow smaller"
   "empty" "all gone"
   "default"))

Partial

(defn grow [name direction]
  (if (= direction :small)
    (str name " is growing smaller")
    (str name " is growing bigger")))

((partial grow "Alice") :small)

Compose

(defn toggle-grow [direction]
  (if (= direction :small) :big :small))

(defn oh-my [direction]
  (str "Oh My! You are growing " direction))

(oh-my (toggle-grow :small))

(defn surprise [direction]
  ((comp oh-my toggle-grow) direction))

(surprise :small)

Destructuring

With array

(let [[color size] ["blue" "small"]]
  (str "The " color " door is " size))

(let [[color [size] :as original] ["blue" ["small"]]]
  {:color color :size size :original original})

;; -> {:color "blue", :size "small", :original ["blue" ["small"]]}

With map

(let [{flower1 :flower1 flower2 :flower2}
  {:flower1 "red" :flower2 "blue"}]
  (str "The flowers are " flower1 " and " flower2))

(let [{flower1 :flower1 flower2 :flower2 :or {flower2 "missing"}}
      {:flower1 "red"}]
  (str "The flowers are " flower1 " and " flower2))

(let [{flower1 :flower1 :as all-flowers}
      {:flower1 "red"}]
  [flower1 all-flowers])

Shorthand with maps

(let [{:keys [flower1 flower2]}
      {:flower1 "red" :flower2 "blue"}]
  (str "The flowers are " flower1 " and " flower2))

with functions

(defn flower-colors [{:keys [flower1 flower2]}]
  (str "The flowers are " flower1 " and " flower2))

(flower-color {:flower1 'blue' :flower2 'red'})

Lazy sequences

(take 5 (range))
;; -> (0 1 2 3 4)

(repeat 3 "rabbit")
;; -> ("rabbit" "rabbit" "rabbit")

(take 5 (repeat "rabbit"))
;; -> ("rabbit" "rabbit" "rabbit" "rabbit" "rabbit")

(rand-int 10)
;; -> 3

(repeat 5 (rand-int 10))
;; -> (7 7 7 7 7)

(repeatedly 5 #(rand-int 10))
;; -> (1 5 8 4 3)

Recursion

(def adjs ["normal"
           "too small"
           "too big"
           "is swimming"])

(defn alice-is [in out]
  (if (empty? in)
    out
    (alice-is
     (rest in)
     (conj out
           (str "Alice is " (first in))))))

(alice-is adjs [])

(defn alice-is [input]
  (loop [in input
         out []]
    (if (empty? in)
      out
      (recur (rest in)
             (conj out
                   (str "Alice is " (first in)))))))

(alice-is adjs)

Recur

(defn countdown [n]
  (if (= n 0)
    n
    (recur (- n 1))))

(countdown 100000)

Map

(def animals
  ["mouse" "duck" "dodo" "lory" "eaglet"])

(def colors
  ["brown" "black" "blue" "pink" "gold"])

(defn gen-animal-string [animal color]
  (str color "-" animal))

(map gen-animal-string animals colors)

(map gen-animal-string animals (cycle ["brown" "black"]))

Reduce

(reduce (fn [r x] (if (nil? x) r (conj r x)))
        []
        [:mouse nil :duck nil nil :lory])

Shaping Expressions

Filter

(filter keyword? [:mouse nil :duck nil])

Remove

(remove nil? [:mouse nil :duck nil])

For

(for [animal [:mouse :duck :lory]
      color  [:red :blue]
      :let  [animal-str (str "animal-"(name animal))
             color-str (str "color-"(name color))
             display-str (str animal-str "-" color-str)]] display-str)

When

(for [animal [:mouse :duck :lory]
      color  [:red :blue]
      :let  [animal-str (str "animal-"(name animal))
             color-str (str "color-"(name color))
             display-str (str animal-str "-" color-str)]
      :when (= color :blue)]
  display-str)

Flatten

(flatten [ [:duck [:mouse] [[:lory]]]])

Vec and Into

(vec '(1 2 3))
;; -> [1 2 3]

(into [] '(1 2 3))
;; -> [1 2 3]

(sorted-map :b 2 :a 1 :z 3)
;; -> {:a 1, :b 2, :z 3}

(into (sorted-map) {:b 2 :c 3 :a 1})
;; -> {:a 1, :b 2, :c 3}

(into {} [[:a 1] [:b 2] [:c 3]])
;; -> {:a 1, :b 2, :c 3}

(into [] {:a 1, :b 2, :c 3})
;; -> [[:c 3] [:b 2] [:a 1]]

Partition

(partition 3 [1 2 3 4 5 6 7 8 9])
;; -> ((1 2 3) (4 5 6) (7 8 9))

(partition-all 3 [1 2 3 4 5 6 7 8 9 10])
;; -> ((1 2 3) (4 5 6) (7 8 9) (10))

(partition-by #(= 6 %) [1 2 3 4 5 6 7 8 9 10])
;; -> ((1 2 3 4 5) (6) (7 8 9 10))

Atom

(def who-atom (atom :caterpillar))

(defn change [state]
  (case state
    :caterpillar :chrysalis
    :chrysalis :butterfly
    :butterfly))

(swap! who-atom change)

@who-atom

Atom with async

(defn inc-print [val]
  (println val)
  (inc val))

(def counter (atom 0))

(let [n 2]
  (future (dotimes [_ n] (swap! counter inc-print)))
  (future (dotimes [_ n] (swap! counter inc-print)))
  (future (dotimes [_ n] (swap! counter inc-print))))

Refs

(def x (ref 1))  
(def y (ref 1))

(defn new-values []
  (dosync  
   (alter x inc) 
   (ref-set y  (+ 2 @x)))) 

(let [n 2]
  (future (dotimes [_ n] (new-values))) 
  (future (dotimes [_ n] (new-values))))

Agents

async with send

(def who-agent (agent :caterpillar))  

(defn change [state]  
  (case state
    :caterpillar :chrysalis
    :chrysalis :butterfly
    :butterfly))
    
(defn change-error [state]
  (throw (Exception. "Boom!")))
  
(defn err-handler-fn [a ex]
  (println "error " ex " value is " @a))  

(send who-agent change)
(send-off who-agent change)

(send who-agent change-error)
(restart-agent who-agent :caterpillar)

(send who-agent change-error)
(set-error-mode! who-agent :continue)
(set-error-handler! who-agent err-handler-fn)

Java Interop

caterpillar".toUpperCase();   (.toUpperCase "caterpillar")
new String("Hi!!");           (String. "Hi!!")
host.getHostName();           (.getHostName host)

Polymorphism

with defmulti

(defmulti who-are-you class)

(defmethod who-are-you java.lang.String [input]
  (str "String - who are you? " input))

(defmethod who-are-you clojure.lang.Keyword [input] 
  (str "Keyword - who are you? " input))

(defmethod who-are-you java.lang.Long [input] 
  (str "Number - who are you? " input))

(defmethod who-are-you :default [input]
  (str "I don't know - who are you? " input))

(who-are-you :alice) 
;; -> "Keyword - who are you? :alice"

(who-are-you "Alice") 
;; -> "String - who are you? Alice"

(who-are-you 123) 
;; -> "Number - who are you? 123"

(who-are-you true) 
(defmulti eat-mushroom (fn [height]
                          (if (< height 3)
                            :grow
                            :shrink)))

(defmethod eat-mushroom :grow [_]
  "Eat the right side to grow.")
  
(defmethod eat-mushroom :shrink [_]
  "Eat the left side to shrink.")

(eat-mushroom 1)
“;; -> "Eat the right side to grow.”

(eat-mushroom 9)
;; -> "Eat the left side to shrink.

with protocol

(defprotocol BigMushroom
  (eat-mushroom [this]))
  
(extend-protocol BigMushroom
  java.lang.String
  (eat-mushroom [this]
    (str (.toUpperCase this) " mmmm tasty!"))

  clojure.lang.Keyword
  (eat-mushroom [this]
    (case this
      :grow "Eat the right side!"
      :shrink "Eat the left side!"))

  java.lang.Long
    (eat-mushroom [this]
      (if (< this 3)
        "Eat the right side to grow"
        "Eat the left side to shrink")))

(eat-mushroom  "Big Mushroom")
;; -> "BIG MUSHROOM mmmm tasty!

(eat-mushroom :grow)
;; -> "Eat the right side!

(eat-mushroom 1)
;; -> "Eat the right side to grow

with defrecord

(defrecord Mushroom [color height])

(def regular-mushroom (Mushroom. "white and blue polka dots" "2 inches"))

(.-color regular-mushroom)
;; -> "white and blue polka dots"

(.-height regular-mushroom)
;; -> "2 inches
(defn hi-queen [phrase]
(str phrase ", so please your Majesty."))
(defmacro def-hi-queen [name phrase]
(list 'defn
(symbol name)
[]
(list 'hi-queen phrase)))
(def-hi-queen alice-hi-queen "My name is Alice")
(def-hi-queen march-hare-hi-queen "I'm the March Hare")
(def-hi-queen white-rabbit-hi-queen "I'm the White Rabbit")
(def-hi-queen mad-hatter-hi-queen "I'm the Mad Hatter")
(let [x 5]
`(first [~x 2 3]))
;; -> (clojure.core/first [5 2 3])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment