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
Context Oriented Programming of Kotlin
Search
Yuki Toyoda
September 19, 2025
5.3k
3
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Context Oriented Programming of Kotlin
Yuki Toyoda
September 19, 2025
More Decks by Yuki Toyoda
See All by Yuki Toyoda
パフォーマンスクリティカルな領域へのRust活用戦略
helloyuk13
4
880
カジュアルコントリビュータと学ぶRustコンパイラ
helloyuk13
3
2k
2025 年の Rust はどこに向かっているのか?
helloyuk13
6
1.5k
RustでWeb開発コソコソ噂話
helloyuk13
15
20k
SeaQL Projectsについて
helloyuk13
1
650
年末ですし、今年のRustの進捗の話をしましょう
helloyuk13
2
3.1k
SwiftでAWS Lambda
helloyuk13
0
280
Rustハンズオン@エウレカ社
helloyuk13
22
11k
Rust ハンズオン第6回 ベアメタル Rust 編
helloyuk13
0
460
Featured
See All Featured
DBのスキルで生き残る技術 - AI時代におけるテーブル設計の勘所
soudai
PRO
66
55k
Utilizing Notion as your number one productivity tool
mfonobong
4
320
Measuring & Analyzing Core Web Vitals
bluesmoon
9
870
Money Talks: Using Revenue to Get Sh*t Done
nikkihalliwell
0
250
Embracing the Ebb and Flow
colly
88
5.1k
Joys of Absence: A Defence of Solitary Play
codingconduct
1
400
Navigating Team Friction
lara
192
16k
HU Berlin: Industrial-Strength Natural Language Processing with spaCy and Prodigy
inesmontani
PRO
0
410
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.2k
Leo the Paperboy
mayatellez
7
1.8k
A better future with KSS
kneath
240
18k
Documentation Writing (for coders)
carmenintech
77
5.4k
Transcript
Kotlinの「コンテクスト指向プログラミング (Context Oriented Programming)」 2025/09/19 Nextbeat Tech Bar:第七回関数型プログラミング(仮)の会
目次 自己紹介 Kotlinにおける高階関数と拡張関数 Kotlinの高階関数はコンテクストを作る Context Oriented Programming (COP) Context ParametersによるCOPの拡張
関数型プログラミングからの影響 まとめ 1
自己紹介 yuki (X: @helloyuki_) 所属: ソフトウェアアーキテクト @ Sansan株式会社 rust-lang/rustのコントリビュータやRust.Tokyoなど 以前はScalaエンジニアで、今はKotlinエンジニアをしている
2
免責事項 5分で細かく解説はできません!ごめんなさい。 代わりに細かい解説を含む記事を書きました。この資料を手がかりにしつつも、 気になる点があれば記事をご覧ください。 Kotlinの「コンテクスト指向プログラミング」とは何か?: https://blog- dry.com/entry/2025/09/19/132623 3
Kotlinにおける高階関数と拡張関数 Kotlinには高階関数がある。 fun foo(action: Actinable -> Unit): Unit 4
Kotlinにおける高階関数と拡張関数 また、拡張関数もある。特定の型に対して実装をあとから継ぎ足しできるイメージの機能。 < レシーバ>.関数名() で実装する。 // 拡張関数 fun Extendable.foo(): Unit
// メンバー内拡張関数 interface SomeScope { fun Extendable.foo(): Unit } 5
Kotlinの高階関数はコンテクストを作る 高階関数はブロックとして記述することができる。これが「コンテクスト」を作る。 class DatabaseContext { fun startTransaction(block: (Transaction) -> Unit):
Unit = TODO() } class Transaction fun callScopeFunctions() { // applyはKotlinのスコープ関数と呼ばれる関数のひとつ // fun <T> T.apply(block: T.() -> Unit): T DatabaseContext().apply { // DatabaseContextのコンテクスト startTransaction { tx -> // Transactionのコンテクスト } } } 6
Context Oriented Programming 高階関数の作るコンテクストと拡張関数とを組み合わせると、コンテクストに応 じて利用できる関数が切り替わる実装をできる。 KotlinではこれをContext Oriented Programmingと呼ぶ。 An introduction
to context-oriented programming in Kotlin: https://proandroiddev.com/an- introduction-context-oriented-programming-in-kotlin-2e79d316b0a2 Kotlinのコルーチンはこれを使ってよくデザインされた代表例だと思う。 7
CoroutineScope kotlinx.coroutinesというライブラリに入っている機能。 coroutineScope という関数が CoroutineScope のコンテクストを生成し、その中 であればたとえば async などの関数を呼び出せる。 この実装にはまさに、高階関数と拡張関数が利用されている。
8
CoroutineScope coroutineScope 関数はブロックとしてCoroutineScopeのレシーバ付き関数リテラルを受け 取る。 async 関数は CoroutineScope の拡張関数になっている。 // coroutineScope関数
suspend fun <R> coroutineScope(block: suspend CoroutineScope.() -> R): R // async関数 fun <T> CoroutineScope.async( context: CoroutineContext = EmptyCoroutineContext, start: CoroutineStart = CoroutineStart.DEFAULT, block: suspend CoroutineScope.() -> T ): Deferred<T> 9
CoroutineScope これらを組み合わせると、 coroutineScope のコンテクスト内で async 関数を呼び出せる。 import kotlinx.coroutines.async import kotlinx.coroutines.coroutineScope
suspend fun callCoroutine() { coroutineScope { // async関数はCoroutinesScopeのコンテクスト内でのみ呼び出せる。 val firstTask = async { highLoadFunction() } val secondTask = async { highLoadFunction() } // Continues... } } 10
Context ParametersによるCOPの拡張 さらにKotlin 2.2.0になって、コンテクスト情報を伝播させられるContext Parametersという実験的な機能が実装された。 Scalaのimplicitsによく似ている。 11
Context ParametersによるCOPの拡張 関数に context(ctx: Context) を追加すると、裏で自動でコンテクストを伝播してくれる。 一方で、コンテクストがきちんと切り出されていない箇所で呼び出されるとコンパイルエラー で検知される。 context(ctx: Context)
fun delegateContext() = ctx.call() fun main() { with(Context) { // これは問題ない delegateContext() } // コンテクストの切り出されていない箇所で呼び出すとコンパイルエラーになる delegateContext() } 12
Context ParametersによるCOPの拡張 これを利用すると、たとえば下記を実装できる。 いわゆるモノイド。 型つきエラーハンドリング(Raise DSL)。 Raise DSLを今回は紹介する。 13
型つきエラーハンドリング(Raise DSL) // 今回のコンテクスト interface Raise<E : Exception> { //
今回はエラーを単に送出するだけにする fun raise(error: E): Nothing = throw error } // AppError用のコンテクストをハンドリングする関数を定義する。 inline fun <T> handle(block: context(Raise<AppError>) () -> T): T { return try { val raiseImpl = object : Raise<AppError> {} with(raiseImpl) { block() } } catch (e: Exception) { // 何かしらのハンドリングをする。今回は便宜のために単に呼び出し元に伝播する。 throw e } } 14
型つきエラーハンドリング(Raise DSL) sealed class AppError : Exception() { object NegativeNumber
: AppError() } context(raiseCtxt: Raise<AppError>) fun validateNumber(x: Int): Int { if (x < 0) { raiseCtxt.raise(AppError.NegativeNumber) } else { return x } } fun callRaiseDSL() { // こちらは通常のバリデーションが通り、値が返ってくる。 val result = handle { validateNumber(1) } // バリデーションの結果AppError.NegativeNumberが送出される。 val error = handle { validateNumber(-1) } } 15
関数型プログラミングからの影響 Context ParametersのDesign Docでも言及があるが、いわゆる型クラスに近い概 念と言える? また、コンパイル時にコンテクストが十分かどうかを検査することから、 Coeffects的だと言える。 Raise DSLはAlgebraic Effectに似ている。
など。 16
まとめ KotlinにはContext Oriented Programmingという考え方がある。 これは結構関数型プログラミングで議論されるコンセプトの影響を受けている。 17
参考文献 KEEP-0259: https://github.com/Kotlin/KEEP/blob/main/proposals/KEEP-0259- context-receivers.md KEEP-0367: https://github.com/Kotlin/KEEP/blob/main/proposals/KEEP-0367- context-parameters.md Functional Error Handling
in Kotlin: Part 3 - The Raise DSL: https://rockthejvm.com/articles/functional-error-handling-in-kotlin-part-3-the-raise- dsl 18