Slide 1

Slide 1 text

λ 関数型プログラミング 攻略ガイド 第四回関数型プログラミング(仮)の会 2023-03-24 A Good Way to Learn Functional Programming knih

Slide 2

Slide 2 text

λ 関数型プログラミング 攻略ガイド 第四回関数型プログラミング(仮)の会 2023-03-24 A Good Way to Learn Functional Programming knih 迷走

Slide 3

Slide 3 text

Finally, safely-extensible and efficient language-integrated query PEPM '16: Proceedings of the 2016 ACM SIGPLAN Workshop on Partial Evaluation and Program ManipulationJanuary 2016 Pages 37–48https://doi.org/10.1145/2847538.2847542 Multi-Stage Programming、そして脆弱性レジリエンス × Clean Architecture https://engineering.visional.inc/blog/212/scalamatsuri2020-interview-msp/ 脆弱性レジリエンスを高めるための Clean Architecture https://yamory.io/blog/architecting-for-resilience/ エンタープライズアジャイル開発における品質管理とセキュリティ対策をyamoryで考える https://yamory.connpass.com/event/198588/ Scala3でコードは爆速になるマルチステージプログラミングの考え方 https://logmi.jp/tech/articles/324146 Dotty ではじめるマルチステージプログラミング入門 https://www.youtube.com/watch?v=gpQHgcIIzFY From Tagless-Final to Typed-Final: Program Transformations in the Final Style https://speakerdeck.com/dcubeio/from-tagless-final-to-typed-final-program-transformations-in-the-final-style ContractS Tech Book Vol.1 第8章 型の力で高品質にドメインをモデリングする ー関数型DDDに向けてー. https://nextpublishing.jp/book/14565.html Publications 3

Slide 4

Slide 4 text

● C/C++ ● CPUレジスタ、省メモリプログラミング ● Java、Spring Boot、JavaScript ● オブジェクト指向 ● 独自フレームワーク、テーラリング 4 関数型プログラミングをいかにして学んだか ● 関数型スタイル ● OCaml、Haskell ● (一般化)代数的データ型 ● HOAS、tagless ● モナド ● fold, unfold ● 自然とセキュアコーディング

Slide 5

Slide 5 text

攻略ガイドといえば・・・ 5

Slide 6

Slide 6 text

6 https://twitter.com/lambda_conf/status/803695008100466688

Slide 7

Slide 7 text

SLFPでいうと ● LambdaConf発行 ● 関数型プログラミングに関す る概念・スキルをレベル分け したもの 7 初級 上級 このあたり

Slide 8

Slide 8 text

8 イミュータブルなデータ 二階関数 データの構築&分解 関数合成 第一級関数&ラムダ 代数的データ型 パターンマッチ パラメータ多相 一般的な再帰 型クラス、インスタンス、法則 低次の抽象化(Equal, Semigroup, Monoid 等) 参照透過性、完全性 高階関数 部分適用、カリー化、ポイントフリースタイル GADT 高階カインド型 ランクN型 Folds & Unfolds 高次の抽象化(圏, 関手, モナド) 基本的なOptics 効率的な永続データ構造 存在型 コンビネータを用いたEDSL Codata (Co)Recursion Schemes 一歩進んだOptics 双対的な抽象化(Comonad) モナドトランスフォーマー Freeモナド & Extensible Effects 関数型アーキテクチャ 一歩進んだファンクタ(Exponential, Profunctors, Contravariant) GADTs と Finally Tagless を用いたEDSL 一歩進んだモナド(Continuation, Logic) 型族、関数従属 High-Performance カインド多相 ジェネリックプログラミング 型レベルプログラミング 依存型、シングルトン型 圏論 グラフ簡約 Higher-Order Abstract Syntax 関数型言語のためのコンパイラ設計 Profunctor Optics 初級 上級 The Ladder of Functional Programming

Slide 9

Slide 9 text

