ぱたへね

はてなダイアリーはrustの色分けができないのでこっちに来た

[book] コーディングを支える技術を読んで

コーディングを支える技術 ~成り立ちから学ぶプログラミング作法を読んでもやもやしていた所があるのですが、いったん思っていることをアウトプットしてみます。

本の紹介

 コーディングを支える技術は、世の中で人気のある(プログラミング)言語を比較しながらいろいろと勉強していきましょうという本です。プログラミングを初めて半年から1年程度の人が読むとちょうど良いと思います。6章の例外と7章のPythonのスコープの話は知らないことが多く、とても面白く読めました。全体的にはすごく丁寧に書かれていて、突っ込みが浅くて残念になるところを除けば、まとまりのつかなくなりそうな話を上手くまとめていると思います。

プログラミング言語に共通の知識を身につけるには

 この本を読んでいて感じたのが、「プログラミング言語に共通の知識を身につけるには、少数のプログラミング言語にしか採用されていない機能を調べる」方が面白いんじゃないかと言うことです。もちろん、この話はコーディングを支える技術を読んだ次のステップの話ですし、コーディングを支える技術では共通の知識がつかないという意味でもありません。

 例を一つあげると、Cのプリプロセッサを採用している大規模開発を想定した言語は少ないですよね。私の知る限りC++だけです。よく似た機能があるVerilog-HDLでも、単に同じ文字列を変換するのではなく、`を付けないとプリプロセッサによる置換は行われません。これは何でなんでしょうね。逆になんでC++だけ(テンプレートがあるにもかかわらず)機械的な置換を行うのか。そういう所に、言語に共通のトレードオフがあって、言語設計者の思想が見えてくると思います。
 そういう他で採用されていない特徴を、私が知っている範囲で挙げてみました。言語規格では無いものも入れてます。

  • Common Lisp マクロ、仕様に入っているデバッグ機能、複雑怪奇なformatやloopの存在、YES-OR-NO-Pのような要らんだろっていう標準関数
  • Scheme マクロ、継続、自己主張の強い独自拡張された処理系が多い(Racket Gauche Guileなど)
  • Tcl uplevelのようなスタックフレームを操る関数、returnコマンド、使いにくい例外のシンタックス
  • C プリプロセッサ、仕様のなかでの処理系依存の多さ、さっぱり使えない文字列処理の標準関数、関数の引数や戻り値に配列を使えない、freestandingの概念
  • Forth きもいif文、関数の定義がスタック
  • Python グローバル変数がデフォで読めるのに書けない、文字列の表現が3種類もある、別実装が多い(IronPython Jython pypy Stackless etc)、import this
  • F# 関数型言語なのに変数をバリバリ書き換えられる、Computation Expressions、Type Provider、再帰に必要なrec、単位
  • SystemVerilog 豊富な乱数、時系列に関するアサーション
  • C++ 基本的に全部
  • Perl 基本的に全部

 私自身が理由が説明できるものも、できないものもあります。中には単に実装が楽だから、便利だからというのも多いです。とはいえ、言語設計者にとって実装が楽というのと、ユーザーにとって便利というのは、そこからトレードオフがあるわけで、それぞれの言語がどうしてそういう所を選んだのかは調べていくと面白いと思います。C++に関しては古い機能はC++の設計と進化に書いてありますので、それを読むとだいたいの事は書いてあります。

 コーディングを支える技術で、6章の例外と7章のPythonのスコープの話が面白く感じたのは、ここだけが全ての言語に共通の説明ではなく、ある言語がこういう仕様、仕組みになっているという視線で説明されていたからだと思います。

言語の思想を学ぶにはどの言語がよいのか

 以前に学ぶべき5つ言語についてという記事を読みました。はてぶでGaucheを勧めていますが、その気持ちは今でも変りません。Gaucheを勧める理由は、まずはGauche自身が設計されるにあたってCommon LispPerlの影響を強く受けている事です。Gaucheのそれぞれの機能において、Schemeのままにしておく、Perlから持ってくる、Common Lispから持ってくるの中からどれかを選んでいるわけで、それぞれで設計思想による判断が入っていると考えると、それだけでも学ぶ価値があります。もう一つの大きな理由は、Gaucheの設計者であるShiroさんが、設計上の話をWeb上で公開しているだけでなく疑問に丁寧に答えてくださるからです。

 例えばGaucheにdocstringが無い理由を読むと、ユーザーにとって便利という話と実装上の問題、そして思想の話までとても面白くまとまっています。こういう文章が日本語で読めるのが勉強用にGaucheを勧める理由です。

最後に

今こうやってまとめただけでも、単位を扱える言語がF#とC++(Boost::units)の2つと気がつきました。ベクトルが違いそうな言語間での共通点です。
http://msdn.microsoft.com/ja-jp/library/vstudio/dd233243.aspx
http://www.kmonos.net/alang/boost/classes/units.html
どちらも、単位をつけた数値はその単位を含む型、クラスになり、コンパイル時の型検査によって単位を確認します。

と書いてみましたが、F#は言語組込の機能なのでなんとでも実装できるのでしょうが、C++のBoost::unitsはコンパイラの動きが説明できないことに気がつきました。面白い機能なので、ぜひ仕組みを調べてみたいです。