Slide 1

Slide 1 text

Clojure コレクションで探る immutable で persistent な世界

Slide 2

Slide 2 text

lagénorhynque 🐬 カマイルカ (defprofile lagénorhynque :id @lagenorhynque :readings ["/laʒenɔʁɛ̃ k/" "ラジェノランク"] :aliases ["カマイルカ" " 🐬 "] :languages [Java Japanese ; native languages Clojure Haskell ; functional languages English français] ; European languages :interests [programming language-learning law politics mathematics])

Slide 3

Slide 3 text

1. 改めて関数型プログラミング( 言語) とは? 2. Java とClojure のコレクションを調べてみよう 3. Clojure コレクションの全体像 4. 局所的にミュータビリティがほしいとき 5. 独自コレクションを実装しよう

Slide 4

Slide 4 text

改めて関数型プログラミング ( 言語 ) とは ?

Slide 5

Slide 5 text

定義例 関数型プログラミング(functional programming; FP) 副作用を可能な限り避ける( 局所化する) プログラ ミングスタイル 関数型プログラミング言語(functional programming language; FPL) 関数型プログラミングが実践しやすいように設計 されている言語

Slide 6

Slide 6 text

再代入不可な変数が定義可能であればFPL? const, final, val, etc. それを活用していればFP していることになる? ラムダ式があり高階関数が豊富に提供されていれば FPL? filter, map, reduce, etc. それを活用していればFP していることになる?

Slide 7

Slide 7 text

確かにFP/FPL に近づいている感じがする。 でも、それで満足?

Slide 8

Slide 8 text

私🐬が期待する実用的なFPL のイメージ: 不変で永続的なデータ構造(immutable persistent data structures) が豊富に提供さ れ、容易に定義可能 そうでないデータ構造は非中心的な位置付け i.e. immutable でpersistent がデフォルト FP も できる言語をFPL と呼びたくはない

Slide 9

Slide 9 text

永続的 (persistent) 関数型データ構造を更新する際には、更新前と更新 後のバージョンが両方ともその後の処理で利用でき ることを期待する 複数のバージョンをサポートするデータ構造は永続 的(persistent) ←→ 同時に1 つのバージョンしか許さないデータ 構造は刹那的(ephemeral) FPL はすべてのデータ構造が自然と永続的になると いう興味深い性質を持つ 命令型データ構造は概して刹那的 (p. 13) 『純粋関数型データ構造』

Slide 10

Slide 10 text

Java と Clojure のコレクションを調べてみよう

Slide 11

Slide 11 text

Java オブジェクト指向・非関数型言語 静的型付き言語 JVM 言語 関数型プログラミング関連機能が充実してきた // メソッドの定義 jshell> void hello(Object x) { ...> System.out.println("Hello, %s!".formatted(x)); ...> } | created method hello(Object) // メソッドの呼び出し jshell> hello("Java") Hello, Java!

Slide 12

Slide 12 text

Clojure 非オブジェクト指向・関数型言語 動的型付き言語 JVM 言語 オブジェクト指向を嫌い関数型を志向したLisp ;; 関数の定義 user=> (defn hello [x] (println (str "Hello, " x "!"))) #'user/hello ;; 関数の呼び出し(適用) user=> (hello "Clojure") Hello, Clojure! nil

Slide 13

Slide 13 text

参考 : Scala オブジェクト指向・関数型言語 静的型付き言語 JVM 言語 オブジェクト指向に関数型が溶け込んだ言語 // メソッドの定義 scala> def hello(x: Any): Unit = | println(s"Hello, $x!") def hello(x: Any): Unit // メソッドの呼び出し scala> hello("Scala") Hello, Scala!

Slide 14

Slide 14 text

[Java] の実装のひとつ mutable でephemeral な可変長配列 java.util.ArrayList user=> (def xs (java.util.ArrayList.)) #'user/xs user=> xs [] user=> (def ys ; ysに束縛 #_=> (doto xs #_=> (.add 1) ; 破壊的に要素追加 #_=> (.add 2) #_=> (.add 3))) #'user/ys user=> ys [1 2 3] user=> (identical? xs ys) ; オブジェクトの同一性を確認 true java.util.List

Slide 15

Slide 15 text

[Java] unmodifiable (view) list user=> (def xs #_=> (doto (java.util.ArrayList.) #_=> (.add 1) #_=> (.add 2) #_=> (.add 3))) #'user/xs user=> xs [1 2 3] user=> (def ys (java.util.Collections/unmodifiableList xs)) ; 変 #'user/ys user=> (.add ys 4) ; 破壊的更新操作はできない Execution error (UnsupportedOperationException) at java.util.Col modifiableCollection/add (Collections.java:1067). null

Slide 16

Slide 16 text

コレクション( ここではList) に対する変更不可能な ビュー もとのコレクションやその要素がmutable なら immutable ではない もとのコレクションが( 実質的に) immutable であ る、もしくはこのビューを介してのみ操作できる 状態であれば実質的にimmutable cf. user=> (.add xs 4) ; もとのリストは破壊的更新操作ができる true user=> xs [1 2 3 4] user=> ys ; 変更不可能なビューにも波及する [1 2 3 4] java.util.Collection

Slide 17

Slide 17 text

[Clojure] の実装 immutable でpersistent な可変長配列 の一種 ベクター (vector) user=> (def xs []) ; 初期化 #'user/xs user=> xs [] user=> (def ys (conj xs 1 2 3)) ; 要素追加してysに束縛(破壊的更新操作 #'user/ys user=> ys [1 2 3] user=> (identical? xs ys) ; オブジェクトの同一性を確認 false clojure.lang.IPersistentVector HAMT (hash array mapped trie)

Slide 18

Slide 18 text

Clojure コレクションの全体像

Slide 19

Slide 19 text

Clojure コレクションに関するインターフェース ref. (p. 38) Clojure Applied

Slide 20

Slide 20 text

参考 : Scala 不変コレクションのトレイト Traversable Iterable Seq Set Map IndexedSeq LinearSeq SortedSet SortedMap BitSet ref. 可変コレクションおよび不変コレクション | Collections | Scala Documentation

Slide 21

Slide 21 text

Clojure コレクションの性能特性 ref. Clojure Performance Guarantees

Slide 22

Slide 22 text

Scala 不変コレクション ( 列型 ) の性能特性 ref. 性能特性 | Collections | Scala Documentation

Slide 23

Slide 23 text

Clojure のデータ構造の応用について気になったら 書籍 を読もう Clojure Applied

Slide 24

Slide 24 text

Further Reading

Slide 25

Slide 25 text

Clojure Clojure Clojure - Data Structures Clojure - Sequences Clojure - Transient Data Structures Clojure - Datatypes: deftype, defrecord and reify Clojure Applied: From Practice to Practitioner Clojure Performance Guarantees [Stefan Tilkov’s Blog] clojure/core.rrb-vector: RRB-Trees in Clojure

Slide 26

Slide 26 text

Scala Java Scala 可変コレクションおよび不変コレクション | Collections | Scala Documentation 性能特性 | Collections | Scala Documentation Java SE 17 & JDK 17 The Collections Framework (Java SE 17 & JDK 17)

Slide 27

Slide 27 text

Kotlin JavaScript Python Kotlin/kotlinx.collections.immutable: Immutable persistent collections for Kotlin immutable-js/immutable-js: Immutable persistent data collections for Javascript which increase efficiency and simplicity. tobgu/pyrsistent: Persistent/Immutable/Functional data structures for Python