JavaScript を初めて少し経つと、関数型の考えを取り込んで書いた方が効率が良いフェーズがくると思います。特に React などの View 用ライブラリを使い出すと、自然とその考えかたに影響を受けたコードを書くことになります。

さらにこれを推し進め、関数型の利点を取り込んでいきたいと思い、いくつか本を読んだのですが、以下二冊が特に JavaScript をメインに書いている人にとってはわかりやすい本だと思いました。

「関数型プログラミングの基礎」は JavaScript で説明が進むので、JavaScript を書く人間がとても入っていきやすいです。しかも情報工学に関する知識もつくので素晴らしい。ただ、抽象度がそれなりに高いので、本腰を入れて読む必要があります。少し JavaScript を勉強した、くらいの入門者ではつまづく可能性があるので、まずは JavaScript そのものに慣れ親しんでから、この本に取り組むことをお勧めします。

「プログラミングの基礎」は、この記事の本題である OCaml が使われている書籍なのですが、OCaml は関数型言語であり強い型付け言語でもあり、加えてオブジェクト指向でもあり、手続き型でもあるので、JavaScript を書いている人間が、関数型とそれから TypeScript 等の静的型付け言語へ入っていくためにちょうどいい導入になるなと感じました。

もちろん上記 JavaScript による関数型の本から入って、同時に TypeScript を使い始めてもいいのですが、どうやら TypeScript のような静的型付け言語を使っている人たちは、JavaScript 以外の静的型付け言語で「型付け言語」について習得していて、そのスキルの延長線上で TypeScript を書いているようなのです。

そういう意味で、OCaml で静的型付けの性質について学ぶのはかなり効率がいいように思います。特に上記の書籍は、「変数の宣言」レベルから解説が始まるので、挫折する恐れが鍵なくゼロに近い。

ということで OCaml を学習していきます。

環境作成

HomeBrew でインストールできるそうなのでこれでいきました。

brew install ocaml
brew install opam

あとは terminal で ocaml と実行すれば対話型インタプリタが起動する。

終了するためには

exit 0;;

(* もしくは *)

#quit;;

初めての計算

  • 末尾に ;; をつけてエンターを押すとコマンドが実行される。
  • 整数と実数では、計算のために使う演算子が違う。実数の場合は +. のように . を後ろにつける。
  • 整数と実数では型が違うので (int と float) 足せない。
1 + 1 ;; (* int 整数の場合 *)
1.1 +. 1.2;; (* float 実数 (少数点を拭くものなど) の場合*)

関数の定義

関数名 f, 引数が一つで x, 内容が x * x という関数の定義。

ocaml
let f x = x * x ;;
js
const f = x => x * x

定義した関数を実行するには以下。関数名 引数 の形。

ocaml
f 4
js
f(4)

関数の型

関数を定義すると以下のように出力されたはずだ。これは f の型を示している。

つまり「f にバインドされている値は <fun> 関数で、この関数は引数 int を受けて int を返すものである」ということが示されている。

ocaml
# let f x = x * x;;
val f : int -> int = <fun>

IDE で開発したい

WebStorm に慣れきった私のようなフロントエンドエンジ的には、ちょっとしたことですら JetBrains の IDE を使いたい。IntelliJ IDEA に OCaml をサポートするプラグインである ReasonML というものがあったのでこれをインストールした。

拡張子は .ml

.ml という名前のファイルを作るとラクダのマークになるはずだ。ここにコードを書いていく。

;; はファイル内ではいらない。

ファイルの中では ;; 入らないので以下のように関数を定義して、使用するコードを書く。

test.ml
let f x = x * x
let res = f 4 

以下はダメ。f 4 の部分が前のコードの続きのように解釈されるためらしい。

test.ml
let f x = x * x
f 4 

#use "test.ml" でファイルを読み込んで実行

ocaml の対話型インタプリタを起動中に以下コマンド実行するとファイルを読み込んで、その内容を実行できる。

#use "test.ml"

注意点は、最初の # はインタプリタの入力待ちの # ではなく、本当に入力するコマンドに # を含めることだ。

OCaml インタプリタで履歴を残す

これで毎回 use ... とかやらないで済む。

brew install rlwrap
alias ocaml='rlwrap ocaml' # alias を追加
ocaml