Wprowadzenie do
dla owców
Daniel Janus
Rebased
@nathell
Clojure…
- jest dynamicznie typowany
- ma bogatą paletę struktur danych
- jest Lispem
- jest oparty o platformę
- stawia na niezmienność
- jest leniwy, ale nie za wszelką cenę
- ma rozbudowaną bibliotekę standardową
- znacznie ułatwia pisanie programów współbieżnych
Clojure ma bogatą paletę struktur danych
- Liczby, napisy, wartości logiczne, wyrażenia regularne, symbole, klucze
3 -42/11 "WRUG" true #".*" wrug :wrug
- Listy, wektory, mapy, zbiory
(raz dwa trzy)
[raz dwa trzy]
{raz dwa, trzy cztery}
#{raz dwa trzy}
- Referencje, atomy, agenty, futures, promises
Składnia Clojure
- Już ją znacie
- Z punktu widzenia składni nie ma żadnej różnicy pomiędzy kodem a danymi
- Kod składa się z wyrażeń
Reguły ewaluacji
- Symbole wyliczają się do wartości zmiennych, które nazywają
- Listy wyliczają się w ten sposób, że
- pierwszy element listy jest traktowany jako funkcja
- ta funkcja jest wywoływana z pozostałymi elementami listy jako argumentami
- Wszystko inne wylicza się do samego siebie (potencjalnie rekurencyjnie)
… i to wszystko!
No, prawie.
Przykłady
(+ 3 4)
(+ 3 (* 4 5))
(+ (* 3 4) 5)
[+ (* 3 4) 5]
(if (> 3 4) 5 6)
((if (> 3 4) + -) 5 6)
Lukier składniowy
- ; wykomentowuje wszystko do końca wiersza
- #_ wykomentowuje następujące po nim wyrażenie
- Przecinki są białymi spacjami
- (quote x) (równoważnie 'x) wstrzymuje ewaluację
Clojure jest oparty o platformę
- Java / JVM
- JavaScript (ClojureScript)
- .NET / Common Language Runtime (ClojureCLR)
Język Java: |
Java “Enterprise”: |
Java Virtual Machine: |
Clojure stawia na niezmienność
- Wartości są co do zasady niezmienne
- Zamiast zmieniać, przetwarzamy jedne wartości w inne
- (conj [1 2 3] 4) nie zmienia wektora [1 2 3], ale daje nowy wektor [1 2 3 4]
- Efektywne (czasowo i pamięciowo) współdzielenie podstruktury
Ekspresywna biblioteka standardowa
Współbieżność: STM
- STM: Software Transactional Memory (pamięć transakcyjna)
- ACI bez D
- Referencje: skoordynowane, synchroniczne, atomowe zmiany stanu jednej lub więcej wartości
- Atomy: nieskoordynowane, synchroniczne, atomowe zmiany stanu jednej wartości
- Agenty: asynchroniczne, atomowe zmiany stanu jednej wartości
.gem
.jar
RubyGems
Bundler
Rake
RVM/rbenv
…
Leiningen
Leiningen
(defproject myproject "0.1"
:description "This is a sample project"
:dependencies
[[org.clojure/clojure "1.6.0"]
[clojure-csv "2.0.1"]
[enlive "1.1.5"]])
Rack
Ring
Rails
?
Sinatra
Compojure
Compojure
(ns hello-world.core
(:require [compojure.core :refer :all]
[compojure.route :as route]))
(defroutes app
(GET "/" []
"Hello World
")
(route/not-found
"Page not found
"))
RSpec
Speclj, Midje
WRUG
warsaw-clojurians
Instaparse
Gramatyka EBNF:
S = AB*
AB = A B
A = 'a'+
B = 'b'+
Parser:
(def as-and-bs
(insta/parser
"S = AB*
AB = A B
A = 'a'+
B = 'b'+"))
Lisp is worth learning for the profound enlightenment experience you will have when you finally get it. That experience will make you a better programmer for the rest of your days, even if you never actually use Lisp itself a lot.
— Eric S. Raymond, How To Become a Hacker