楽しいClojureの話
これはなに?
沖縄で行われたハッカーズチャンプルー 2016の懇親会のLT大会で発表した資料です。
Clojureとは
- Lisp方言のひとつ
- インタラクティブな開発(REPL)
- 関数型プログラミング
- 並行処理をしやすい
- 多様な実行環境(JVM、ClojureScript)
Lispの特徴
(str "カッコが多い言語です")
;; 関数をカッコの1番目に、2番目からあとにはその関数の引数をいれます
(+ 1 2 3 4) ; => 10
;; マクロを使って新しい文法を自分で追加できます
(defmacro unless [test then]
(list 'if (list 'not test)
then)))
(if true "then" "else") ; => "then"
(unless true "then" "else") ; => "else"
インタラクティブな開発(REPL)
(str "カッコが多い言語です")
;; 関数をカッコの1番目に、2番目からあとにはその関数の引数をいれます
(+ 1 2 3 4) ; => 10
;; マクロを使って新しい文法を自分で追加できます
(defmacro unless [test then]
(list 'if (list 'not test)
then)))
(if true "then" "else") ; => "then"
(unless true "then" "else") ; => "else"
インタラクティブな開発(REPL)
基本、不変なデータ(変数じゃない)
; シンボルにデータを束縛する
(def my-name "arakaki yuji")
my-name ; => "arakaki yuji"
; レキシカルスコープ内のみで一時的に束縛
(let [my-name "yuji"]
my-name) ; => "yuji"
; スコープ外には影響ない
my-name; => "arakaki yuji"
; 文字
/a
; 文字列
"Hello World"
; list(Lispのベースとなるデータ型)
(list 1 2 3) ; => (1 2 3)
; Vector(順番を持ったコレクション)
["a" 1 'hello \a]
; Map(キーと値を対応させたコレクション)
{:name "arakaki yuji" :age 27}
; Set(値が一意になること保証したコレクション)
; シンボル
(symbol "my-name") ; my-name
; 関数
(fn [n] (+ n 5))
; => #object[user$eval19622$fn__19623 0x243a2394 "user$eval19622$fn__19623@243a2394"]
関数が第一級オブジェクト
; 関数定義
(defn hello-world [name]
(str "Hello World, " name))
; 関数が第1級オブジェクトなので引数で関数を返せる関数作れる
(defn add-factory [number]
(fn ([] number)
([n & more] (apply + (conj more n number)))))
(def add-8 (add-factory 8)
(def add-100 (add-factory 100))
(add-8 2)
; => 10
(add-100 30)
; => 130
変更可能なデータもある
; シンボルにデータを束縛する
(def my-name "arakaki yuji")
my-name ; => "arakaki yuji"
; レキシカルスコープ内のみで一時的に束縛
(let [my-name "yuji"]
my-name) ; => "yuji"
; スコープ外には影響ない
my-name; => "arakaki yuji"
; 文字
/a
; 文字列
"Hello World"
; list(Lispのベースとなるデータ型)
(list 1 2 3) ; => (1 2 3)
; Vector(順番を持ったコレクション)
["a" 1 'hello \a]
; Map(キーと値を対応させたコレクション)
{:name "arakaki yuji" :age 27}
; Set(値が一意になること保証したコレクション)
; シンボル
(symbol "my-name") ; my-name
; 関数
(fn [n] (+ n 5))
; => #object[user$eval19622$fn__19623 0x243a2394 "user$eval19622$fn__19623@243a2394"]
; 関数定義
(defn hello-world [name]
(str "Hello World, " name))
; 関数が第1級オブジェクトなので引数で関数を返せる関数作れる
(defn add-factory [number]
(fn ([] number)
([n & more] (apply + (conj more n number)))))
(def add-8 (add-factory 8)
(def add-100 (add-factory 100))
(add-8 2)
; => 10
(add-100 30)
; => 130
変更可能なデータもある
基本不変データのClojureですが、変更可能なデータ型もある。
それらは用途に応じて使い分けれるように複数あります。
変更可能なデータ型の種類
- atom
- ref
- agent
; atom
(atom x 1)
x ; => #object[clojure.lang.Atom 0x757c7948 {:status :ready, :val 1}]
;; 値を参照するには@をつける
@x ; => 1
;; 単独で値を変更したいデータの時に使う
(reset! x 5)
@x ; => 5
; ref
(def y (ref 1))
y ; => #object[clojure.lang.Ref 0x3fe68e45 {:status :ready, :val 1}]
;; 値を参照するには@をつける
@y ; => 1
; refは複数の値を協調して変更したい場合に使う
(def z (ref 5))
(dosync
(ref-set y 10)
(ref-set z 20))
@y ; => 10
@z ; => 20
; agent
(def a (agent 1))
a ; => #object[clojure.lang.Agent 0x307b6b7e {:status :ready, :val 1}]
@a : => 1
; agentは非同期でデータを変更したい場合に使う
(send a + 100)
; => #object[clojure.lang.Agent 0x307b6b7e {:status :ready, :val 1}]
a
; => #object[clojure.lang.Agent 0x307b6b7e {:status :ready, :val 101}]
並行処理をしやすい
; atom
(atom x 1)
x ; => #object[clojure.lang.Atom 0x757c7948 {:status :ready, :val 1}]
;; 値を参照するには@をつける
@x ; => 1
;; 単独で値を変更したいデータの時に使う
(reset! x 5)
@x ; => 5
; ref
(def y (ref 1))
y ; => #object[clojure.lang.Ref 0x3fe68e45 {:status :ready, :val 1}]
;; 値を参照するには@をつける
@y ; => 1
; refは複数の値を協調して変更したい場合に使う
(def z (ref 5))
(dosync
(ref-set y 10)
(ref-set z 20))
@y ; => 10
@z ; => 20
; agent
(def a (agent 1))
a ; => #object[clojure.lang.Agent 0x307b6b7e {:status :ready, :val 1}]
@a : => 1
; agentは非同期でデータを変更したい場合に使う
(send a + 100)
; => #object[clojure.lang.Agent 0x307b6b7e {:status :ready, :val 1}]
a
; => #object[clojure.lang.Agent 0x307b6b7e {:status :ready, :val 101}]
Clojure自体が並行処理を前提として設計されている
- 不変なデータ型
- 関数型プログラミングにより副作用を減らす
- 並行処理をサポートする機能を複数用意
並行処理用の機能
まだちゃんと勉強できていないのでこんなのあるよ〜ぐらい・・
- agent
- thread
- core.async
- future
多様な実行環境
-
Clojure(.clj)
- JVM上で実行される
- Javaのライブラリを使用可能
-
ClojureScript(.cljs)
- JavaScriptにコンパイルされる(AltJS)
-
両方でコードを共有可能(.cljc)
- フロントエンドとサーバーサイドでロジックを共有できる
- 各動作環境の独自機能は共有できないので注意
最後に
Clojure(.clj)
- JVM上で実行される
- Javaのライブラリを使用可能
ClojureScript(.cljs)
- JavaScriptにコンパイルされる(AltJS)
両方でコードを共有可能(.cljc)
- フロントエンドとサーバーサイドでロジックを共有できる
- 各動作環境の独自機能は共有できないので注意
Clojure楽しいがまだ自分は大きなアプリケーション書いたことはないので、これから書いていきたい。
もし他にも興味ある方がいれば一緒にやりましょう^^/
Author And Source
この問題について(楽しいClojureの話), 我々は、より多くの情報をここで見つけました https://qiita.com/arakaji/items/41ae4f536cafe57b5842著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .