🐪

「プログラミングの基礎」を読んだ感想

2023/07/11に公開

プログラミングの基礎を読んだ感想になります。

普段はGoやPHPを書いていて、関数型言語に興味はありつつも挫折しがちだったので通読できてよかった。(赤黒木とヒープは解いてませんがそれ以外は解きました。)

関数型への疑問

関数型のメリットとして、状態を持たない、参照透過性があることでバグを生み出しにくいというのが言われています。
ただ手続き型やオブジェクト指向チックな言語を業務で使っている自分からすると下記の疑問がありました。

  • モデリング対象は状態を持つよね?
  • 再代入できないけど、同じ変数名でletしたら再代入したのと一緒だよね?

今回Ocamlのコードを書いてみて、関数型言語は状態や再代入する部分は最小限にするように言語側からサポートしてくれる言語という認識になりました。

手続き型やオブジェクト指向言語を使ってロジックを書いているとバグが発生したときに状態を追いづらいことになり、デバッグに時間がかかりがちですが、関数型言語だとそのようなコードを書く前に「お前それ副作用あるけど大丈夫?、ちゃんと認識している?」と問いかけてくれます。

その問いかけの強弱がHaskell > Ocaml >> 手続き型やオブジェクト指向言語って感じでしょうか。

ここからは本でよかった部分、参考になった部分になります。

テストファースト

本を通して、デザインレシピと呼ばれるプログラミングのやり方が説明されていて、
関数の意図、型、例(テスト代わり)を書いていくスタイルで進みます。

ちゃんとテスト書いてからロジックを書くというのが徹底されており、2007年に発行された本なのにこのやり方自体は全く古びていないなーと思いました。

実際の例はこんな感じです。

double.ml
(* 目的: 整数が与えられたら、2倍して返す*)
(* double : int -> int *)
let double x = 2 * x 

(* テスト *)
let test1 = double 0 = 0
let test2 = double 2 = 4
let test3 = double 8 = 16

インタプリタ上でファイルを読み込むとテスト結果が出てきます。

$ #use "double.ml";;
val double : int -> int = <fun>
val test1 : bool = true
val test2 : bool = true
val test3 : bool = true

テストライブラリなど全く使っていない簡素なテストですが、テストでやりたいことがちゃんとできていて素晴らしいと思いました。

再帰関数

関数型言語といれば再帰ということで、整数やリストを使った再帰関数が出てきます。
かなりシンプルなものから順にやっていくので挫折することもないし、普段使っているmap、filter、foldなどの理解も深まりました。

逐次実行、副作用

純粋関数型ではないので手続き的に書いたり、副作用を使う方法も最後に紹介されています。
逆に言えばここまでは関数しか使わずにコードが書けます。
バグの少ないコードを書くためになるべく副作用のない関数を使って書いてねというのが本の構成からも読み取れます。

まとめ

プログラミングの基礎という名に偽りなく、テストファーストなプログラミングが学べるよい本でした。
関数型の考え方や副作用についても学べ、他の言語を使っているときもこの辺が副作用あるなーとか、参照透過性のある関数を書こうとか意識できるようになりそうだと感じたので、普段関数型言語を使っていないけど関数型の考え方を学ぶのにも良い本だと思います。
Haskell(主にモナド周り)とかで関数型難しすぎと思う自分のような人にちょうどいい感じの本でした。

Discussion