9 イミュータブルなデータ 二階関数 データの構築&分解 関数合成 第一級関数&ラムダ 代数的データ型 パターンマッチ パラメータ多相 一般的な再帰 型クラス、インスタンス、法則 低次の抽象化(Equal, Semigroup, Monoid 等) 参照透過性、完全性 高階関数 部分適用、カリー化、ポイントフリースタイル GADT 高階カインド型 ランクN型 Folds & Unfolds 高次の抽象化(圏, 関手, モナド) 基本的なOptics 効率的な永続データ構造 存在型 コンビネータを用いたEDSL Codata (Co)Recursion Schemes 一歩進んだOptics 双対的な抽象化(Comonad) モナドトランスフォーマー Freeモナド & Extensible Effects 関数型アーキテクチャ 一歩進んだファンクタ(Exponential, Profunctors, Contravariant) GADTs と Finally Tagless を用いたEDSL 一歩進んだモナド(Continuation, Logic) 型族、関数従属 High-Performance カインド多相 ジェネリックプログラミング 型レベルプログラミング 依存型、シングルトン型 圏論 グラフ簡約 Higher-Order Abstract Syntax 関数型言語のためのコンパイラ設計 Profunctor Optics 初級 上級 The Ladder of Functional Programming マイクロフレームワークのた めに利用 ドメインモデル・ユースケースを表 現するために利用 某プロダクトで実践

Slide 10

Slide 10 text

10 関数型プログラミングの習得は 数学が絡むのでつまづきやすい説

Slide 11

Slide 11 text

数学は避けて通れない? 11 ● 避けて通れない、というより避けないほうが良い ● 数学的感覚があると精緻なモデリングに役立つ オブジェクト指向を身につけるのにJavaだけ学んでいても本質が 掴みづらいのと同じ

Slide 12

Slide 12 text

方針 ● ちょっとだけ数学的準備をする ● プログラミングを知ることは、その言語を知ること ● モナドうんぬんより、関数脳がつくられることを優先 ○ いろんな言語で関数型スタイルを楽もう 12

Slide 13

Slide 13 text

ショートカットコース 13 Haskell Scala 部分型関係 基礎固め 応用(モナド)

Slide 14

Slide 14 text

ミニマムコース 14 前半ぐらいまで

Slide 15

Slide 15 text

学習ステップ 15 ● 第一級関数 ● 関数適用・関数合成 ● 基本のデータ型 ● リスト、map, filter, fold ● パラメータ多相(多相型) ● 代数的データ型 ● パターンマッチング ● 高階関数 ● 部分適用、カリー化、ポイント フリー ● 再帰・帰納 ● 効率性 ● 無限リスト ● banana split ● 木構造 ● 型クラス・インスタンス・法則 ● モノイド、半群、Equal ● モナドと純粋関数 ● コルーチン ● 継続、CPS ● パーサーコンビネーター 副作用のコントロール力 関数による表現力 基礎

Slide 16

Slide 16 text

進め方 16 忘れる モチベー ション Step 0 Step 1 基礎 Step 2 関数の表現力 Step 3 副作用のコントロール力

Slide 17

Slide 17 text

Step 0: モチベーション ● 精度の高い型を表現できる ○ 取り扱う領域が適切になる(狭まる)=テスト範囲を小さくできる ● 型の浸透 ○ 影響範囲が特定しやすくなり、変更容易性が高まる ● マイクロフレームワークをつくるのに良い 17

Slide 18

Slide 18 text

Step 0: いったん忘れる ● 意識しないと従来のプログラミングの習得スタイルにはまってしまう ○ 条件分岐、ループ処理、モジュール・クラス・・・ ● 関数型プログラミング言語のベース理論 ○ Haskell → System F ○ OCaml → ML ○ Scala3 → DOT 18 柳川 範之、為末 大. Unlearn(アンラーン) 人生100年時代の新しい「学び」. 日経BP、2022.

Slide 19

Slide 19 text

