для Java разработчиков
Как говориться, нам нужно то, что делает решение простых задач легким, а сложных - возможным.
Чаз Эмирик
«Программирование на Clojure»
Роман Махлин
2016г.
и многие другие
Теперь мы подходим к решающему шагу в математической абстракции:
мы забываем, что обозначают наши символы.
Герман Вейль
«Математический способ мышления»
(defn fast-pow [a n]
(cond (zero? n) 1
(even? n) (letfn [(square [x] (*' x x))]
(square (fast-pow a (/ n 2))))
:else (*' a (fast-pow a (dec' n)))))
public static double pow(double a, int b) {
double result = 1;
while(b > 0) {
if (b % 2 != 0) {
result *= a;
b--;
}
a *= a;
b /= 2;
}
return result;
}
(ns conway.rules)
(defn gen-cell[](if (> (Math/random) 0.7) :alive :dead))
(defn seed-grid [rows cols]
(vec (take rows (repeatedly
(fn [] (vec (take cols (repeatedly gen-cell))))))))
(defn neighbors [[i j]]
(let [x ((juxt inc inc identity dec dec dec identity inc) i)
y ((juxt identity inc inc inc identity dec dec dec) j)]
(map vector x y)))
(defn count-neighbors [grid coord]
(let [n (map #(get-in grid %) (neighbors coord))]
(count (filter #(= % :alive) n))))
(defn sim-step [grid coord]
(let [n-live (count-neighbors grid coord)]
(if (= :alive (get-in grid coord))
(case n-live
(2 3) :alive
:dead)
(if (= 3 n-live) :alive :dead))))
(defn step [grid]
(into [] (for [i (range (count grid))]
(into [] (for [j (range (count (get grid i)))]
(sim-step grid [i j]))))))
Игра жизнь
Две основные фазы:
На выходе обычный jar фаил
Три вида переменных
(def bookshelf (ref #{}))
(defn shelve[book]
(dosync (alter bookshelf conj book)))
(defn unshelve [book]
(dosync (alter bookshelf disj book)))
Пример:
Пример:
(def x (agent 0))
(defn increment [c n] (+ c n))
(send x increment 5) ; @x -> 5
(send x increment 10) ; @x -> 15
(ns parallel-fetch
(:import (java.io InputStream InputStreamReader BufferedReader)
(java.net URL HttpURLConnection)))
(defn get-url [url]
(let [conn (.openConnection (URL. url))]
(.setRequestMethod conn "GET")
(.connect conn)
(with-open [stream (BufferedReader.
(InputStreamReader. (.getInputStream conn)))]
(.toString (reduce #(.append %1 %2)
(StringBuffer.) (line-seq stream))))))
(defn get-urls [urls]
(let [agents (doall (map #(agent %) urls))]
(doseq [agent agents] (send-off agent get-url))
(apply await-for 5000 agents)
(doall (map #(deref %) agents))))
(prn (get-urls '("http://lethain.com" "http://willarson.com")))
Например:
(.toUpperCase "fred")
-> "FRED"
(.getName String)
-> "java.lang.String"
(.-x (java.awt.Point. 1 2))
-> 1
(System/getProperty "java.vm.version")
-> "1.6.0_07-b06-57"
Math/PI -> 3.141592653589793
(bean java.awt.Color/black)
-> {:RGB -16777216, :alpha 255, :blue 0, :class java.awt.Color, :colorSpace #object[java.awt.color.ICC_ColorSpace 0x5cb42b "java.awt.color.ICC_ColorSpace@5cb42b"], :green 0, :red 0, :transparency 1}
(defn len [x] (.length x))
(defn len2 [^String x] (.length x))
user=> (time (reduce + (map len (repeat 1000000 "asdf"))))
"Elapsed time: 3007.198 msecs" 4000000
user=> (time (reduce + (map len2 (repeat 1000000 "asdf"))))
"Elapsed time: 308.045 msecs" 4000000
(set! *warn-on-reflection* true)
-> true
(defn foo [s] (.charAt s 1))
-> Reflection warning, line: 2 - call to charAt can't be resolved.
-> #user/foo
(defn foo [^String s] (.charAt s 1))
-> #user/foo
(defn hinted
(^String [])
(^Integer [a])
(^java.util.List [a & args]))
-> #user/hinted
функция с именем примитива возвращает этот примитив
функция с именем примитива во множественном числе возвращает массив примитивов
Огромный набор функций для поддержки операций с примитивами
static public float asum(float[] xs) {
float ret = 0;
for(int i = 0; i < xs.length; i++)
ret += xs[i];
return ret;
}
(defn asum [^floats xs]
(areduce xs i ret (float 0)
(+ ret (aget xs i))))
Каждый год проходит clojurecup - хакатон по этому языку коммандами до четырех человек со всего мира
Clojure - функциональный и простой язык общего назначения, "новый LISP" под JVM, который позволяет делать все, что позволяет делать Java в функциональном стиле.
pros | cons |
---|---|
|