第4回プログラミングの基礎読書会まとめ

5.3〜6章終了まで。

5.3

これは先にテストを直すべきじゃないのかな?

5.4

手続き型言語を知っているが、関数型言語を学ぶ価値として式と文を明確に意識するようになる点が挙げられる。
なので、

if (hogehoge) {
  hoge = true;
} else {
  hoge = false;
}

みたいなコードの価値*1をちゃんと考えられるようになる。

5.5

abs_valueのfloatを=で比較しているのが気になる。
これぐらいなら大丈夫だと思うけど、浮動小数点を=でテストするとのは怖い気が。


微妙なケースとして、0.0をやるなら、MAX/MIN Valueもやりたいところかも。
floatの場合はともかく、intでやる場合、2の補数表現の表現限界から、

min_int = -min_int;;

はtrueとなる。とかという事例は有名なので。

32bit符号付整数*2を例にとると、min_int = 0x80000000。
符号を変える場合、全ビットを反転させて1を足す。
故に、0x7FFFFFFF + 1 = 0x80000000となり、答えは変わらない。


floatにおいて、その符号を反転させる単項演算子は(-.)であり、(-)では型が違うと怒られる。
一方で、-1.0はリテラルであるため有効。-x (x: float)はコンパイルエラーとなる。

5.6

15以上、25以下の境界っていうなら、14,15,16,24,25,26あたりが対象になる気がするんだけれど、なぜ7,20,28がテスト対象何だろうか。
あと、気温(摂氏)だから-274以下の場合不正になったりするという隠し仕様が出てきたりも。


ここで書かれている、(15 <= t && t <= 25)は非常に分かりやすく、(t >= 15 && t <= 25)などとすると、意味解析に少し時間がかかるので、分かりやすい記述を心掛けたい。

6.1

エラーメッセージはきちんと読みましょう。英語でも。
それだけで大体の問題は分かります。

6.3

if 2 > 3 then sin 3.14 cos 0.0

とした場合のエラーメッセージは"This function is applied to too many arguments, ..."となる。
コンパイラの仕組み的に、構文解析→意味解析をするように思うので、関数の引数の数を検出するより先に、elseが無いというメッセージが出てもよさそうな物ですがどうなんだろ。


インタプリタとしての挙動は分かるんだけど、ocamlc, ocamloptで実行してみたけれど同一のメッセージしか出力されなかったので、いったいどうなっているのかなぁと。

6.5

単位に着目すればこの場合の問題はある程度解決できる。
例えば、面積の単位はm^2【単位:平方メートル】であるが、この場合は円周【単位:メートル】であるので、単位が合わない時点で問題を検出できる。
この仕組みを実現している言語として、F#、C++(Boostを利用、だったかな?)がある。

*1:もちろんこのコード自体はダメな方向の価値しか持たない。hoge = hogehoge; で十分:-D

*2:なお、OCamlの場合は31bit(64bitの場合63bit)となるが、原理は変わらない