Step 1: 基礎 ● 代数的データ型とパターンマッチングが特に重要(個人的に) ● 関数と集合 ● 型は値の集合 ○ 依存型が出てくるまではこの理解でOK ● すべては関数(ラムダ計算) ● 関数型の基本スタイルを学ぶ 19

Slide 20

Slide 20 text

数学的準備 20 未定義は例外につながる コンパイル時に検知できない

Slide 21

Slide 21 text

数学的準備 ● 離散構造 21 https://www.cs.tsukuba.ac.jp/~kam/lecture/discrete2017/

Slide 22

Slide 22 text

型は値の集合 22

Slide 23

Slide 23 text

集合 23 f: A → B どちらが取り扱う範囲が広 いか?

Slide 24

Slide 24 text

数学的準備 ● ラムダ計算 24 住井 英二郎(2005). ラムダ計算入門 http://www.kb.ecei.tohoku.ac.jp/~sumii/class/keisanki-software-kougaku-2005/lambda.pdf.

Slide 25

Slide 25 text

数学的準備 ● ラムダ計算 ○ 計算論理学 ■ https://www.cs.tsukuba.ac.jp/~kam/complogic/ 25 http://www.kb.ecei.tohoku.ac.jp/~sum ii/class/keisanki-software-kougaku-2 005/lambda.pdf

Slide 26

Slide 26 text

Step 1: 基礎 ● 素直にOCamlで取り組むのが吉 ● セットアップが面倒かも、、、 ○ emacs + tuareg ● 言語は非常にシンプルで覚えやすい ● 数式は一切でてきません 26 授業資料 http://pllab.is.ocha.ac.jp/~asai/book-mov/

Slide 27

Slide 27 text

Step 1: 基礎 ● 理解を深めるためにプログラミング言語をつくる ● 教材 ○ 筑波大学 ソフトウェアサイエンス実験 ○ http://logic.cs.tsukuba.ac.jp/jikken/ 27 関数プログラミングをするということは、 関数型プログラム言語を知るということ おすすめ

Slide 28

Slide 28 text

ミニ言語をつくる(メニュー) ● セットアップ ● 言語の構成要素 ○ 構文(Syntax) ○ 意味論(Semantics) ○ 型付規則(Typing Rule) ● 基本的なインタープリター ○ 基本的な言語機能 ○ 構文・意味論 ● 型検査と型推論 ○ 型システム ● 簡単なコンパイラの作成 ○ 抽象機械 28 e ::= x 変数 | let x = e in e let式 | let rec f x = e in e let-rec式 | fun x -> e 関数 | e e 関数適用 | true 真理値リテラル(定数) | false 真理値リテラル(定数) | if e then e else e if式 | n 自然数リテラル (n は自然数 0, 1, 2, ...) | - e 整数演算(符号の反転) | e + e 整数演算(足し算) | e * e 整数演算(かけ算) | e / e 整数演算(割り算) | e = e 等しさ(整数と真理値) | e > e 大小比較(整数) | e < e 大小比較(整数)

Slide 29

Slide 29 text

Step 2: 表現力を高める ● 慣れないうちは、ついつい手続き・破壊的操作に戻りがち ● このフェーズで関数脳をつくる ● 処理を関数として分割すると、品質担保しやすい ○ 特に品質担保したいところは、全域関数として切り出す ● 遅延評価、foldl,foldrの特性が理解できればひとまずOK 29 Graham Hutton. 1999. A tutorial on the universality and expressiveness of fold. おすすめ

Slide 30

Slide 30 text

Step 3: 副作用のコントロール力 ● いかにエラーを型として表現・設計するか ● 副作用を含むエラーを型として表現したときに、それらをどうハンドリ ングするか ○ ここが従来の例外ベースのエラーハンドリングに比べて難しいポイント 30 Philip Wadler (1992). The essence of functional programming.

Slide 31

Slide 31 text

