Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
ミュータビリティとイミュータビリティの狭間: 関数型言語使いから見たKotlinコレクション
Search
Kent OHASHI
July 08, 2024
Programming
160
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
ミュータビリティとイミュータビリティの狭間: 関数型言語使いから見たKotlinコレクション
Kotlin標準コレクションのイミュータビリティ(不変性)について、ScalaやClojureと比較しながら調べてみよう!
Kent OHASHI
July 08, 2024
More Decks by Kent OHASHI
See All by Kent OHASHI
速習FP in Scala with Flix: Flix言語で親しむ純粋関数型のコード設計
lagenorhynque
0
17
"Simple Made Easy" Made Easier: Clojureに学ぶsimplicity
lagenorhynque
0
25
Property-Based Testing with test.check and clojure.spec
lagenorhynque
0
59
🐬の推し本紹介2025: 『コーディングを支える技術 ――成り立ちから学ぶプログラミング作法』
lagenorhynque
0
120
KotlinでミニマルなResult実装による関数型エラーハンドリング
lagenorhynque
0
70
Functional Calisthenics in Kotlin: Kotlinで「関数型エクササイズ」を実践しよう
lagenorhynque
1
440
関数型言語テイスティング: Haskell, Scala, Clojure, Elixirを比べて味わう関数型プログラミングの旨さ
lagenorhynque
1
270
純LISPから考える関数型言語のプリミティブ: Clojure, Elixir, Haskell, Scala
lagenorhynque
1
280
From Scala/Clojure to Kotlin
lagenorhynque
0
120
Other Decks in Programming
See All in Programming
PHPだって関数型したい 〜できること、できないこと〜 / fp-in-php
jsoizo
0
210
AI時代、エンジニアはどう育つのか -未経験エンジニアの成長を間近で見て考えたこと-
thasu0123
0
110
【やさしく解説 設計編 #1】「ドメイン駆動」と「実装駆動」ってなに? 〜設計の考え方を、たとえ話で学ぼう〜
panda728
PRO
1
120
エンジニアにデザインハーネスを 〜デザインプロセスを規定するためのハーネス〜 / Design harness from an engineer's perspective
rkaga
2
1.5k
AIキャラアプリkaiwaの低遅延音声通話基盤をどう作ったか - AWS Gravitonで支える低遅延・低コストAI Agent基盤
mogamit
0
170
Welcome to the "Parametricity" 🏙️ − Generic だけど Specific な世界 −
guvalif
PRO
1
170
琵琶湖の水は止められてもNet--HTTPのリトライは止められない / You might be able to stop the water flow of Lake Biwa but you can't stop Net::HTTP retries
luccafort
PRO
0
380
ルールを書いて終わらせないハーネスエンジニアリング
yug1224
2
1.5k
ITヒヤリハットを整理してみた ~ライフサイクルと原因から考える再発防止策~
koukimiura
1
110
Laravelで学ぶ Webアプリケーションチューニング入門/web_application_tuning_101
hanhan1978
4
570
関数型プログラミングのメリットって何だろう?
wanko_it
0
180
PHP に部分適用が来るぞ!……ところで何それ?おいしいの? #phpcon / phpcon-2026
shogogg
0
210
Featured
See All Featured
Ethics towards AI in product and experience design
skipperchong
2
330
Digital Ethics as a Driver of Design Innovation
axbom
PRO
1
340
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
16k
The Language of Interfaces
destraynor
162
27k
Code Review Best Practice
trishagee
74
20k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
32
3k
The State of eCommerce SEO: How to Win in Today's Products SERPs - #SEOweek
aleyda
2
11k
GraphQLとの向き合い方2022年版
quramy
50
15k
Joys of Absence: A Defence of Solitary Play
codingconduct
1
410
Navigating Weather and Climate Data
rabernat
0
360
Ecommerce SEO: The Keys for Success Now & Beyond - #SERPConf2024
aleyda
1
2.1k
Getting science done with accelerated Python computing platforms
jacobtomlinson
2
310
Transcript
ミュータビリティと イミュータビリティの狭間 関数型言語使いから見たKotlinコレクション #kotlinfest2024_after_33 1
のプロダクトエンジニア 主要技術スタック: Kotlin + のたまごスポンサー 🥚 の運営企業 関数型言語/関数型プログラミングが好き 仕事や趣味で ,
, などに長く 触れてきた 最近再入門したKotlinも好きになりつつある 😆 lagénorhynque 🐬カマイルカ 株式会社スマートラウンド Ktor Kotlin Fest 2024 Server-Side Kotlin Meetup Clojure Scala Haskell 2
1. きっかけ 2. 実験・調査 3. まとめ 3
1. きっかけ 4
Kotlin Fest 2024のセッションを聴いていた私 🐬 「Kotlinにはイミュータブルとミュータブルの2種 類のコレクションがあります」 「Kotlinを導入することで私たちはイミュータビリ ティを得ました」 Kotlinの List
のコードとともに破壊的更新操作 ができない例が示される 5
🐬の反応 Kotlinの List, Set, Map などは「イミュータブル」 (不変)なコレクションといえるのだろうか 🤔 同じくJVM言語(さらに関数型言語)のScalaや Clojureとはどう違うのだろう
確かKotlinには準標準ライブラリ(?)として があったはず 🤔 immutable/persistent collectionsを別途用意し ているということは標準のコレクションはそうで はないと暗示しているような? kotlinx.collections.immutable 6
2. 実験・調査 7
Lisper/Clojurianの本能に従ってREPLで試してみる ℹ️ 実行環境 # Kotlin $ kotlinc -version info: kotlinc-jvm
2.0.0 (JRE 22.0.1) # Scala $ scala -version Scala code runner version 3.4.2 -- Copyright 2002-2024, LAMP/ EPFL # Clojure $ clj -version Clojure CLI version 1.11.3.1463 8
Kotlinの List MutableList インスタンスを List 変数に代入する: >>> val xs: MutableList<Int>
= mutableListOf(1, 2, 3) // イミュータブル(?)とされるList型の変数に代入できてしまった >>> val ys: List<Int> = xs >>> ys.add(4) error: unresolved reference: add ys.add(4) ^ >>> xs.add(4) res3: kotlin.Boolean = true >>> xs res4: kotlin.collections.MutableList<kotlin.Int> = [1, 2, 3, 4] // MutableList型の変数xsからの破壊的更新がysに必然的に波及している >>> ys res5: kotlin.collections.List<kotlin.Int> = [1, 2, 3, 4] 9
インターフェース kotlin.collections.MutableList は kotlin.collections.List を継承している ref. 実体は (Javaのミュータ ブルな可変長リスト) >>>
xs::class res6: kotlin.reflect.KClass<out kotlin.collections.MutableLi st<kotlin.Int>> = class java.util.ArrayList >>> ys::class res7: kotlin.reflect.KClass<out kotlin.collections.List<kotl in.Int>> = class java.util.ArrayList MutableList - Kotlin Programming Language java.util.ArrayList 10
List インスタンスをJavaのメソッドで操作する: >>> val zs: List<Int> = listOf(1, 3, 2)
// Javaの破壊的なメソッドがコンパイル/実行時エラーなく呼び出せてしまった >>> java.util.Collections.sort(zs, { a, b -> b.compareTo(a) } ) // イミュータブル(?)とされるListのインスタンスが更新できてしまった >>> zs res10: kotlin.collections.List<kotlin.Int> = [3, 2, 1] 11
listOf に2要素以上を与えて得られる実体は の戻り値と同じ(ミ ュータブルな固定長リスト) >>> listOf<Int>()::class res11: kotlin.reflect.KClass<out kotlin.collections.List<kotl in.Int>>
= class kotlin.collections.EmptyList >>> listOf(1)::class res12: kotlin.reflect.KClass<out kotlin.collections.List<kotl in.Int>> = class java.util.Collections$SingletonList >>> listOf(1, 2)::class res13: kotlin.reflect.KClass<out kotlin.collections.List<kotl in.Int>> = class java.util.Arrays$ArrayList >>> listOf(1, 2, 3)::class res14: kotlin.reflect.KClass<out kotlin.collections.List<kotl in.Int>> = class java.util.Arrays$ArrayList java.util.Arrays.asList 12
参考: Scalaの List ListBuffer インスタンスを List 変数に代入する: が明確に分離されている scala> val
xs: List[Int] = List(1, 2, 3) val xs: List[Int] = List(1, 2, 3) // Listは独自のイミュータブルコレクション scala> xs.getClass val res0: Class[? <: List[Int]] = class scala.collection.immu table.$colon$colon // ミュータブルなListBufferとイミュータブルなListにまったく互換性なし scala> val ys: scala.collection.mutable.ListBuffer[Int] = xs -- [E007] Type Mismatch Error: ------------------------------ // (エラー詳細は省略) ミュータブルコレクションとイミュータブルコレク ションの型階層 13
List インスタンスをJavaのメソッドで操作する: が、破壊的更新はできない (できたらイミュータブルコレクションと呼べない) scala> val zs: List[Int] = List(1,
3, 2) val zs: List[Int] = List(1, 3, 2) // ScalaのListはJavaのCollection/Listと互換性がない scala> java.util.Collections.sort(zs, Ordering[Int].reverse) -- [E007] Type Mismatch Error: ------------------------------ // (エラー詳細は省略) // 内部的な実体を維持しながら(コピーせず) Javaコレクションに変換できる scala> import scala.jdk.CollectionConverters.* scala> val zs_ = zs.asJava val zs_: java.util.List[Int] = [1, 3, 2] // 破壊的更新操作はサポートしていない(実行時エラーになる) scala> java.util.Collections.sort(zs_, Ordering[Int].reverse) java.lang.UnsupportedOperationException 実体を維持したままJavaのインターフェースに適合 するように変換できる 14
参考: Clojureのvector (IPersistentVector) 標準ライブラリに user=> (def xs [1 2 3])
#'user/xs ;; vectorは独自のイミュータブルコレクション user=> (class xs) clojure.lang.PersistentVector ;; IPersistentVectorインターフェースを実装している user=> (instance? clojure.lang.IPersistentVector xs) true ;; Java interopを円滑にするため、java.util.Listも実装している user=> (instance? java.util.List xs) true 独自のミュータブルコレクション はない 15
vectorインスタンスをJavaのメソッドで操作する: Javaのインターフェースを実装しているが、破壊的 更新はできない(できたらイミュータブルコレクシ ョンと呼べない) user=> (def zs [1 3 2])
#'user/zs ;; 破壊的更新操作はサポートしていない(実行時エラーになる) user=> (java.util.Collections/sort zs >) Execution error (UnsupportedOperationException) at java.util. List/sort (List.java:514). 16
3. まとめ 17
イミュータブル(不変)っぽく見えてイミュータブル とは言いがたいデータ構造がある Kotlinの List はその例だといえる immutableではなく read-only (読み取り専用) なインターフェースと呼ぶのが正確と思われる ref.
effectively immutable (実質的にイミュータブル) だと形容されることもあるが、抜け道が残れば当 然ながらイミュータビリティ(不変性)は保証され ないことになる List - Kotlin Programming Language 18
🐬の感想: Kotlin言語/標準ライブラリの設計判断には実用 上の合理性を感じる ある意味でScala/Clojure以上にJava interopを 重視するからこそ必然性があるのかも(?) しかし、純粋な関数とデータで副作用を最小化/ 局所化するプログラミングスタイル(関数型プロ グラミング)を好む私としては、イミュータブル コレクションがデフォルトであってほしかった
(Kotlinでの総合的な開発体験は好印象 😊) 19
Further Reading KotlinのListについて : REPLでの簡単な実験結果のメモ by 🐬 read-only vs immutable
lists in Kotlin, Scala and Clojure Kotlinのコレクションは「不変」と「可変」に分か れていない - kmizuの日記 Kotlin 紹介 - List / MutableList - PHONE APPLI Engineer blog 20
Kotlin, Scala, Clojureのコレクションについて Collections overview | Kotlin Documentation Calling Java
from Kotlin | Kotlin Documentation > Mapped types Mutable and Immutable Collections | Collections | Scala Documentation Conversions Between Java and Scala Collections | Collections | Scala Documentation Clojure - Data Structures > Collections 21
関数型プログラミングについて : 関数型プログラミ ングの考え方と実利の紹介 by 🐬 : 不変かつ永続的なコ レクションの簡単な紹介 by
🐬 JavaからScala、そしてClojureへ: 実務で活きる関 数型プログラミング | ドクセル Clojureコレクションで探るimmutableで persistentな世界 | ドクセル Immutable object - Wikipedia Persistent data structure - Wikipedia 22