iSoligorsk #3 2013

57
Introduction to Clojure Soligorsk, 26.01.2013 Friedrich Boeckh

Transcript of iSoligorsk #3 2013

Page 1: iSoligorsk #3 2013

Introduction to Clojure

Soligorsk, 26.01.2013Friedrich Boeckh

Page 3: iSoligorsk #3 2013

… even Microsoft cares

http://www.thoughtworks.com/articles/technology-radar-october-2012

ThoughtWorks 2012: Clojure is on the Radar

http://cafe.elharo.com/programming/java-programming/why-functional-programming-in-java-is-dangerous/

… as always - it does not make everybody happy:

Page 4: iSoligorsk #3 2013

World singles

• 3,000,000 members• 1,000,000 emails / day• 80,000 logins / day• 2,000 concurrent users (average)

http://corfield.org/articles/WorldSinglesWeb.pdf

Sean Corfield

Page 5: iSoligorsk #3 2013

http://skillsmatter.com/podcast/home/reviving-the-uswitch-back-office-with-clojure

uSwitch.com

Ryan Greenhall

Page 6: iSoligorsk #3 2013

Clojure at a bankMalcolm Sparkshttp://blog.malcolmsparks.com/?p=17

Page 7: iSoligorsk #3 2013

Clojure at another bankJon Pitherhttp://www.pitheringabout.com/?p=693

Page 8: iSoligorsk #3 2013

Clojure at yet another bank

Page 9: iSoligorsk #3 2013

Clojure at Nokia Entertainment

http://skillsmatter.com/event/clojure/clojure-at-nokia-entertainment

Page 10: iSoligorsk #3 2013

Big Data Done Better – Mastodon C

https://www.mastodonc.com/

Page 11: iSoligorsk #3 2013

Clojure gives Innovation a Boost

Stuart Halloway Justin Gethland

& Rich Hickey

Page 12: iSoligorsk #3 2013

http://de.slideshare.net/alexott/clojure-lisp-for-the-modern-worldhttp://alexott.net/ru/clojure/clojure-intro/index.html http://alexott.net/en/clojure/video.html

Russian wording in the following from Alex Ott´s talk at itsea 2012

Page 13: iSoligorsk #3 2013

Что такое Clojure?

• Rich Hickey, 17.10.2007, сейч са́� v1.4, RC v1.5 • Lisp-ообразный• Функциональный• Конкурентное программирование

http://stackoverflow.com/questions/1050222/concurrency-vs-parallelism-what-is-the-difference

• Многоплатформенный (JVM, .Net, JavaScript, etc.)• Открытый исходный код и либеральная лицензия

Eclipse Public License 1.0

• Активное сообщество разработчиков• Коммерческое применение• Коммерческая поддержка

Page 14: iSoligorsk #3 2013

Активное сообщество разработчиков

Sean Corfieldhttp://corfield.org/articles/WorldSinglesWeb.pdf, mid 2012

Page 15: iSoligorsk #3 2013

Почему Lisp?

• Простой синтаксис - code as data structures homoiconic• Метапрограммирование (макросы)• Создание доменно-специфических языков DSLs• Генерация кода во время компиляции• Возможность избежать повторений

• Генерация и выполнение кода в runtime• Интерактивная разработка REPL• Динамически типизированный

Page 16: iSoligorsk #3 2013

John McCarthy1927 - 2011

Lisp Specification, 1958

Lisp? 7 элементов + fn нотация

Page 17: iSoligorsk #3 2013

Lisp? 7 элементов + fn нотация

• (quote x) returns x• (atom x)returns the atom t (true) if the value of x is

an atom or the empty list. Otherwise it returns ().• (eq x y) returns t if the values of x and y are the

same atom or both the empty list, and () otherwise.• (car x) expects the value of x to be a list, and returns its first element.• (cdr x) expects the value of x to be a list, and returns everything after

the first element.• (cons x y) expects the value of y to be a list, and returns a list

containing the value of x followed by the elements of the value of y.• (cond (p1 e1) ... (pn en)) is evaluated as follows. The p

expressions are evaluated in order until one returns t (true). When one is found, the value of the corresponding e expression is returned as the value of the whole cond expression.