Step 3: 副作用のコントロール力 ● パーサーコンビネーターが便利 ○ せっかくなので副作用コントロールとは別に、パーサーコンビネーターを習得しておく と吉。外部サービスのデータ取り込み等。 ○ 精緻なパース処理が品質高く、楽々記述できる 31 今となっては動かないところもあるので、 雰囲気だけ掴んで、パーサーコンビネー タライブラリのマニュアル・サンプルを読 むのが良い おすすめ

Slide 32

Slide 32 text

まとめ 32

Slide 33

Slide 33 text

まとめ 33 ● まず頭を空っぽにする ● 関数型プログラミング言語として作られた言語で学ぶのが近道 ● すべては関数(という気持ち) ● 関数型プログラミングは実用的 ○ 学術的な側面が垣間見えるので、一部の人たちが趣味でやっているように見えてしまう かもしれませんが、高品質かつ高生産につくれる ● 適用・導入する技術レベルは予め決めておいたほうが良い ○ オンボーディングとセット

Slide 34

Slide 34 text

参考文献 ● 柳川 範之、為末 大(2022). Unlearn(アンラーン) 人生100年時代の新しい「学び」. 日経BP. ● 浅井 健一(2007). プログラミングの基礎. サイエンス社. ● Miran Lipovača著、田中英行/村主崇行 共訳(2012).すごいHaskellたのしく学ぼう!. オーム社. ● 大川徳之(2018).関数プログラミング実践入門.技術評論社. ● Benjamin C. Pierce著、住井 英二郎 監訳、遠藤 侑介、酒井 政裕、今井 敬吾、黒木 裕介、今井 宜洋、才川隆文、今井 健男 訳(2013). 型システム入門. オーム社. ● Paul Chiusano、Rúnar Bjarnason 著、株式会社クイープ 訳(2015). Scala関数型デザイン&プログラミング. インプレス. ● Noel Welsh、Dave Gurnell(2020). Scala with Cats. Underscore Consulting LLP. ● RichardBird 著、山下伸夫 訳(2017). Haskellによる関数プログラミングの思考法. ドワンゴ. ● Chris Okasaki 著、稲葉一浩、遠藤侑介 訳(2017). 純粋関数型データ構造. ドワンゴ. ● 原啓介(2020). 集合・位相・圏. 講談社. ● 鹿島 亮(2009).数理論理学. 朝倉書店. ● David I. Spivak 著、川辺 治之 訳(2021). みんなの圏論. 共立出版. ● Hutton, Graham & Meijer, Erik. (1996). Monadic Parser Combinators.Technical report NOTTCS-TR-96-4. Department of Computer Science, University of Nottingham. ● Graham Hutton. (1999). A tutorial on the universality and expressiveness of fold. Journal of Functional Programming, 9(4), 355–372. ● Philip Wadler. (1992). The essence of functional programming. In Proceedings of the 19th ACM SIGPLAN-SIGACT symposium on Principles of programming languages (POPL '92). Association for Computing Machinery, New York, NY, USA, 1–14. ● Meijer, E., Fokkinga, M., Paterson, R. (1991). Functional programming with bananas, lenses, envelopes and barbed wire. In: Hughes, J. (eds) Functional Programming Languages and Computer Architecture. FPCA 1991. Lecture Notes in Computer Science, vol 523. Springer, Berlin, Heidelberg. ● 浅井 健一(2011). shift/reset プログラミング入門. ● 亀山幸義、海野広志(2017). 離散構造. https://www.cs.tsukuba.ac.jp/~kam/lecture/discrete2017/ (2023年アクセス) ● 住井 英二郎(2005). ラムダ計算入門. https://www.kb.ecei.tohoku.ac.jp/~sumii/class/keisanki-software-kougaku-2005/lambda.pdf(2023年アクセス) ● 亀山幸義(2013). ソフトウェアサイエンス実験 関数プログラミング. https://www.logic.cs.tsukuba.ac.jp/jikken/(2023年アクセス) 34

Slide 35

Slide 35 text

EOF 35