BuriKaigi2025-純粋関数

8.7K Views

February 01, 25

スライド概要

BuriKaigi2025の登壇資料です。
https://burikaigi.dev/
『純粋関数基礎 嬉しいこと尽くしな純粋関数を開発に組み込もう!』

X: @hk_it7 河野裕隆


要約(AI)
純粋関数は、プログラミングにおいて同じ入力に対して常に同じ出力を返し、副作用が生じない関数です。この特徴により、テスト容易性が向上し、思わぬ不具合を防ぐことができます。また、純粋関数により関数の詳細を追わずに済む技術を提供します。これらのメリットを踏まえ、純粋関数を積極的に開発に取り入れることが重要です。

profile-image

Ruby/Javaプログラマー。エンジニアリングマネージャー。 軽度の広く浅いオタク。

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

関連スライド

各ページのテキスト
1.

TORANOANA Lab 純粋関数基礎 嬉しいこと尽くしな純粋関数を開発に組み込もう! 虎の穴ラボ 河野 裕隆 BuriKaigi 2025 #burikaigi #burikaigi_m Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

2.

自己紹介 河野 裕隆(こうの ひろたか) 好きなもの ● 2019/08~ 虎の穴ラボ ● VOCALOID(初音ミク) ● 新規開発チーム ● 謎解き、クイズ ○ ● クリエイティア他 X: @hk_it7 その他活動 ● 東葛.dev主催者 ● エンジニアがこの先生きのこるためのカンファレンス2025 ○ コアスタッフ(3/9)🍄 2 Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

3.

自己紹介 河野 裕隆(こうの ひろたか) ● 2015:私立文系大学卒 ● 2015~:中小SIerから派遣されてtoBシステムのJavaプログラマ ● 2019~:現職で通販サイトのJavaプログラマ ● 2020~:現職でファンクラブサイトのRubyプログラマ ● 2022~:Vue.js/TSのプロジェクト開始 ● 現在:エンジニアリングマネージャー ○ テック/ピープル/プロダクト/プロジェクト全部見る 3 Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

4.

📢今日伝えたいこと Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

5.

純粋関数はいいぞぉ! Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

6.

⚠注意 Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

7.

純粋関数型言語 の話はしません! Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

8.

アジェンダ ● 純粋関数とはなにか ○ ● ● 「純粋関数ではない」とはなにか 純粋関数によって嬉しいこと ○ テスト容易性 ○ 副作用による不具合の防止 ○ 関数の詳細を追わない技術 純粋関数への置き換え方法考察 Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

9.

純粋関数とはなにか Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

10.

純粋関数とはなにか 辞書的な意味 > 純粋関数 (pure function)とは、プログラミングにおける関数のうち、同じ入 力に対して常に同じ出力を返し、副作用が生じないもの。 引用元:IT用語辞典 e-Words https://e-words.jp/w/%E7%B4%94%E7%B2%8B%E9%96%A2%E6%95%B0.html 例 ● 2つの引数を取り、引数の合計を返す関数 ● 図形オブジェクトを引数に取り、図形の面積を返す関数 Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

11.

純粋関数とはなにか - サンプルコード 2つの引数を取り、引数の合計を返す関数:Java Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

12.

純粋関数とはなにか - サンプルコード 2つの引数を取り、引数の合計を返す関数:TypeScript Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

13.

純粋関数とはなにか - サンプルコード 2つの引数を取り、引数の合計を返す関数:Ruby Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

14.

純粋関数とはなにか 辞書的な意味 > 純粋関数 (pure function)とは、プログラミングにおける関数のうち、同じ入 力に対して常に同じ出力を返し、副作用が生じないもの。 引用元:IT用語辞典 e-Words https://e-words.jp/w/%E7%B4%94%E7%B2%8B%E9%96%A2%E6%95%B0.html ● 関数 ● 入力 ● 出力 ● 副作用 Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

15.

純粋関数とはなにか 関数(ファンクション)とはなにか ● 与えられた値(引数)を元に 何かしらの処理をして結果(戻り値)返すもの ● サブルーチンの一種 ○ ex)Pascalではサブルーチンをファンクションとプロシージャを 区別する ■ ファンクション:戻り値あり ■ プロシージャ:戻り値なし Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

16.

純粋関数とはなにか 関数(ファンクション)とはなにか ● 与えられた値(引数)を元に 何かしらの処理をして結果(戻り値)返すもの ● メソッドはオブジェクトの中にある関数 ○ Javaはトップレベルにクラスしか宣言できない ■ 基本的に関数はクラス(オブジェクト)の中にある <=>Java 8のラムダ式 ● 第一級オブジェクトとして関数が定義できる Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

