読者です 読者をやめる 読者になる 読者になる

自分が何故、静的型付が好きなのか少し考えてみた

さて、私はRubyやJSも好きでよく使ってますが、基本的にはScalaとか静的な言語の方が好きです。

機械にできることは機械にやらせるというのが基本スタイルなので。その上で、どういったところを気になってるのか、せっかくの機会なので整理して見ました。

 

変数に型がないということの利点について考える」に触発されたのですが、コメント欄がモヒカンのおもちゃにされすぎてるw 読むだけで勉強になると思うので、みなさん見てみましょう><

 

型ってなに?

色々定義はあると思うのですが、データの表現の種類、と私は理解してます。言い換えればオブジェクトです。

言語的な制約でプリミティブ型とオブジェクト型に分けることはありますが、概念的には全てオブジェクトで考えています。

これをコンパイル時に解決するものが静的型付言語、実行時に解決するものが動的型付言語、ですね。

 

以下はその前提で書き進めます。

 

動的型付けを使いたい時

動的型付け言語最大のメリットはずばり型宣言がいらない! 事などではなく、ダックタイピングでしょう。

元記事で変更に強いという言い回しで出てくるのも、概ねこれに起因することですね。

 

また、修正しやすいのもメリットです。インタフェースを変えるような大きな変更をしても、修正量自体は少なくてすみます。そのため、プロトタイプとかを作るのには非常に強力です。

 

他にも多くの場合強力なメタプログラミング機能を備えているのも魅力の一つではありますが、これは静的型付けでも解決できる場合も多いので、動的型付けの特徴というより言語の特徴ですね。ただ、method missing系はさすがに難しいので、これらが使いたい時にはやはり動的な言語で書くのが良いですね。黒魔術ですがw

 

ちなみに、ダックタイピングライクな事も、特異メソッド的なことも、それScalaで出来るよ、って感じなのでその辺は言語機能の差と考えることもできます。もちろん、動的型付けの方が、そういった機能を実装しやすい、というのはあるでしょうけど。

静的型付けを使いたい時

静的型付けのメリットはなんと言ってもコンパイルエラーが出ること。これに付きます。

これによって実行して初めてわかる問題をかなり減らすことができます。C言語のようにしょぼい型システムだと嬉しさなんてありませんが、JavaScala, OCaml, Haskellなどだとかなり有用です。

関数型言語群の強力な型システムのメリットは私も学びきれてないので、Javaレベルで考えてみますが、だいたい下記のメリットがあります。

  1. スペルミス
  2. 存在しないメソッドの検出(名前が似てるだけで親クラスが違う)
  3. enum等による誤入力の検出
  4. オーバーロードできる!
  5. 変更による影響範囲の検出
  6. プログラマに対するメタ情報
  7. 静的解析の容易さによるIDE/解析ツールの充実

このあたりですね。1や2は特に言うことはないそのままですね。3に関しては整数等で代用するのではなく、正しく列挙型あるいはBoolean型を使う場合のメリットです。

これにより誤って違う数字を入れてしまうという基本的なバグがなくなりますし、原理的にマジックナンバーも減ります。非常に有用。

 

4としてはオーバーロード。なぜか元記事ではしなくていい、とか書かれてましたが、これは非常に有用な機能です。

本質的には型に対する条件分岐の構文糖衣。1つのメソッドは小さければ小さいほど良く、条件分岐は必要最小限が望ましいと考えてるので、使わないてはない。

 

5はリネームやシグネチャなどインターフェースを変更した時の影響を簡単に洗い出せること。これはかなり重要。コンパイル時というのはつまるところIDEの場合、開発中そのものなので、リアルタイムに指摘されるし、指摘を直せばそれで解決。

 

6は主に公開メソッドのシグネチャのこと。型宣言というのはとても大事。そのメソッドが何を受け付けることを意図しているのかが一目でわかる。これは4のオーバーロードにも言えること。もちろん、それをコメントに書くことも出来るのだけど、その正しさをコンパイル時に保証できるのだが、可能な限りメタ情報も型で表現する方がいい。なので、個人的には後述するように型をなるべく細かく作るのが好き。ちなみに型推論が可能な場合、シグネチャの型も省略できるのだけど、自分は公開メソッドに関してはあえて明示的に書いています。

 

7は静的型付言語の場合はコンパイルと同程度の情報はIDEやその他解析ツールから比較的容易に取り出せる、という点です。なのでIDEはリアルタイムにコンパイルエラーを検出でき、コードアシストも強力に効き、リファクタリングも充実しています。また、findbugのような解析ツールも静的型付け向けのほうが充実してはいます。

変更に強いのは?

変更の容易さは動的型付けでしょう。しかし、変更の強さは静的型付けだと思います。

それは、前述したとおり、影響範囲の抽出が容易だからです。もちろん、実行すればわかることも多いでしょうけど、実行しないと分からないのはナンセンスです。

変更の影響を小さく抑えることができるので、開発スピードは早くなり、結果として十分なテストも出来るかもしれません。それはそれで大きなメリットなのですが、個人的にはそのプロセスよりもコンパイルが通らないと前に進めないという状況の方が開発の中で闇に葬られないので品質向上につながると思っています。

どっちを使うべき?

 ケースバイケースです。というのが基本的な回答ですが、個人的には前述の通り静的片付けが好みなのでこちらを使うことが多いです。ただ、クイックに書きたい時はやはり動的型付け言語のが便利ですね。

ただ、実際のところ、これは静的型付動的型付けというより、どの言語を使うか、という話になると思います。クイックに書きたいとしてもPHPで書くより、Scalaで書いたほうが楽なところが私の場合は多いです。

あるいはC言語よりRubyの方がよっぽど安全に書けるでしょう。

 

 

おまけ:ぼくのかんがえたさいきょうのかたしすてむ

個人的には文字列や数値のような汎用的な型の使用をもっと減らすことで型システムの恩恵を受けれると思います。

たとえばメールアドレス型を定義すればフォーマットチェックなどの基本的なことはすべて、型システムに任せることができます。

たいていのデータには入力範囲があるので、純粋なテキスト等を除いて、列挙型をベースにしたプログラミングがいいんじゃないかな、と。

現実にはそういった型を作るのが面倒すぎますし、型変換も煩雑になるので取ることが難しいスタイルですけど、そういった言語が欲しいなぁ。