あの Dave Thomas が書いた『Programming Elixir』を買ったのでぼちぼち読んでいる。
Chapter 1. に Elixir の特徴を巧みに表現した文章があってカッとなったので、引用しておきたい。
Think Different(ly)
- Object orientation is not the only way to design code
- Functional Programming need not be complex or mathematical.
- The foundations of programming are not assignments, if statements, and loops.
- Concurrency does not need locks,semaphores, monitors, and the like.
- Processes are not necessarily expensive resources.
- Metaprogramming is not just something tacked onto a language.
- Even if it is work, programming should be fun.
意訳
簡単に意訳しておこう。若干超訳
- オブジェクト指向が、唯一のコードのデザイン手法ではない
- 関数型プログラミングは必ずしも複雑でもないし、数学的である必要もない
- プログラミングの基礎はいつも「代入、if文、ループ」というわけじゃない
- 並行処理はロック、セマフォ、モニタとかを必要としない
- 「プロセス」って高価なリソースではないよ
- メタプログラミングは言語におまけ程度に付け加えられたものってわけじゃないぜ
-
こんな感じでもプログラミングは楽しいよたとえそれが仕事だとしても、プログラミングは楽しくなくっちゃ
プログラミングについての常識感というかありがちな先入観を否定する形で Elixir の特徴を述べてて、巧い。
それぞれ何を言っているのか
個人的見解も交えてそれぞれ何のことを言ってるか補足してみよう。
オブジェクト指向が、唯一のコードのデザイン手法ではない
Elixir が関数型言語であることを言ってる。
Elixir にはオブジェクトの仕組みはない、けど、プログラムを構造的にデザインすることはもちろんできる。Elixir on Rails な Phoenix なんかを見ていると、Rails ライクな MVC フレームワークを構成するのにもオブジェクト指向が必要だったわけじゃない、というのがわかる。
関数型プログラミングは必ずしも複雑でもないし、数学的である必要もない
Elixir は関数型だけれども、自分程度でも使えているし、決して複雑ではない。また、実際使って見るとかなりプラクティカルな言語であり理論的な背景をきちんと理解しないと使いこなせないかというとそんなことはない。実際、自分は他の関数型言語でまともに使えるものはない程度のスキルだが何とかなってる。
このところ Elixir を触っていて、むしろ関数型とは何かを Elixir を通じてだんだんと実感できているような、個人的にはそういう感じ。
プログラミングの基礎はいつも「代入、if文、ループ」というわけじゃない
- Elixir の変数は代入ではなく、束縛
- Elixir での条件分岐的な処理は if 文ではなく、パターンマッチを使って書く方がより Elixir らしい (参照: Elixir のパターンマッチを攻略しよう)
- Elixir にループはない。再帰で書くとか、Enum 使おうぜ
ということ。
はじめは代入も、if 文も、ループもあまり使わない/使うな、と言われると面食らう感じはあるが、実際には Elixir を使って書いてると「あれ、気づいたら if 文使ってなかったわ」みたいな感じになる。言語の制約がうまくプログラマを導いてくれる。
並行処理はロック、セマフォ、モニタとかを必要としない
Elixir の並行処理はアクターモデルによる "Shared Nothing" 戦略である。
軽量プロセスを作って、プロセスとプロセスは何もデータを共有せず、お互いのやりとりはメッセージパッシングのみに限定される。メッセージでは任意の値を送受信できるが、送受信に際してそれらの値はコピーされ、共有はされない。
結果、並行して動いているそれぞれのプロセスは何も共有してないのでロックもセマフォも要らない。
もちろん、アクターモデルが苦手で従来型 (e.g. マルチスレッド) の方が得意とする並行処理もあるはあるので銀の弾丸ではないが、多くの場面では、この戦略でうまくいく。
「プロセス」って高価なリソースではないよ
Elixir の並行処理の基礎は、軽量プロセスによって成立している。
Elixir におけるプロセスは OS のプロセスではなくて、Elixir 内における小さな実行コンテキストのこと。プロセスをたくさん作って並行処理させて、いらなくなったら捨てる。エラー処理だけのためにプロセスを作ったりとかカジュアルにやる。
Elixir 上のプロセスは、Erlang VM (BEAM) によりスケジューリングされて OS 観点ではマルチスレッド + スレッドプールで動いている。従って、マルチコア CPU もうまく活用できる。
OS のプロセスはリソース的に高価なので fork とかは躊躇があったけれども、Elixir のそれは 300 ワードとかその程度なんでがんがん作ってがんがん活用すべし、みたいなものである。
メタプログラミングは言語におまけ程度に付け加えられたものってわけじゃないぜ
あまりメタプログラミング詳しくないけど、Elixir はすべての文法をマクロで変更できちゃう。lisp みたいなもの。
なので、おまけじゃないよってことが言いたいのかな。
こんな感じでもプログラミングは楽しいよ
Elixir 楽しい。久々にプログラミングって楽しいな、と思いながら触ってる。