• A function is expressed as (lambda (p1 ... pn) e), where p1 ... pn are atoms, called parameters, and e is an expression.

Paul Graham, The Roots of Lisphttp://www.paulgraham.com/rootsoflisp.html http://www.cse.sc.edu/~mgv/csce531sp07/jmc.pdf

Page 18: iSoligorsk #3 2013

Богатство Lisp наследия• Hal Abelson, Jerry Sussman and Julie Sussman, Structure and

Interpretation of Computer Programs (SICP), http://mitpress.mit.edu/sicp/, http://newstar.rinet.ru/~goga/sicp/sicp.pdf (russ.), http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-001-structure-and-interpretation-of-computer-programs-spring-2005/video-lectures/

• Peter Seibel, Practical Common Lisp, http://www.gigamonkeys.com/book/

• Paul Graham, On Lisp, http://www.paulgraham.com/onlisp.html, http://lib.store.yahoo.net/lib/paulgraham/onlisp.pdf

Page 19: iSoligorsk #3 2013

Богатство Lisp наследия

Conrad Barski (M.D.)

http://vimeo.com/9605639

Page 20: iSoligorsk #3 2013

Богатство Lisp наследия• VLSI design, Boeing, US government & military, ITA Software (in

2010 acquired by Google)

• NASA, The Remote Agent Experiment - Debugging code from60 million miles away, Ron Garret, 14 February 2012

• Paul Graham, Beating the Averages, http://www.paulgraham.com/avg.html, http://lib.store.yahoo.net/lib/paulgraham/bbnexcerpts.txt

