Mais conteúdo relacionado
Semelhante a Clojure (20)
Mais de Uehara Junji (20)
Clojure
- 3. 短く書ける
Clojure Scala
http://www.bestinclass.dk/index.php/2009/09/scala-vs-clojure-round-2-concurrency/
- 4. 関数型言語の3階層
• レベル1
• 関数定義でプログラムを書く
• Emacs Lisp, Common Lisp, Scheme, C言語
• レベル2
• レベル1に加え、 副作用を排し、遅延評価を駆使する
• Scala, Haskell
• レベル3
• レベル2に加え、オブジェクト指向を否定し型に頼らない
• Clojure ←いまここ
注:この階層は本資料作成者が勝手に考えたもの。
- 5. 副作用を避けるといっても
• 徹底的に避ける派: Haskell
• Monad
• できるだけ避ける派: Scala, Clojure
• どうせJavaアクセスに必要だし
• ただし、副作用が生じるものとそうでないも
のを明確に区分けして扱う
- 6. 他の言語との比較
ダックタイピン
動的型/静的型 クラスベース 動的言語か※
グ
動的型+型ヒント
Clojure による最適化 × × ○
静的型+型
Scala ○ × ×
推論
Java 静的型 ○ × ×
動的型+オプショナル
Groovy タイピングによる実行
時チェック
○ ○ ○
Ruby 動的型 ○ ○ ○
※参考: http://groovy.dzone.com/news/dynamic-typing-vs-dynamic-lang
- 7. Java連携 面白
い!
• JavaのAPIを呼び出すための専用構文
(.toUpperCase "String") ;; インスタンスメソッド呼出
(.. "String " toUpperCase trim) ;; a.b.c
(Math/max 1 2) ;; staticメソッド呼出
(Integer. 3) ;; new Integer
• Javaよりも短く、Java APIを呼ぶ
- 8. 多様な並行処理モデル
• ref & STM ・・・トランザクショナルな(ロールバ
ック可能な)アトミック操作(ACIDならぬACI)
• Atom・・・ アトミックな参照変数だがロールバッ
クはしない
• Agents・・・キューを使ってタスクを非同期実行
(結果的にアトミックになる)。synchronizedの
waitしないバージョン。GParsのSafeに影響。
• スレッドローカルなvar
• lock ・・・Javaのsynchronized
- 9. ref & STM 面白
い!
• (def current-track (ref "北の宿から"))
(def current-singer (ref "都はるみ"))
(dosync
(ref-set current-track "天城越え") トランザクション
(ref-set current-singer "石川はるみ"))
• SMT(ソフトウェアトランザクショナルメモリ)
•トランザクションは楽観的排他制御によってロールバックされた
り再実行されたりするからして、副作用は許されない。→関数型
の効用
•楽観的排他制御は「ロックフリーアルゴリズム」でありロック待ち
しないので原理的に高速。やってみて駄目ならもう一度やる。マ
ルチコア・メニーコア時代の新常識 。
- 10. 遅延評価
• 遅延シーケンス
>(def long-seq (range 0 100000000))
>(take 3 long-seq)
(0 1 2)
• 無限長シーケンスでも無問題
>(defn mugen-seq [] (iterate inc 0))
> (take 3 (mugen-seq))
(1 2 3)
- 12. マクロ 面白
い!
• リーダマクロ
• #(), ;, @, ^, #^, ', #"", 'x, ~, ~@, #'
• ユーザ定義はできない
• 普通のマクロ
(defmacro my-if [cond body] `(if ~cond ~body))
(my-if true (println "hoge"))
• マクロはGroovyでいうAST変換に相当(コンパイラ
のコンパイル処理に介在して、コード変換を行う)
• コーディングパターン/デザインパターンを表現
する間接レイヤ
- 13. recur,trampoline
• 自動的な末尾再帰最適化はしない(JVM制約による)
• 明示的な末尾再帰最適化を指示するためのマーカ:
•
recur
•trampoline(相互再帰用)
• (defn recur-fibo [n]
(letfn [(fib [current next n]
(if (zero? n)
current
(recur next (+ current next) (dec n))))]
(fib 0 1 n))
- 14. 変態?なところ 面白
い!
• [ ] はvectorリテラル、マップリテラル{}, セットリテラル#{}も書ける
> (defn plus [a b] (+ a b))
• (vector インデックス) で要素参照
>([1, 2, 3] 1)
2
• (マップ キー)でキーに対応する値が取れる
>({ :hoge 10 :fuga 20 } :hoge)
10
• カンマと空白は等価
{ :hoge 10, :fuga 20 }
(+ 1,2)
• 分配束縛・・・引数を受け取りつつパターンマッチングしつつ多重変数代
入
• 何を言ってるかわからねーと思うが引数を取得したら処理の大半が
終わっていた・・
- 15. オブジェクト指向への
アンチテーゼ
• オブジェクト指向は冗長である
• 可読性重視とかいったって、コード量が莫大になる
ならそれはやっぱり理解しにくく読みにくい。難解で
も短い方がいい(難解な部分を極小化した上で)。
• 名詞が幅を利かせすぎている
• 動詞の逆襲
• オブジェクト指向の利点(カプセル化、情報隠蔽、再利
用、多態)は、関数型とクロージャとマルチメソッドでよ
りよく達成できる