17.

純粋関数とはなにか 参考:Javaの”関数”=>JLS見ても関数型インターフェイス系の話のみ ● メソッド参照、ラムダ式により関数を定義できる(Java8~) ● sum関数はどのオブジェクトにも属していない=メソッドではない Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

18.

純粋関数とはなにか 引数とはなにか ● 関数やメソッド、プロシージャに渡す値 ● 関数定義で書く引数:「仮引数」 ● 関数呼び出しで書く引数:「実引数」 仮引数 実引数 Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

19.

純粋関数とはなにか 副作用とはなにか ● 式の評価値を得る以外の状態の内部変化 ● グローバル変数、ローカル定数の変更、I/O等 ○ 「ファイルに書き込む」も副作用 Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

20.

「純粋関数ではない」とはなにか 純粋関数 ● 同じ入力に対して常に同じ出力を返す ● 副作用が生じないもの ↓ 非純粋関数 ● 同じ入力でも異なる出力になる場合がある ● 副作用がある Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

21.

「純粋関数ではない」とはなにか 副作用を使ったプログラムの例 Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

22.

「純粋関数ではない」とはなにか 常に同じ出力にならない例 Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

23.

「純粋関数ではない」とはなにか 常に同じ出力をしない例 Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

24.

章まとめ:「純粋関数ではない」とはなにか(再掲) 純粋関数 ● 同じ入力に対して常に同じ出力を返す ● 副作用が生じないもの ↓ 非純粋関数 ● 同じ入力でも異なる出力になる場合がある ● 副作用がある ○ 実行すると他に何か影響を与える Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

25.

アジェンダ ● 純粋関数とはなにか DONE ○ ● ● 「純粋関数ではない」とはなにか 純粋関数によって嬉しいこと ○ テスト容易性 ○ 副作用による不具合の防止 ○ 関数の詳細を追わない技術 純粋関数への置き換え方法考察 Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

26.

純粋関数によって 嬉しいこと Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

27.

純粋関数によって嬉しいこと ● テスト容易性 ○ ● 副作用による不具合の防止 ○ ● テストコードが書きやすい 思わぬ参照での不具合防止 関数の詳細を追わない技術 ○ 副作用がないのでインプットとアウトプットのみ見れば良い それぞれ深堀りしていきます Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

28.

テスト容易性 ● 同じ引数なら常に同じ値を返す ○ システムの状態や他オブジェクトに依存しない <=>フレーキーテスト 実施するたびに結果が変わる可能性がある Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

29.

テスト容易性 Rubyのコード:is_discount_day_a?は純粋関数 どちらのほうがテストが書きやすいでしょう? Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

30.

テスト容易性 Javaのコード Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

31.

テスト容易性 Javaのコード Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

32.

副作用による不具合の防止 ● グローバルな変数を共有して使っていると思わぬ不具合を生む ● DBで設定値の管理など ● DBのステータス管理によるデッドロックもある意味これが原因 Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

33.

副作用による不具合の防止 Ruby:こんなコード誰も書かないと思いますが...... Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

34.

関数の詳細を追わない技術 ● 副作用がないのでインプットとアウトプットのみ見れば良い ○ とはいえ純粋関数であることは外からわからない ○ ドキュメントに書く?(JSDoc/JavaDoc/RDocなど) =>副作用があると影響範囲を調べる必要があったり ● チーム内の習熟度にもよる ● 実際は純粋関数かどうかより適切な命名かどうかのほうが大きい ○ 副作用ありそうな命名:update/insert/引数に対象がないadd ○ 副作用なさそうな命名:get/calc Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

35.

章まとめ:純粋関数のメリット ● テスト容易性 ○ ● 副作用による不具合の防止 ○ ● テストコードが書きやすい 思わぬ参照での不具合防止 関数の詳細を追わない技術 ○ 副作用がないのでインプットとアウトプットのみ見れば良い =>適切な命名が前提 Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

36.

アジェンダ ● 純粋関数とはなにか DONE ○ ● ● 「純粋関数ではない」とはなにか 純粋関数によって嬉しいこと DONE ○ テスト容易性 ○ 副作用による不具合の防止 ○ 関数の詳細を追わない技術 純粋関数への置き換え方法考察 Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

37.

純粋関数への 置き換え方法考察 Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

38.

改めて純粋関数の条件 ● 同じ入力に対して常に同じ出力を返す =>状態に依存しない ● 副作用が生じないもの =>(関数の外側の)状態を変更しない Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