• Andreas Lehmann, Common Lisp Raytracer, (source code transcript e. g. here https://github.com/fbmnds/clrt), videos and PDFs http://rudairandamacha.blogspot.de/2012/09/writing-simple-raytracer-in-common-lisp.html

Page 21: iSoligorsk #3 2013

Богатство Lisp наследия• Peter Norvig, Paradigms of Artificial Intelligence Programming:

Case Studies in Common Lisp (PAIP), http://norvig.com/paip.html

• Daniel P. Friedman, Matthias Felleisen, The Little Schemer, http://mitpress.mit.edu/books/little-schemer

• Overview by Vsevolod Dyomkin, http://lisp-univ-etc.blogspot.com/2012/12/lisp-books.html

• Rich Hickey, Books that influenced Clojure, http://www.amazon.com/gp/richpub/listmania/fullview/R3LG3ZBZS4GCTH

Page 22: iSoligorsk #3 2013

Богатство Lisp наследия – Emacs ??Marco Baringer's SLIME Tutorial Video:

http://www.youtube.com/watch?v=_B_4vhsmRRI ( underscore)

Page 23: iSoligorsk #3 2013

Отличия от других Lisp’ов• Немного упрощенный синтаксис -- меньше скобочек• Неизменяемые данные (immutability)• Добавлено больше базовых структур данных: вектора,

отображения (maps) и т.д.• Расширяемый reader, но без reader macros• "Ленивые" коллекции (lazy-seq) • Мета-информация привязанная к данным и функциям• Case-sensitive names• Исключения вместо условий/рестартов• Полиморфизм: протоколы и мультиметоды• Software Transactional Memory System (STM)• Java Interoperation, http://clojure.org/java_interop

( underscore)

Page 24: iSoligorsk #3 2013

Полиморфизм на Clojure• Протоколы, мультиметоды

https://www.ibm.com/developerworks/java/library/j-clojure-protocols/

Stuart Sierra,

Page 25: iSoligorsk #3 2013

Полиморфизм на Clojure• Протоколы, мультиметоды

http://oredev.org/2012/sessions/expressing-yourself-polymorphism-in-clojure

Page 26: iSoligorsk #3 2013

Software Transactional Memory System (STM)

Graig Andera

http://pluralsight.com/training/Courses/TableOfContents/clojure-concurrency-tutorial

Page 28: iSoligorsk #3 2013

Lambda Calculus ~ “effectively programmable”

Alonzo Church1903 - 1995

Stephen Kleene1909 - 1994

Alan Turing1912 - 1954

Page 29: iSoligorsk #3 2013

Lambda Calculushttp://www.infoq.com/presentations/Y-Combinator

transcript by Michael Kohl, http://citizen428.net/blog/2010/12/14/clojure-deriving-the-y-combinator-in-7-stolen-steps/

(defn Y [h] ((fn [f] (f f)) (fn [f] (h (fn [n] ((f f) n))))))

(def fact (Y (fn [g] (fn [n] (if (< n 2) 1 (* n (g (dec n))))))))

Jim Weirich (Y-rich)

Page 30: iSoligorsk #3 2013

Почему ФП?

1922 - 1990

You want functions?

Page 31: iSoligorsk #3 2013

Почему ФП?

Get some:

Page 32: iSoligorsk #3 2013

Clojure / ФП - Namespaces

• Namespaces are mappings from simple (unqualified) symbols to Vars and/or Classes.

• Namespaces are first-class, they can be enumerated etc. • Namespaces are also dynamic, they can be created, removed

and modified at runtime, at the Repl etc.• The best way to set up a new namespace at the top of a Clojure

source file is to use the ns macro. • The current namespace, *ns* can and should be set only with

a call to in-ns or the ns macro, both of which create the namespace if it doesn't exist.

http://clojure.org/namespaces

Page 33: iSoligorsk #3 2013

Clojure / ФП - Namespaces• clojure.core - Fundamental library of the Clojure language• clojure.data - Non-core data functions.• clojure.inspector - Graphical object inspector for Clojure data

structures.• clojure.java.browse - Start a web browser from Clojure• clojure.java.io• clojure.java.javadoc - A repl helper to quickly open javadocs.• clojure.java.shell• clojure.main• clojure.pprint - A Pretty Printer for Clojure• clojure.reflect - Reflection on Host Types• clojure.repl - Utilities meant to be used interactively at the REPL

Page 34: iSoligorsk #3 2013

Clojure / ФП - Namespaces

• clojure.set• clojure.stacktrace - Print stack traces oriented towards Clojure, not

Java.• clojure.string• clojure.template - Macros that expand to repeated copies of a

template expression.• clojure.test - A unit testing framework.• clojure.walk• clojure.xml - XML reading/writing.• clojure.zip - Functional hierarchical zipper, with navigation, editing,

and enumeration. See Huet

Page 35: iSoligorsk #3 2013

Базовый синтаксис

• Код – структуры данных• Выражение – список, первый элемент бывает:• Функция• Макрос• Специальная форма

• Примеры:

(def a 1)

(+ 1 2)

(defn square [x] (* x x))

(defmacro when [x & body] `(if ~x (do ~@body)))

Page 36: iSoligorsk #3 2013

Базовые типы данных

• Числа (целые, рациональные, вещественные): 42, 1/3, 12345678901234567N, 4.2, 42.2M

• Строки: "string... " • Знаки (characters): \a, \newline, …• Регулярные выражения: #"\d+"• Логические значения: true, false• как null в Java nil• Симбол (symbol): name• keyword: :name, (:name {:name "test"})

Page 37: iSoligorsk #3 2013

Коллекции

• Разные коллекции:• Списки: '(1 2 3 "abc") (quoting)• Вектора: [1 2 3] (no quoting)• Отображения (maps): {:k1 1234 :k2 "value"}

• Множества: #{:val1 "text" 1 2 10}• persistent & transient коллекции• Вектора, отображения и множества сами являются

функциями:

([1 2 3] 2) ({:a 1 :b 2 :c 3} :b)=> 3 => 2(no quoting) (no quoting)

Page 38: iSoligorsk #3 2013

Persistent collections• Новая копия данных при

изменении• Затрагивается только

измененная часть• Производительность

сравнима с коллекциями Java

http://blip.tv/clojure/clojure-concurrency-819147

Rich Hickey to the Western Mass. Developers Group on Clojure and concurrency.(2,5h – well invested time!)

http://www.youtube.com/user/ClojureTV

Page 39: iSoligorsk #3 2013

Последовательности• Последовательности (sequences):• Коллекции Clojure & Java, массивы, iterable, …• "Ленивые" операции над последовательностями• Могут быть бесконечными• Один набор операций над последовательностями:

map, reduce / reductions, filter, …

Tim McCormack, http://www.brainonfire.net/files/seqs-and-colls/main.html

http://www.infoq.com/presentations/Clojure-Reducers

Page 41: iSoligorsk #3 2013

Clojure Destructuring

(def indexes [1 2 3]); #'user/indexes

(let [[x & more :as full-list] indexes] (println "x:" x "more:" more "full list:" full-list)); x: 1 more: (2 3) full list: [1 2 3]

(def point {:x 5 :y 7}); #'user/point

(let [{the-x :x the-y :y} point] (println "x:" the-x "y:" the-y)); x: 5 y: 7

http://blog.jayfields.com/2010/07/clojure-destructuring.html

Jay Fields

Page 42: iSoligorsk #3 2013

Clojure core.logic

https://www.youtube.com/watch?v=A7de6pC-tnU

Dan Friedman William Byrd

Prolog

Page 43: iSoligorsk #3 2013

Clojure core.logicProlog

http://www.vimeo.com/45128721

Page 44: iSoligorsk #3 2013

IDE & средства сборки кода• Поддержка в IDE/редакторах:– Eclipse (Counterclockwise)– Netbeans (Enclojure)– IntelliJ IDEA (La Clojure)– Emacs + SLIME (depricated) или nRepl / ritz-repl

• Ubuntu: https://launchpad.net/~cassou/+archive/emacs • Windows: ftp://ftp.gnu.org/gnu/emacs/windows/, cygwin.com

– VimClojure– LightTable, Textmate, Sublime Text 2, Jedit

• Средства сборки кода:– Поддержка Clojure в Maven, Ant, Cake, Gradle– самый популярный: Leiningen (спасибо, Phil)

Phil Hagelberg

Page 45: iSoligorsk #3 2013

Библиотеки и репозитории

• Простой доступ к библиотекам JVM• Библиотеки написанные на Clojure:– Web-разработка: Compojure, Ring, Scriptjure– RDBMS: ClojureQL, clojure.java.jdbc, Korma– NoSQL: Monger, Clouch, …– GUI: Seesaw

http://darevay.com/talks/clojurewest2012/#/title-slide – Логическое программирование: core.logic

• Репозитории: Maven Central, Clojars.org

Page 46: iSoligorsk #3 2013

Clojure + Leiningen + Emacs 24/emacs-live on Windows 8

• Install Java JDK from http://www.java.com

• Install cygwin, use defaults; use cygwin package manager to install git

• Install Leiningen 2.0 in cygwin, this includes Clojure:

– $ cd; git clone \ https://raw.github.com/technomancy/leiningen/preview/bin/lein

– Place it on your $PATH, preferably use ~/bin– $ chmod 755 ~/bin/lein – $ lein self-install

• Install Emacs 24 + emacs-live in Windows:• Download Emacs 24 from ftp://ftp.gnu.org/gnu/emacs/windows/• Download emacs-live from https://github.com/overtone/emacs-live • Move directory emacs-live to C:\Users\%your user name%\AppData\Roaming\.emacs.d

Caveat: emacs-live does not yet collaborate on Windows with ritz-repl, i.e.emacs-live provides not the full SLIME functionality as per mid Jan. 2013

Page 47: iSoligorsk #3 2013

Let´s start: 4clojure.com

See also:http://www.lisperati.com/clojure-spels/casting.htmlhttps://github.com/relevance/labreplhttp://clojurekoans.com/ http://tryclj.com/

Page 48: iSoligorsk #3 2013

Lazy Searching

;;;; 4clojure #108

;; find f satisfying:;(= 64 (f (map #(* % % %) (range)) ;; perfect cubes (filter #(zero? (bit-and % (dec %))) (range)) ;; powers of 2 (iterate inc 20))) ;; at least as large as 20

;; caution: the function for powers of 2 becomes ;; highly inefficient for n > 28:;(time (last (take 28 (filter #(zero? (bit-and % (dec %))) (range)))));"Elapsed time: 25954.456087 msecs";67108864

Page 49: iSoligorsk #3 2013

;; define predicate on ordered, infinite seqs:;(defn in? [coll x] (cond (empty? coll) false (= x (first coll)) true (< x (first coll)) false :else (in? (rest coll) x)))

;; for convenience:;(def inf-seq-1 (map #(* % % %) (range))) (def inf-seq-2 (filter #(zero? (bit-and % (dec %))) (range)))(def inf-seq-3 (iterate inc 20))

Lazy Searching

Page 50: iSoligorsk #3 2013

;; predicate in? can be used on a finite list of infinite seqs:;

(take 10 (for [i (range)] [i (map #(in? % i) (list inf-seq-1 inf-seq-2 inf-seq-3))]));([0 (true true false)] [1 (true true false)] [2 (false true false)] [3 (false false false)] [4 (false true false)] [5 (false false false)] [6 (false false false)] [7 (false false false)] [8 (true true false)] [9 (false false false)])

(first (drop 64 (for [i (range)] [i (map #(in? % i) (list inf-seq-1 inf-seq-2 inf-seq-3))])));[64 (true true true)]

Lazy Searching

Page 51: iSoligorsk #3 2013

;; for convenience:;(def three-infinite-seqs (list inf-seq-1 inf-seq-2 inf-seq-3))

;; predicate in? can be reduced on a finite list ;; of infinite seqs;;; for convenience define in-seqs?:;(defn in-seqs? [x & colls] (reduce #(and %1 %2) (map #(in? % x) colls)))

(apply in-seqs? 4 three-infinite-seqs);false(apply in-seqs? 64 three-infinite-seqs);true

Lazy Searching

Page 52: iSoligorsk #3 2013

;; in-seqs? can be used to build a vector tuple in a for loop:(take 10 (for [i (range)] [i (apply in-seqs? i three-infinite-seqs)]));([0 false] [1 false] [2 false] [3 false] [4 false] [5 false] [6 false] [7 false] [8 false] [9 false])

;; hence, filtering on the infinite seq of tuples is possible:;(first (filter #(true? (% 1)) (for [i (range)] [i (apply in-seqs? i three-infinite-seqs)]));[64 true]

Lazy Searching

Page 53: iSoligorsk #3 2013

;; finally, pick the solution from the right tupel:;((first (filter #(true? (% 1)) (for [i (range)] [i (apply in-seqs? i three-infinite-seqs)]))) 0);64

;; Remark:;;;; optimize the solution by using -> / ->>;; http://kotka.de/blog/2010/04/Did_you_know_II.html

Lazy Searching

Page 54: iSoligorsk #3 2013

Balanced Primes – 1st

;;;; 4clojure #116 (Prime Sandwich)

(= 1103 (nth (filter balanced? (range)) 15))

(defn prime? [n] (cond (< n 2) false (= n 2) true :else (= '(1) (filter #(zero? (rem n %)) (range 1 (inc (Math/sqrt n)))))))

(defn p-before [p] (last (filter prime? (range p))))

(defn p-after [p] (first (filter prime? (drop (inc p) (range)))))

(defn balanced? [p] (cond (< p 4) false (prime? p) (= p (/ (+ (p-before p) (p-after p)) 2)) :else false))

Page 55: iSoligorsk #3 2013

Balanced Primes – 2nd

(= 1103 (nth (filter balanced? (range)) 15))

;; prime?, balanced? as before;; balanced? needs to be refreshed;; and (take 10 primes);;(def primes (filter prime? (range)))

(defn p-before [p] (last (filter #(< % p) primes)))

(defn p-after [p] (first (filter #(> % p) primes)))

Page 56: iSoligorsk #3 2013

Balanced Primes – 3rd(= 1103 (nth (filter balanced? (range)) 15))

;; prime?, primes, in? as before

(def partitioned-primes (map #(vector (second %) (= (second %) (/ (+ (first %) (last %)) 2))) (partition 3 1 primes)))

(def balanced-primes (map #(% 0) (filter #(true? (% 1)) partitioned-primes)))

(defn balanced? [p] (in? balanced-primes p)))

Page 57: iSoligorsk #3 2013

Вопросы?

Спасибо за внимание.