ネタ元:「[プログラミング]「型」があるのは福音だよ?」から「変数に型がないということの利点について考える」
うん、面白い。
どのような型の値でも代入できる
まず基本的なこととして変数に型がなければどのような型の値でも代入できるということです。つまり、受け取るときに、どのような型の値を受け取るのかを意識する必要がありません。
my $str = 'Hello';
my $num = 1;
my $nums = [1, 2, 3];
my $person = {age => 2, name => 'taro'};
my $ua = LWP::UserAgent->new;
「どのような型の値でも代入できる」ということですが、C/C++ でも、ポインターに限定すれば、void
とアスタリスクで宣言することで、どのような型のポインターでも代入できますよ。Java や C# なら、Object
で宣言すれば、何でも入れられるんじゃないかなぁ?でも、それをやる人は、まず、いない。おおよそ、構造体や関数の型を定義して、それを使う。なぜか。型を明示することにメリットがあるから。そのメリットについては、明示的には書かない。
そして、これは、次と一緒と考えて良いのかな?
変数に型がないと変更に強い
変数に型がないとソースコードの変更に強くなります。たとえば右辺の返す型に変更があったとしても、受け取る側のソースコードを変更する必要はありません。
# clinetはClientA型でもClientB型でもよい
my $ua = $c->client;
「どのような型でも代入できる」では、初期値の代入しかしていません。しかし、「変数に型がないと変更に強い」では、コーの変更のことにまで言及してあるので、例えば次のようなコードも許される、ということかな?
my $variable = 1;
my $variable = 'abc';
で、「変更に強い」というのを、この様に、「コードを変えなくてもよい」のようにはいわないと思うのですが、どうなんだろう?私がイメージする「変更に強いコード」とは、仕様に変更があったとき、「どの範囲に影響があり、どこを修正すれば良いかがわかりやすいコード」なのですが。ここで言われているのは、「どのような型でも代入可能なので、型が変わったということがわからず、変更しなければならない箇所がわかりにくい」でしかないと思うのです。ああ、「変更しなくていい」だから、変更しなければならない箇所はわからなくて良いのか。でも、変更しなければならない箇所がわかりにくいということは、変更が有効になっていることをテストするコードを書きにくい、ってことじゃないかな?そうすると、コメント欄で、「テストすればわかる」と書かれていることと矛盾します。確かに、テストコードを“書いて”、テストすればわかるでしょう。しかし、テストコードを“書く”のなら、次の所とも矛盾します。
記述量がとても短くなる
変数の型がないことによって記述量がとても短くなります。
え~~!!テストコードの方が、記述量が短いですって?そんなこと無いでしょう?
ちょっとふざけてみました。いや、かなりまじめ。型を書くという事を「記述量が多い」といいながら、静的型付け言語では不要な「型チェックのためのテストコード」を書くことは、記述量に入らない?テストコードを書く時間は、開発時間に入らない?生産性として勘定しない?そんなバカな。。。
あと、ここも気になった。
複数の型を受け取りたいときに、インターフェースを実装する必要がない
Javaで大きなの労力といえば、インターフェースの仕組みを覚えて、実装することでしょう。複数の型を受け取りたい変数を作成したい場合は、まずインターフェースを実装することになります。
関数のオーバーロードが不要になる
変数の型を持つ言語は、型が異なるのだが、処理としては同一の処理を行いたい場合には、オーバーロードという機能を使う必要があります。変数の型がなければ、オーバーロードの機能は必要ではなく、ただ単にif文で分岐すればよいだけなのでとても楽です。
おそらく、「オブジェクト志向設計」を誤解しています。それはおそらく、「オブジェクト指向設計」という字を使うから。oriented は「志向」であって、「指向」ではないのです。明鏡国語辞典には、こう書かれています。
志向:[名・他サ変]意識や思考がある対象に向かうこと。「平和国家の建設を━する」「アウトドア[本物・上昇]━」「指向」とも書かれるが、本来的な用法ではない。「指向」は単に物理的な方向をいう。
指向:[名・他サ変]ある一定の方向をめざして進むこと。また、その方向へ向かわせること。「市場を東南アジア全域に━する」「━性アンテナ」
オブジェクトに指向しかしていないから、オブジェクトを使う事を考える。オブジェクトに志向するなら、そもそも「オブジェクトとは何か」について考えます。そうすると、「処理としては同一の処理を行いたい」など、処理に志向した考え方はしなくなります。オブジェクトに志向していれば、「このオブジェクトとあのオブジェクトで、同一の処理が適用できる」の様になるでしょう。
もちろん、書いてあることもおかしくて、Java, C++, C# では、次のように書くだけです。
void sub()
{
// 「hoge().DoSomething();」とも書ける。
IInterface arg = hoge();
arg.DoSomething();
}
あ、「変数に型がないと変更に強い」に、次のように書いてありましたっけ。「たとえば右辺の返す型に変更があったとしても、受け取る側のソースコードを変更する必要はありません。
」と。じゃぁ、同じように書きましょう。「型に追加があっても、実行するところのコードを変更、if - else if
を連ねる必要は有りません。勝手に、追加された型の DoSomething メソッドが実行されます。」と。記述量も少ないし、いいよね。
で、わかっていただけないのが、この arg
引数の型が IInterface
以外に変更になったとき、静的型付き言語ではコンパイルすることで検出できるのですが、「動的型付け言語…といって良いのかな?…では、実行“しなければ”わからない」のうち、「しなければ」が「すれば」なのか、どっちだ?!という点。同じように、「テストすればわかる」なのか、「テストしなければわからない」なのか、という問題もある。コメントをされている方々は「しなければ」なのですが、著者さんは「すれば」なんですね。
で、これについては、思うのです。「経験のないものはわからない」と。
もし、著者さんが、小規模の開発、小規模物件の追加改造しかされた経験がないなら、「すれば」でしょう。しかし、大規模から巨大規模の開発しか経験されていない方なら、「しなければ」でしょう。
この間、必要に駆られて SQLite3 を触ったのですが、これって、型の宣言って、無視しやがるのね。INTEGER と宣言したのに、文字列も実数も格納できてしまうorz 私としては「怖い」のですが、アプリケーションの設定を簡易的に保存する手段としては、まぁ、良いかもしれませんね。でも、基幹業務に使いたいとは思わないなぁ。
そういうことで、小手先の技でチョイチョイとつくって、全体を見渡せる範囲に収まっているなら、動的型付け言語って、便利だと思います。一人で全体を見渡せないなら、静的型付き言語の方が便利です。
投稿日時 : 2013年3月13日 22:20