39.

状態に依存しないために Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

40.

状態に依存しないために ● みんな大好き(?)な図 ○ 依存性のルール(内側のものは外側に依存しないようにする) この考え方をもとにコードを整理し直す 状態はできるだけ外側に持ち、内側に伝播させていくことで 内側のコードの純粋関数の割合をあげていく Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

41.

状態に依存しないために 内側から ● ドメイン固有のルール ● アプリ固有のルール ● 外界とのやり取り ● DBやUI、FW:外界 アプリ固有のルール(実装)の 内側を極力純粋関数にしていく Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

42.

状態に依存しないために Q. なぜ「外界とのやり取り」や「DBやUI、FW:外界」を純粋関数にし ないのか A. 外界とのやり取りはIO(副作用)やDBの参照(状態への依存)が発生 するため (例)DBにselectを投げる=>取得できる件数や情報はDBの状態 に依存する モナドで解決するのチョットツライ Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

43.

状態に依存しないために ● Ruby on Railsと相性が悪い...... ● DB(スキーマ)とModelの密結合 ○ 状態:Modelで管理 ○ ドメインロジック:Modelで管理 どうするか? ● Rails wayに乗り、状態依存を許容する ● Usecase層やModelからDomain層を作る(Rails wayから外れる) ○ ActiveRecordをRepositoryのように使うイメージ Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

44.

副作用を生じさせないために ● 変数等はイミュータブルにする ○ 言語機能を活用する ■ Java:Record、List.of() ● ■ clone()はちょっと使いにくい TypeScript:Readonly/setIn/スプレッド構文 Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

45.

副作用を生じさせないために ● コードレビューで見ていく ○ チームとして心がけていくことでコード品質が上がり、認知負荷 が下がっていく ○ メソッド内でオブジェクトを書き換えるなどはしないように Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

46.

副作用を生じさせないために ● Staticおじさんは悪くない ○ OOP文脈では忌避されがちだが...... ○ 純粋関数はオブジェクトの状態に依存しないのでインスタンス単 位で操作するメリットは薄い ○ 主にJavaの話 ■ クラスを名前空間(コンテキスト)としてStaticメソッドを 作成することで自然と状態に依存しないコードになる ○ Ruby on Railsだと割とクラスメソッドで関数定義するので文化差 Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

47.

副作用を生じさせないために ● ありそうな疑問 ○ 引数増えるのでは? ■ 増えます ■ あまりにも増えすぎるようなら責務が大きいか疑う ■ DTO(Data Transfer Object)にまとめることも視野 Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

48.

副作用を生じさせないために ● ありそうな疑問 ○ GRASP原則の情報エキスパートなどと反する部分があるのでは? ■ 部分的にはそう ■ オブジェクトが自分の状態を参照して結果を導出することを 避けているので ■ イミュータブルにしてオブジェクト内の変数を参照すること で達成していく ● インスタンス単位で冪等性を担保する方向 Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

49.

章まとめ:純粋関数で実装していくために ● まずは依存関係の整理から ○ ● DBや外部に依存するところをドメインロジックと切り離す オブジェクト指向のパラダイムと対立するものではない ○ 部分的に取り入れていこう! ○ 疎結合はOOPでも望むところだったはず Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

50.

本日のまとめ Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

51.

「純粋関数ではない」とはなにか(再掲) 純粋関数 ● 同じ入力に対して常に同じ出力を返す ● 副作用が生じないもの ↓ 非純粋関数 ● 同じ入力でも異なる出力になる場合がある ● 副作用がある ○ 実行すると他に何か影響を与える Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

52.

純粋関数によって嬉しいこと ● テスト容易性 ○ ● 副作用による不具合の防止 ○ ● テストコードが書きやすい 思わぬ参照での不具合防止 関数の詳細を追わない技術 ○ 副作用がないのでインプットとアウトプットのみ見れば良い Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

53.

置き換え方法考察 ● ある程度どんな言語でも実践できる(はず) ● ドメインロジックから進めていく ○ 開発者全員に考え方を浸透させる => テストファーストで進めるなど ● 言語機能を活用する ○ オブジェクト指向言語でもパラダイムを取り入れている ■ ○ Java:switch式/パターンマッチなど 新しいバージョンの新機能を使えるように準備することも大切 Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

54.

純粋関数はいいぞぉ! 大事なことなので(略 Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

55.

最後に一言 Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.

56.

ここまで言ってきたけど 要はバランス ありがとうございました!! Copyright (C) 2024 Toranoana Lab Inc. All Rights Reserved.