ブログトップ 記事一覧 ログイン 無料ブログ開設

サンプルコードによるPerl入門

2013-02-27

変数に型がないということの利点について考える

 PHPPerlRubyPythonなどのスクリプト言語に対して、変数に型がないということを否定的にとらえる人もいるかと思います。特にC言語Javaなどの静的言語を使ってきた人にとっては、型がないということが不安材料として目に映ることが多いのではないかと思います。 

 けれども、型がないということは、本当に素晴らしいことです。型がないことによって、たくさんの面倒から解放されるからです。

どのような型の値でも代入できる

 まず基本的なこととして変数に型がなければどのような型の値でも代入できるということです。つまり、受け取るときに、どのような型の値を受け取るのかを意識する必要がありません。

my $str = 'Hello';
my $num = 1;
my $nums = [1, 2, 3];
my $person = {age => 2, name => 'taro'};
my $ua = LWP::UserAgent->new;

 文字列であろうと、数値であろうと、配列であろうと、連想配列であろうと、オブジェクトであろうと、それを意識する必要がありません。

記述量がとても短くなる

 変数の型がないことによって記述量がとても短くなります。

my $ua = LWP::UserAgent->new;

 もし変数に型があれば、次のようになるでしょう(Javaの例)。

LWP::UserAgent ua = new LWP::UserAgent();

 型推論で解決できるという意見があるかもしれませんが、型推論は不完全だと思います。まず右辺で型が明示されていない場合に使えないので、右辺に型がない場合は、結局型を書かないといけないからです。また型推論はソースコードコンパイルの時間を遅くしてしまいます。ソースコードが大きくなってきた場合に、すばやく書いて、すばやく実行結果をもらうことができなくなります。また統合開発環境での、メソッドの自動補完の機能の実装が少し難しくなります。

変数に型がないと変更に強い

 変数に型がないとソースコードの変更に強くなります。たとえば右辺の返す型に変更があったとしても、受け取る側のソースコードを変更する必要はありません。

# clinetはClientA型でもClientB型でもよい
my $ua = $c->client;

関数オーバーロードが不要になる

 変数の型を持つ言語は、型が異なるのだが、処理としては同一の処理を行いたい場合には、オーバーロードという機能を使う必要があります。変数の型がなければ、オーバーロードの機能は必要ではなく、ただ単にif文で分岐すればよいだけなのでとても楽です。

sub sum {
  my $value = shift;
  
  if ($valueがA型なら) {
  
  }
  elsif ($valueがB型なら) {
  
  }
}

 変数に型がないことによって、関数の重複を減らすことができるという大きなメリットがあります。

複数の型を受け取りたいときに、インターフェースを実装する必要がない

 Javaで大きなの労力といえば、インターフェースの仕組みを覚えて、実装することでしょう。複数の型を受け取りたい変数を作成したい場合は、まずインターフェースを実装することになります。

 けれども、変数に型がなければ、インターフェースという仕組みは不要です。変数に型がないことによって、クラスの実装が重複がなくとてもシンプルになります。

C++テンプレートのような機能も必要がない

 関数の引数が配列を受け取る場合を考えてみてください。そして、配列に含まれている変数の型が、定まっていない場合を考えます。また配列自体が、普通の配列なのか、動的配列なのか、特殊なリストなのかということがわからない場合についても考えてみてください。変数に型があると、このようなたくさんのことを個別に考えて、うまくインターフェースを実装したり、C++のテンプレートのような複雑でデバッグしにくい機能を使ったりしなければなりません。

 けれども、変数に型がなければ、そもそもこのような問題に直面することがありません。関数で受け取った後に、必要に応じて、if文で型を判定すればよいだけだからです。ですから、変数に型がないことによって、関数やメソッドの実装が重複なく簡単に書けます。

変数に型がないとどのような型の値が代入されているかわからないという批判に答える

 変数に型がないとどのような型の値が代入されているかわからないという批判があるかと思います。可読性の問題です。でも、僕は型のない言語の可読性が低いと感じたことはないです。それは、そもそも静的言語を読むときとは、違う読み方をしているからだと思います。

 スクリプト言語を読むときには、文脈を追って読むとどんな値が入っているかが、たいていはすぐにわかります。たとえば変数が次のような使われ方をしているとします。

$nums->[3];

 $numsは配列(へのリファレンス)です。

$ages->{age};

 $agesはハッシュ(へのリファレンス)です。

my $ua = LWP::UserAgent->new;

 $uaにはLWP::UserAgent型の値が入っています。

my $c = Client->new;
my $ua = $c->ua;

 $uaってなんだろう? Clientクラスのuaメソッドが何を返しているかを調べればわかるな。

 こんな風に読んでいってスクリプト言語を読むことに慣れてしまえば、何の問題もないと思います。

変数に型がないことのメリットは重複を少なくソースコードがかけること

 変数に型がないことのメリットは重複を少なくソースコードがかけることです。変数の型を意識しなくてもよいということは、それを利用するクラスや関数、メソッドも、利用するときに、型を意識する必要がないということです。これは重複の少ない保守性の高いプログラムを書くときにとても役に立ちます。

 スクリプト言語は保守性が低いといわれますが、そもそも根拠はないと思います。静的言語はインターフェースやクラスをそのたびに実装しなければならないので、修正や変更が行いづらいです。その点では、保守性は低いといえます。

 もう型のない言語は終わった、これからはハイブリッド型の言語の時代だという論評もときどき聞かれますが、その人は、型がないことのメリットを理解していないように思います。たぶんその人は、ソースコード上の見栄えという面しか理解していないんじゃないかと思います。

変数に型がないことのデメリットはないのか

 あげるとすれば、パフォーマンスです。値の型が事前にわかっていれば、数値演算は圧倒的に速くなります。それが整数であることがわかっていれば、それを前提に計算ができるので、数値計算のパフォーマンスは、静的言語が圧倒的によいです。

 でもパフォーマンスが問題にならない局面では、スクリプト言語を利用するのがよいと思います。

 もうひとつは、メソッドや関数名の補完の実装がうまくできないので、統合開発環境には頼れないということですね。スクリプト言語を書く場合は、まるっとたくさん暗記して、統合開発環境に頼らないのが、開発効率がよいと思います。

はてなブックマークコメントへの返信

型がないことのデメリット:型があれば静的にコンピューターが発見できるバグを発見できないので人間様がやる必要がある というのはあると思う

(nkgt_chkonkさん)

 これはコンパイル時に、コンパイルエラーがわかるという意味だと思います。でもスクリプト言語というのは、コンパイルと一緒に実行してしまいます。すると、バグがその時に見つかるので、バグの発見しやすさは変わらないと思います。

いくらなんでもポジティブすぎるのでは…!

(gfxさん)

 ポジティブすぎる箇所を教えてください。

工エエェェ(´д`)ェェエエ工

(choplinさん)

 工エエェェ(´д`)ェェエエ工となる箇所を教えてください。

一人で把握出来る規模のものを一人で作って保守していた頃は同じことを考えていた気がする

(Dolpenさん)

大規模になったとき動的言語の型がないデメリットを実感すると思う

(t2y-1979さん)

 大規模になってくると、保守できなくなるという発想は、そもそも間違いだと思います。CookpadGithubmixiはてな、faccbook、amazon、みんな動的な型を持つスクリプト言語を使って、大規模サイトを作っています。そう思うのは、思い込みや、プロジェクト管理の問題ではないかな。

型がない言語、書いた人間のマインドモデルに依存しすぎるので、よっぽど優れたマインドモデル持ってないと辛い

(mizchiさん)

 それは静的な型がソースコードの中に見えれば、マインドモデルに依存しないといっているように聞こえます。静的な型を持つ言語で書いても、ひどいソースコードはたくさんあります。

冗長に書くことでコンパイル時にそれらの間に矛盾がないか部分的ながらチェックできるのが静的型システムの一つの利点なんです

(nakag0711さん)

 なんでみんな、コンパイル時、コンパイル時って呪文のようにとなえるの? 一回プログラム実行したらわかるんじゃないのかなと思う。

実行時までエラーが判明しないというのは、アプリケーションの質を高める阻害要因になりかねないのですよ。

(mohnoさん)

 プログラムを一回実行したらいいだけじゃないの。というよりも、もし統合開発環境使っているのだったら、コンパイルと実行は、同時じゃないのかなと思う。

変態整数型仕様(変数に型があるくせに代入時エラーもなく暗黙に型変換しやがる)のせいで阿鼻叫喚が絶えない,あの酷い言語に聞かせてやりたい.

 どの言語のことかわからないです。

変更に強い/弱いの考え方がズレてないか?

 ずれてないです。たとえば、インターフェースを作成して、実クラスにメソッドをひとつ追加しようと思うと、インターフェースにも重複して変更を加えないといけないです。動的な型を持っていれば、そこを修正する必要がないので、変更に強いんです。

PythonとRubyは同列に並べるがPHPは入れないところに謎の序列を感じた / 型推論のある言語をマジメに使ったことがあるとは思えない / 大規模になると、LLでも型を明示してIDEの補完を活用した方が断然生産性上がるよ

 PHPを抜いたことには深い意図はないです。PHPはデプロイのしやすさ、Webに特化した関数がコアに初めから入っているので、利用しやすいという点ではWebプログラミングをしやすい言語だと思っています。型推論に関しては、僕の認識が甘かったです。LLでも型を明示するということの意味は、ちょっとわからないです。

爆釣ですなぁ。自分もJavaやってからRuby始めたころは、こんな感想だった。いいんじゃない、いろんな言語のよい所わかるのは。次はscalaあたりに手を付けてみると全然違う世界が広がると思う。

(kabisukeさん)

 釣ってないです。普段どおり、普通に書いたら、ブックマークいっぱいついちゃっただけです。 

「一回プログラム実行したらわかる」 一度携帯電話のプログラム書いてみろ「110番に緊急呼している最中に月が変わってプリペイド契約が切れその瞬間に緊急地震速報がきた」みたいなのとかテストできんの?

(naoya2kさん)

 これはもっと試験の一般的な問題だと思います。静的な型でそのプログラムを作ったから安全ということとはぜんぜん関係がないと思います。

そもそもPHPもPerlもRubyもPythonも型はあるんだけど、明示して宣言しないだけで。

(rokujyouhitomaさん)

 このお話は、内部的な値の型について議論しているのではなくって、変数が型を要求しないので、どんな型を持つ値でも代入できるメリットについて書いています。

一回実行したらわかる、というのがおかしい。Perlにまともなカバレッジ分析ツールがあるのなら使ってみれば、一回では済まないことがわかるはず。

(tproさん)

 一回実行したらわかるということの意味は、その部分を一回実行したら、バグが判明するという意味です。カバレッジをすべて通すという意味ではないです。カバレッジの問題は、また別問題です。分岐が正しいかというのは、そもそも静的な型付けをある言語が持っているかということとは全然別のはなしです。

これはPerlユーザーに背中から刺されるレベル

(Nkznさん)

 内容がないですね。

追記

 以下は勘違いしていました。

型推論で解決できるという意見があるかもしれませんが、型推論は不完全だと思います。まず右辺で型が明示されていない場合に使えないので、右辺に型がない場合は、結局型を書かないといけないからです。

 型推論はもっと多くの場合うまく型を推論してくれるようです。型推論に対する利点の議論は取り下げます。

 でもそんなに的外れな議論はしていないと考えていますよ。


読み物へ

faith_and_bravefaith_and_brave 2013/02/27 17:36 > でもスクリプト言語というのは、コンパイルと一緒に実行してしまいます。すると、バグがその時に見つかるので、バグの発見しやすさは変わらないと思います。

いえ、コンパイルは通らないパスも検査しますが、動的型付け言語は、構文エラー以外は通ったパスしか検査しません。網羅的なパスを自動実行するコードを書かない限り、静的型付けと同じエラー検出は期待できません。

nkgt_chkonknkgt_chkonk 2013/02/27 17:48 https://gist.github.com/Shinpeim/5046338

上記のようなコードでは、 動的な言語の場合は $complex_condition が真のときにしかエラーになりません。が、静的な型をもつ言語ではコンパイル時にエラーになります。複雑な条件かつレアなケースでしか通らないようなところにあるバグは、「実行すればわかる」とは言えないだろうと思います。

あるいは、 Perl では Smart::Args などを利用すればそれなりに厳格な型チェックができますが、これも実行時チェックなので実際にその行が実行されなければエラーを見つけることはできません。

もちろん、適切にテストを書くことでこのデメリットはある程度軽減することができますが、このレベルのバグはコンパイラが見つけてくれればそれだけ人間は楽ができるというのが私の主張です。

わたしも Perl は好きですし動的な型付けはサクサク書けるし柔軟で良いなーと思いますが、それは安全性とのトレードオフであるという認識です。

choplinchoplin 2013/02/27 18:22 では気になったところから3つほど

前提として、perlについて書かれているようなので、型がない -> 動的型付け、として捉えています。

> まず右辺で型が明示されていない場合に使えないので、右辺に型がない場合は、結局型を書かないといけないからです。

静的型付け言語が長くなる理由としてこの理由を挙げられていますが、意味がよく分かりません。
もし型名と同じコンストラクタが型推論に必須という意味であれば間違っています。
scalaの例ですが、次の式ではsumはIntと推論されます。Intの+(Int)メソッドがIntを返すと定義されているからです。

val sum = 1 + 2

> 変数に型がないと変更に強い

変更に強いの捉え方によりますが、私は変更に強いとは変更してもプログラムが壊れないという意味だと考えています。
例として挙げられているコードですが、もし$uaがClientBにないメソッドを呼び出していると、そのメソッドを呼ぶパスが実行時に通るまでプログラムが壊れていることに気づきません。

my $ua = $c->client;

$ua->method_only_in_client_a # 変更後に実行されて初めてエラー

テストで意識的にパスを通すことでエラーを拾うしかありません。

静的型付け言語であればコンパイル時に存在しないメソッドの呼び出しでエラーになり、そもそも実行することができません。

> 関数のオーバーロードが不要になる

もしどうしてもオーバーロードしたくないのであれば、scalaであればAnyでうけてisInstanceOf[T]かパターンマッチで挙げられている例と同等のことが可能です。
意図しない型が入ってきた時に弱くなるので、強い理由がない限りやらないと思いますが。

scala> def f(a:Any) = if (a.isInstanceOf[String]) "String" else "other"
f: (a: Any)java.lang.String

scala> f("hoge")
res1: java.lang.String = String

scala> f(1)
res2: java.lang.String = other

全体的に静的型付けであることのメリットデメリットを捉えちがえているように感じます。特に保守性の部分について。

個人的にですが、動的型付け言語のメリットは、プログラム書き始めの試行錯誤のスピードが早い、初学者の学習曲線がなだらかであることだと思っています。

noronoro 2013/02/27 18:47 pythonの2.xで日本語を使ってると型宣言したくなります。書いてるうちにunicodeなのかstrなのかわからなくなってしまうので。

ほげほげ 2013/02/27 18:58 どのような型の値でも代入できる: これ自体は良いとも悪いとも言えない
記述量がとても短くなる: 「型推論」についての理解が不十分
変数に型がないと変更に強い: 「変更に強い」の問題点はchoplinの挙げている通り
オーバーロード・インターフェース・テンプレート: 比較対象の言語の選び方が恣意的
変数に型がないことのメリットは重複を少なくソースコードがかけること: 「保守性」とは?

全体的にズレてます。

ほげほげ 2013/02/27 18:59 「choplinさん」と書いたつもりが、「choplin」と呼び捨てにしてしまっていました。
すみません。

__ 2013/02/27 19:25 この記事で型推論が不完全というのの意味が明らかでないのが気になるところですが、例えば ML という言語に対する健全かつ完全な型推論アルゴリズムが存在するというのは良く知られている事実です。健全性に関する証明は、Milner の A Theory of Type Polymorphism in Programming という論文にあります。(完全性の証明も探しているのですが、良さそうなのがなかなかみつからないのでまた後で)
型推論アルゴリズムの健全性(soundness)とは、そのアルゴリズムにプログラム p を入力したときに型 t が付くと出力されれば、必ずプログラム p は型 t で型付けできるという性質です。
型推論アルゴリズムの完全性(completeness)とは、そのアルゴリズムに型を付けられるプログラムを入力すると、必ず型が付くという出力が得られるという性質です。
これらの性質を満たすとしても"不完全"でしょうか? また、複雑な体系であれば完全性の成り立つ型推論アルゴリズムが存在しないこともありますが(実際に使われているプログラミング言語の型推論器も完全でないことは多い)、代入の右辺に型が明示的に書いてないからというような理由で型を決定できないことは、あまり無いように思います。実用する上ではほとんど困りません。

matsulibmatsulib 2013/02/27 20:00 この記事はCやJavaなどの静的言語とPerlを比較してと言ってるから、関数型言語についてまで言及しているとは思えない。ここで言ってる型推論の不完全性・冗長性というのは、C#の型パラメータが省略できないということに限定されるのでは。なんとかという関数型言語ではできるという指摘はごもっとも。でもちょっと意地悪な気もする。

通りすがり通りすがり 2013/02/27 21:01 長くなったんで、匿名ダイアリーに書いときました。
http://anond.hatelabo.jp/20130227205911

perlcodesampleperlcodesample 2013/02/27 21:40 faith_and_braveさん

>いえ、コンパイルは通らないパスも検査しますが、動的型付け言語は、構文エラー以外は通ったパスしか検査しません。網羅的なパスを自動実行するコードを書かない限り、静的型付けと同じエラー検出は期待できません。

 どうして通らないパスを持つソースコードを書くのでしょうか? 機能として必要だとしたら、その部分にエラーがあれば発見できると思います。また、それほど品質を高めたいのであれば、自動試験を書けばよいと思います。

perlcodesampleperlcodesample 2013/02/27 21:46 nkgt_chkonkさん

>複雑な条件かつレアなケースでしか通らないようなところにあるバグは、「実行すればわかる」とは言えないだろうと思います。

 高品質を求めるのであれば、バグは自動試験で見つけたほうがよいと思います。静的型だから、バグが減ることを期待するのはどうかなと思います。

perlcodesampleperlcodesample 2013/02/27 22:05 _さん、choplinさん

 僕の型推論の理解が不十分でした。ほとんどの場合推論してくれるそうですね。勘違いしていました。これは取り下げです。

perlcodesampleperlcodesample 2013/02/27 22:15 choplinさん

>静的型付け言語であればコンパイル時に存在しないメソッドの呼び出しでエラーになり、そもそも実行することができません。

 実行時に関数名が間違っていたり、存在しなくなって、エラーになったとしても、そこでソースコードを修正すればよいと思います。

 ソースコードを書くときは、試験を行うのですから、バグが見つかるのがコンパイル時か実行時かということは、よい悪いの比較にはならないかと思います。

faith_and_bravefaith_and_brave 2013/02/27 22:16 > それほど品質を高めたいのであれば、自動試験を書けばよいと思います。

そう書いたつもりです。そして以下のコメントに戻ります:

> 型がないことのデメリット:型があれば静的にコンピューターが発見できるバグを発見できないので人間様がやる必要がある というのはあると思う

アプリケーションレイヤーの自動試験のうち、型に関するテストを人間が書かなくて済みます。間違ったコードは静的型によってライブラリ側で保護され、実行することができないので、自動試験をアプリケーション側で書く必要がなくなります。
コンパイル時にできる限りのエラーを検出するのと、とりあえず動くコードを書いてあとで自動試験で保護するのは、開発方針によるトレードオフであって、メリット/デメリットの話ではありません。

また、アプリケーションレイヤーの自動試験は、まだまだ「全てを自動試験可能である」とは言いにくい段階だと思います。一部のコードは、手動で検証する必要がどうしても出てきます。そして人間が試験をする以上、漏れは発生します。そういったところで「通らないパス」は生まれます。

perlcodesampleperlcodesample 2013/02/27 22:18 noroさん

>pythonの2.xで日本語を使ってると型宣言したくなります。書いてるうちにunicodeなのかstrなのかわからなくなってしまうので。

pythonの事情がよくわからないので、なんともいえないのですが、出力してみれば、すぐにわかるのではないかなぁと思います。

perlcodesampleperlcodesample 2013/02/27 22:21 choplinさん

>全体的に静的型付けであることのメリットデメリットを捉えちがえているように感じます。特に保守性の部分について。

 静的型を持つ言語は、保守性が高いというのは、ある種の迷信や神話だと僕は思っています。コード量や、重複が多くなると、保守性は下がると思います。

perlcodesampleperlcodesample 2013/02/27 22:27 ほげさん

>どのような型の値でも代入できる: これ自体は良いとも悪いとも言えない
 これはオーバーロードやテンプレートのような機能を使わないでも書けるという点で、大きなメリットがあると考えています。

>記述量がとても短くなる: 「型推論」についての理解が不十分

 これはそのとおりでした。追記しました。

>変数に型がないと変更に強い: 「変更に強い」の問題点はchoplinの挙げている通り

 たとえば、インターフェースを実装していて、実クラスにメソッドが増えたとすると、インターフェースも直さなくちゃいけないじゃないですか。変数に型がなければ、そもそも意識する必要がなくなるので、変更に強いというのは、本当のことです。

>オーバーロード・インターフェース・テンプレート: 比較対象の言語の選び方が恣意的

 オーバーロードは、C++やJavaを意識しています。インターフェースはJavaです。テンプレートはC++です。静的な型を持つ代表的な言語だと思います。恣意的ではないです。

>変数に型がないことのメリットは重複を少なくソースコードがかけること: 「保守性」とは?

 保守性が高いコードというのは、繰り返しが少ないソースコードのことをいっています。たとえば「Object obj = new Object」よりも「my $obj = Object->new」のほうが、繰り返しが少ないので、保守性が高いという認識です。

perlcodesampleperlcodesample 2013/02/27 22:30 matsulibさん

 型推論については、完全に僕の理解の足りないことが原因でした。言語の比較は「Perl, Ruby, Pytho」vs「C, C++, Java」ですね。

perlcodesampleperlcodesample 2013/02/27 22:41 faith_and_braveさん

>アプリケーションレイヤーの自動試験のうち、型に関するテストを人間が書かなくて済みます。

 型に関する試験は書かないでよいと思います。試験するのは、入力と出力で正しい結果が得らればよいと思います。

>間違ったコードは静的型によってライブラリ側で保護され、実行することができないので、自動試験をアプリケーション側で書く必要がなくなります。

 静的型を持っていればコンパイル時に、型間違いを防いでくれるというのは事実ですが、実際に弊害になる場合をうまくイメージできません。doubleのつもりがintだったとかでしょうか?

 単なる試験不足のように感じますし、潜んでいるバグの多くが型間違いの部分にあるとも思えないです。

oneshotlife_tomoneshotlife_tom 2013/02/27 22:48 myとか、$とか@とか%とか書くの面倒じゃないですか?!その辺もインタープリタが解釈してくれるとめっちゃ楽なんですがね。

perlcodesampleperlcodesample 2013/02/27 22:51 通りすがりさん

>今時のパソコンならコンパイル時間なんて大したことない。

CPU一個あたりの性能は上がりにくくなってきています。コンパイルの遅さが不満になっているというのは、現場の声として実際に存在します。

Scala 2.9.1 final 雑感
http://d.hatena.ne.jp/kmizushima/20110901/1314879295

>実行時間に影響がなく、開発者の待ち時間で済む方が実はよいのでは?

本番でパフォーマンス要求を満たせるならば、開発者の開発速度が上がったほうがよいです。

>実行するまで意図したインスタンスが返ってこなくなった事実に気づかないから。

 これはよく聞かれますが、迷信に近いと思っています。開発中に試験をするのだから、どんなインスタンスが返ってくるかを確認しないわけがないと思います。

>とあるインスタンスしか入ってないつもりのリストに実は全然ちがうものが混ざってた!

 間違ったインスタンスが入っていたら、試験したら、その時にすぐに判明します。そのための試験なんだから、それでいいと思います。

>インスタンスが何を持ってるのかわからない方が可読性に問題がある。

 クラスのドキュメントを読めば、どんなメソッドを持っていて、どんなオブジェクトを返すのかがわかると思います。

faith_and_bravefaith_and_brave 2013/02/27 22:54 > 単なる試験不足のように感じますし、潜んでいるバグの多くが型間違いの部分にあるとも思えないです。

ここから先はもう、コメント欄で一つひとつ型が大事なケースを挙げていくと話が終わりません。strong typedefや依存型など、型によってアプリケーションのエラーを未然に防げる例は数多くありますので、興味があるなら調べてみてください。

perlcodesampleperlcodesample 2013/02/27 22:55 oneshotlife_tomさん

>myとか、$とか@とか%とか書くの面倒じゃないですか?!その辺もインタープリタが解釈してくれるとめっちゃ楽なんですがね。

 歴史的にPerlはそうなっているので、そこは仕方がない部分ですね。タイピングの少なさでいうなら、Rubyのほうがちょっと少ないと思います。「-> が .」「my $num が num」「セミコロン -> なし」なので。

 でもmyがあると変数宣言がどこでされたのかがひと目でわかるし、$がついていると、変数であることがひとめでわかるし、関数名とぶつからないという利点もあります。

...... 2013/02/27 22:56 > 保守性が高いコードというのは、繰り返しが少ないソースコードのことをいっています。たとえば「Object obj = new Object」よりも「my $obj = Object->new」のほうが、繰り返しが少ないので、保守性が高いという認識です。
なんでこれが「保守性が高い」ということになるの?

choplinchoplin 2013/02/27 22:58 > ソースコードを書くときは、試験を行うのですから、バグが見つかるのがコンパイル時か実行時かということは、よい悪いの比較にはならないかと思います。

faith_and_braveさんの繰り返しになりますが、コンパイラが検査してくれることによって、型レベルでは
* 人の手でテストを書く必要がなくなる
* 網羅性が保証される(但しコンパイラが保証してくれる範囲で)
という点で優れています。

後者の網羅性が特に厄介で、カバレッジが100%でない限り本当に全部のパスをテストで通せたか保証することは難しいのではないでしょうか。

> 静的型を持つ言語は、保守性が高いというのは、ある種の迷信や神話だと僕は思っています。

保守性は言語や設計に大きく依存するので、一概に静的型言語だから保守性が高いとはもちろん言えません。
ただ、静的型、動的型という対立軸にのみ注目するのならば、上記の通り型のレベルでの安全性が高まるという点で保守性が高いというのは正しいと思います。
実行時の値レベルまで保証してくれるわけではないので、そこはテストが必要ですが。

> コード量や、重複が多くなると、保守性は下がると思います。

重複についてはその通りですね。ただ、静的型言語であるがゆえに重複が多くなるというのは偽だと思います。
コード量については短ければいいというものではないですが、型推論を始めとして冗長な記述を減らし短く書ける仕組みは色々と取り入れられているので、恐らく考えている程には長くならないと思いますよ。

DryadDryad 2013/02/27 23:02 ○万行規模のコードの”C0 100%”に駆り出されるという悲しみに満ちた経験から、一つ言えることがあります。それは、正常系のパスは何とかなっても、異常系のパスを潰すテストを一つ一つ書いていく作業が、いかに大変な労力を伴うかということです。
この問題に対しては、色々な手法が提唱されています。型を利用するのは、有力な手段のひとつです。うまく型を使うことで、ケアレスミスや異常系の検討漏れを予防し、コードの正しさを証明することができます。その恩恵は、コードの規模が大きくなればなるほど大きいはずです。
具体的な解説については、私より詳しい方が大勢いらっしゃると思うので、他の方のご意見も伺ってみてください。先ほど、ひとつ参考になりそうなリンクがあったので、それだけご紹介しておきます。 https://sites.google.com/site/faithandbrave/error_handling

anonymousanonymous 2013/02/27 23:03 変更に強いというのは全く逆の意見です。
HaskellやOCamlの場合ですが、関数の引数の数や型を変更すると、その型が一致しない箇所がコンパイラで全てピックアップされます。
あとはそこを直していけばいいわけなので、影響を受ける範囲を限定しやすくなります。

「テストを書けばそんなの分かる」と主張されるかもしれませんが、だったら型を書いたほうがラクというのが静的な型付きを好む人達の見解でしょう。

コメントにある、

>>静的型付け言語であればコンパイル時に存在しないメソッドの呼び出しでエラーになり、そもそも実行することができません。
> 実行時に関数名が間違っていたり、存在しなくなって、エラーになったとしても、そこでソースコードを修正すればよいと思います。
> ソースコードを書くときは、試験を行うのですから、バグが見つかるのがコンパイル時か実行時かということは、よい悪いの比較にはならないかと思います。

に関しても、「バグが見つかるのがコンパイル時か実行時か」という差は大きいと思います。
Rubyを書いていてよくであるのが、ある変数やメソッドの返り値が意図せずnilになっていて、そこから生やしたメソッドが見つからず例外が投げられるということです。
変数の値やメソッドの返り値は動的な型付き言語では実行の度に変わる可能性があるので、コンパイル時にこの種のバグを見つけることはできませんし、テストで全てのケースをチェックすることはできませんから本番でこれが起きるかもしれません。

u4u4 2013/02/27 23:15 変数に入ってるインスタンスの型がわからないならテストを書けばいいってのはちょっと乱暴な気がします。
テストを書くのも人間なのでミスはありえますし、カバレッジ100%を目指すとなるとすべてのテストが正しい事を保証するのは至難の業です。
テストの正当性を保証するテストを書けとでもいうのかと。
静的型付け言語であればそもそも型に関する間違いはコンパイラが教えてくれるのでテストを書く必要もありません。
テストを含めた記述量を考えれば静的型付け言語の方がコード量は少なくて済みます。

perlcodesampleperlcodesample 2013/02/27 23:18 ...さん

>なんでこれが「保守性が高い」ということになるの?

DRYという考え方です。

http://ja.wikipedia.org/wiki/Don't_repeat_yourself

「論理的に関連した要素は予測できる形で統一的に変更され、したがってそれらの変更は同期が取れたものとなる。」という意味で、保守性が上がります。

perlcodesampleperlcodesample 2013/02/27 23:21 Dryadさん

>型を利用するのは、有力な手段のひとつです。うまく型を使うことで、ケアレスミスや異常系の検討漏れを予防し、コードの正しさを証明することができます。

 これには根拠がないです。バグを含むのであれば、型間違い以外の部分にももちろんバグが含まれていると思います。なぜ型があれば、バグが少なくなるという発想をするのかが、僕にはちょっとわかりません。

...... 2013/02/27 23:22 OCamlは強力な型推論があるから型を明示する必要は無いし、
参照透過性により移植性は優れているし、
多相型によりオーバーロードに相当する機能も動的型付けと同等に楽にできる。

型クラスのあるHaskellはオーバーロードについてはもっと強い。
しかしこちらはその分型推論は若干弱い。

perlcodesampleperlcodesample 2013/02/27 23:26 anonymousさん

>「テストを書けばそんなの分かる」と主張されるかもしれませんが、だったら型を書いたほうがラクというのが静的な型付きを好む人達の見解でしょう。

 静的な型があれば、バグが減るという見解は信じられません。バグをつぶすのは試験を行う作業だと思います。

>Rubyを書いていてよくであるのが、ある変数やメソッドの返り値が意図せずnilになっていて、そこから生やしたメソッドが見つからず例外が投げられるということです。

 静的に型宣言していても、nullポインタのようなものは、含めることができるので、それを参照しようとすると例外が発生するのではないでしょうか。

 Rubyの場合は、メソッドが呼び出されるときに遅延するだけで、早いか遅いかだけの違いだと思います。

...... 2013/02/27 23:26 > これには根拠がないです。バグを含むのであれば、型間違い以外の部分にももちろんバグが含まれていると思います。なぜ型があれば、バグが少なくなるという発想をするのかが、僕にはちょっとわかりません。
「コンパイルが通れば(型さえ合っていれば)少なくとも実行は可能である」という考え方はあるでしょう。
本当なら依存型 (dependent type) が実装されたマトモな言語があればよいのですが、
そこまで言わなくても例えばOCamlについて言えばコンパイルが通ればあとは実行時に困るのはゼロ除算とスタックオーバーフローぐらいでしょう。

...... 2013/02/27 23:29 どうもこの筆者はテスト工程を過信しすぎている気がする。
コンパイル時に検査できる内容はコンパイラに任せた方が当然バグは減る。

perlcodesampleperlcodesample 2013/02/27 23:30 u4さん

>静的型付け言語であればそもそも型に関する間違いはコンパイラが教えてくれるのでテストを書く必要もありません。

 試験をするときは型の試験なんてしないです。入力と出力のチェックをするだけです。レアケースが、それほど重要な意味を持つなら、ちゃんと自動試験書くべきです。静的な型を持っているから動的な型を持つ言語よりも、安心だとは、僕は思わないです。

oneshotlife_tomoneshotlife_tom 2013/02/27 23:33 書いてあることは理解出来るのだが、はじめてのPythonに書いてある売り文句のようでした。メリットと書いてあるところの恩恵を受けやすいのは、PythonとかRubyのほうじゃないかと。Perlはもっと雑多としているイメージがあります。Perlの良いところは、CPANから持ってこれるところかな・・・。CPANから拝借すれば、自分でコードを書く量が少ないのと、いろいろな人が叩いてくれているため品質が担保される、などなどではないかと。乗りこなしにくい、野生のじゃじゃ馬みたいな感じ。

perlcodesampleperlcodesample 2013/02/27 23:33 ...さん

>どうもこの筆者はテスト工程を過信しすぎている気がする。コンパイル時に検査できる内容はコンパイラに任せた方が当然バグは減る。

 みなさんが、コンパイル時の型チェックを過信しすぎていると思いますよ。結局は、試験をしないと、バグはとれないです。

...... 2013/02/27 23:39 > みなさんが、コンパイル時の型チェックを過信しすぎていると思いますよ。結局は、試験をしないと、バグはとれないです。
誰が試験をしないと言った?
バグを減らす工夫は多いほうが良い、という当たり前の事実を述べているまでである。

DryadDryad 2013/02/27 23:41 >perlcodesampleさん
> なぜ型があれば、バグが少なくなるという発想をするのかが、僕にはちょっとわかりません。

残念ながらあまり広くは知られていませんが、関数型言語を始めとした言語に備わっている強力な型システムを利用すると、ある種のバグを防ぎやすくなるのです。今気づいたのですが、先ほど挙げさせて頂いたドキュメントはfaith_and_braveさんがお書きになったもののようですね。今すぐでなくとも結構ですので、一度、目を通してみることをお勧めします。

u4u4 2013/02/27 23:55 >試験をするときは型の試験なんてしないです。

関数のオーバーロードが不要になる の例で$valueの型で条件分岐してますよね。

静的型付け言語であれば引数の型によって呼び出される関数が静的に決まるので、その関数のテストの際に型の違いを気にしなくていいと思うのですが。


というか自動試験というものに幻想を持ちすぎてるような…
コンパイラに任せられるものは任せたほうがプログラマの負担が減るという話なのに

PocoPoco 2013/02/28 00:04 >>なんでこれが「保守性が高い」ということになるの?

>DRYという考え方です。

違うでしょ。
何か適切な修正例を挙げて
「Object obj = new Object」
より
「my $obj = Object->new」
の方が修正範囲が小さい事示さなきゃ、保守性が高いなんて言えないのでは?
#というかわずか1行のソースで保守性の高さを示すには、上を変更する修正例でかつ下を一切修正しなくて済むような修正例挙げないと。。。
#トークンの出現回数なんて、入力補完の前ではゴミですよね?

YY 2013/02/28 00:05 静的型付けは型チェックしてくれるけどYコンビネータみたいな型付けできない式を書くことができない。表現力を狭めてでも高い品質が必要な時に利用する。動的型付けは逆で、品質を多少下げてでも表現力が必要な時に利用する。

XX 2013/02/28 00:58 再帰型でYコンビネータも型付けできますよ

heisseswasserheisseswasser 2013/02/28 01:58 22:27の時点で回答されているこちらですが
>>変数に型がないと変更に強い: 「変更に強い」の問題点はchoplinの挙げている通り
>
> たとえば、インターフェースを実装していて、実クラスにメソッドが増えたとすると、インターフェースも直さなくちゃいけないじゃないですか。変数に型がなければ、そもそも意識する必要がなくなるので、変更に強いというのは、本当のことです。

そうでしょうか?
僕が思うに、これは単に変更しやすいだけです。逆に言えば、変更されてしまいやすいのです。

もちろん変更しやすいというのはスピーディな開発には役立ち、その点で見れば利点です。

しかし、変更されやすいという点で見れば、
* 自分で実装しているクラスで、メソッドから返すオブジェクトをObjectAからObjectBに内部的に変更したり、
* 使用しているライブラリのクラスで、バージョンアップに伴ってメソッド名が変わった
というようなインターフェースが変更があった場合に、
動的型付け言語では、実行時に、変更があったクラスを使用する側の、変更箇所に関係する部分に運良く実行が到達するまで、インターフェースの変更が検知できません。(*)

変更があった場合に、使う側でそれが分からないのであれば、それは変更に強いとは言えず、むしろ弱いのでは?

もちろん、実行時のテストが必要だというのは、動的型付け/静的型付け言語に関係なく共通ですが、ここで僕が言いたいことは、
動的型付けな言語は、単に変更が容易なだけで、変更に強いという観点はちょっと違うんじゃないかなと。

(*)もちろんテストによっても発見できますが、網羅的にテストしないと発見できない可能性があります。

anonymousanonymous 2013/02/28 05:09 > 静的な型があれば、バグが減るという見解は信じられません。バグをつぶすのは試験を行う作業だと思います。

静的な型はバグが減るとかバグをつぶすというレベルの話ではなく、コードの明らかなミスを無くすものです。
例えば、"foo" + 100みたいなコードはバグ以前にただのミスでしょう。
関数が意図しない型の引数で呼び出されてしまって例外が投げられることはよく経験していらっしゃると思います。
動的な型のチェックではこんなミスも防げなくなってしまいます。
こうしたミスが起きないことを試験で確かめるのはかなり困難でしょう。

> 静的に型宣言していても、nullポインタのようなものは、含めることができるので、それを参照しようとすると例外が発生するのではないでしょうか。
> Rubyの場合は、メソッドが呼び出されるときに遅延するだけで、早いか遅いかだけの違いだと思います。

C言語などのポインタではそうでしょうが、ポインタ以外の変数はもちろんNullポインタにはなりません。int xのxには値がありますし、関数の返り値としてポインタでない型が指定された場合もそうです。
また、HaskellやOCamlなどには望みの値が含まれないかもしれないことを表現できるMaybeやoption型があります。

perlcodesampleperlcodesample 2013/02/28 09:04 oneshotlife_tomさん

>メリットと書いてあるところの恩恵を受けやすいのは、PythonとかRubyのほうじゃないかと。

 メリットは変数に型を持たない言語全般に当てはまります。Pythonは言語仕様がコンパクトなので、だれが書いても同じになりやすいという利点がありますが、今回の議論とは、観点が違うんです。

perlcodesampleperlcodesample 2013/02/28 09:14 >Dryadさん

>残念ながらあまり広くは知られていませんが、関数型言語を始めとした言語に備わっている強力な型システムを利用すると、ある種のバグを防ぎやすくなるのです。

ドキュメント先を読みましたが、一般的な例外処理のお話であって、静的な型を持つことがバグを防ぐという内容ではないように思います。

 みなさん静的な型を持っていると「ある種のバグ」が減ると思っていらっしゃるようですが、もし型が間違っていれば、試験をしたときにどちらにしろ発見できるので、バグの多い少ないには影響しないと思います。

 それを実行時に確認するのは、それほどめんどうなことでもないです。コンパイル時か実行時かという、発見の時期が異なるだけだと思います。

perlcodesampleperlcodesample 2013/02/28 09:26 u4さん

>関数のオーバーロードが不要になる の例で$valueの型で条件分岐してますよね。

 それはプログラムのロジックなので分岐しています。試験の場合は、ひとつひとつの関数ではなくって、この入力があった場合に、このような出力が得られるということを試験します。だから、型の試験というのは、普通は必要ないんです。

>というか自動試験というものに幻想を持ちすぎてるような…
>コンパイラに任せられるものは任せたほうがプログラマの負担が減るという話なのに

 負担は減らないと思います。型がおかしければ静的な型を持つ言語の場合はコンパイル時に、動的な型を持つ言語だと実行時にわかるというタイミングの違いだと思います。

perlcodesampleperlcodesample 2013/02/28 09:31 Pocoさん

>>なんでこれが「保守性が高い」ということになるの?
>DRYという考え方です。

>違うでしょ。
>何か適切な修正例を挙げて
>「Object obj = new Object」
>より
>「my $obj = Object->new」
>の方が修正範囲が小さい事示さなきゃ、保守性が高いなんて言えないのでは?
>#というかわずか1行のソースで保守性の高さを示すには、上を変更する修正例でかつ下を一切修>>正しなくて済むような修正例挙げないと。。。
>#トークンの出現回数なんて、入力補完の前ではゴミですよね?

 これはひとつの例です。たとえばオーバーロードを書かなくて、関数がひとつだけなら、重複を減らせます。またインターフェースを書くという重複もなくせます。ポリモーフィズムを実現したいときに、C++テンプレートのような特殊な実装を使わなくてもすみます。

 だから、動的な型を持つ言語は、ソースコード全体として、かなり重複を減らすことができるんです。

perlcodesampleperlcodesample 2013/02/28 09:34 Yさん

>動的型付けは逆で、品質を多少下げてでも表現力が必要な時に利用する。

 どうしてみなさん、動的型付けは、品質が下がるようなイメージをもっていらっしゃるのでしょうか。動的型付け言語で、大規模でバグの少ないWebサイトが作られているので、品質が下がるということはないと思いますよ。

perlcodesampleperlcodesample 2013/02/28 09:40 >heisseswasser


>しかし、変更されやすいという点で見れば、自分で実装しているクラスで、メソッドから返すオブジェクトをObjectAからObjectBに内部的に変更したり、使用しているライブラリのクラスで、バージョンアップに伴ってメソッド名が変わったというようなインターフェースが変更があった場合に、動的型付け言語では、実行時に、変更があったクラスを使用する側の、変更箇所に関係する部分に運良く実行が到達するまで、インターフェースの変更が検知できません。

 機能として利用されているのであれば、試験したときにわかるので、タイミングの問題だと思います。また本当に100%近くの品質を保証したいのであれば、その部分に関しては、試験を書くべきで、コンパイルチェックにたよるべきではないと思います。

.. 2013/02/28 09:42 > みなさん静的な型を持っていると「ある種のバグ」が減ると思っていらっしゃるようですが、もし型が間違っていれば、試験をしたときにどちらにしろ発見できるので、バグの多い少ないには影響しないと思います。

静的な型を持っていない場合、型が間違っていることを試験しないと発見できない。
静的な型を持っている場合、型が間違っていることを試験せずともコンパイルする際に発見できる。

> それを実行時に確認するのは、それほどめんどうなことでもないです。コンパイル時か実行時かという、発見の時期が異なるだけだと思います。


静的な型を持っていない場合、それほどめんどうなことでなかったとしても実行時に確認する必要がある(手動)。
静的な型を持っている場合、コンパイル時に確認される(自動)。

わた春香わた春香 2013/02/28 09:48 ここでの問題は perlcodesample 氏が想定している C++, Java などのやや古典的(?)な型付き言語と、型と聞いて条件反射的にヒャッハーとやってくるモヒカン達が考える強力な型付き言語との間には幾らかのギャップがあるということですね。
ぶっちゃけその両者は別物と考えてください。後者は計算機科学者たちが数々の数式による証明を元に作り上げた「ぼくのかんがえたさいきょうのぷろぐらむげんご」なので実務畑から叩き上げられた言語とは毛色が違うんです。

モヒカンさん達の言っているのは、「機械的な計算で除去できる間違いは機械に探させたほうが良い」ということです。例えば java のヌルポや一般的な LL の意図しない nil 値エラーの類は強力な型付けによって除去できることが数学的に証明できるとか。

Ruby で書いていると「こんなエラーは静的に指摘できるはずだろ」と本人の能力は棚に上げてPCを窓から放りたくなりますが、Haskell で書いていると「なんでこれで型エラーが出るんじゃい」と本人の能力は棚に上げてPCを窓から放りたくなるのです。

TANUKIMARUTANUKIMARU 2013/02/28 09:55 精鋭ばかりのチーム/個人的趣味内で実装:多いに賛成、利便性を最大限に利用しましょう。
ただ現実を見れば、、安全性、保守性の点でどうしても手放しでは賛成できない。

このプログラム言語に関するエントリを拝読させていただき、純然たる言語である日本語にも
通じるものを感じました。日本語はよく省略される言語だと言われます。
それはつまり、多少の言葉が省かれていてもコンテキストを通じて意味・意思を伝えることができるが
同時に文脈(とその理解)が不十分であれば伝え方、解釈のされ方は多様なものとなります。
我々ネイティブは、貴殿が挙げられているような素晴らしい利便性を享受できていますが
はたしてそれはマジョリティとなり得るのかどうか…。

sumiisumii 2013/02/28 09:59 「完全(complete)な実行時テストを行えばコンパイル時検査は要らない」というのは正しいと思いますが、一般には入力は無限にありうるため「完全な実行時テスト」は不可能なので、前提が成り立たないですよね。

もちろん、(今のところは)静的型つけでは(現実的には)検査できない性質も多いので、コンパイル時検査があるからといって実行時テストが不要になるわけでもないです。単に実行時テストの「一部」が不要(かつ完全)になるだけです。ただし、(Javaぐらいだと微妙ですが)MLやHaskellのようなバリアント型(直和型)とそれに対するパターンマッチングの網羅性検査は、よく言われるNull (None)チェック等を含め「場合分けの漏れ」も防いでくれるので、その「一部」が大きいだけだと思います。

ちなみにいろいろなところでしつこく言っていてすみませんが、"static typing language"ではなく"statically typed languageなので、日本語で言うと「静的型付け言語」ではなく「静的型付き言語」です。:-)

perlcodesampleperlcodesample 2013/02/28 10:03 .さん


>静的な型を持っていない場合、型が間違っていることを試験しないと発見できない。
>静的な型を持っている場合、型が間違っていることを試験せずともコンパイルする際に発見できる。

>静的な型を持っていない場合、それほどめんどうなことでなかったとしても実行時に確認する必要がある(手動)。静的な型を持っている場合、コンパイル時に確認される(自動)。

 型間違いが、頻繁に起こるのであれば、コンパイルチェックは開発効率を上げるかも知れませんが、型間違いなんて、普通にプログラムを書いていれば、あまり起こらないと思うんです。

 静的な型を持つ言語で開発していても、一回は絶対試験しますよね。そのときにバグがあれば、型間違いを見つけることができます。だから、タイミングの問題だけで、手間はあんまり変わらないと思います。

わた春香わた春香 2013/02/28 10:06 あとあれですね、そもそも Haskell なんかには変数自体が存在しないっていう。代入とは人類の犯す最も恐るべき悪徳だとか何とか。

わた春香わた春香 2013/02/28 10:08 > 型間違いなんて、普通にプログラムを書いていれば、あまり起こらないと思うんです。

それが死ぬほど起こるんですなこれが。静的型付き関数言語のプログラミングは型エラーとの格闘です。

anonymousanonymous 2013/02/28 10:10 input/outputのテストだけとおっしゃいますが、それはあくまでビヘイビアであってユニットテストとしては不足していますよね。カバレッジ100%を目指す場合、動的型付言語であろうと型に関するテストも必要だと思います(発生頻度の問題ではありません。)し、そうなるとテストコードは膨れ上がります(しかも人手で書くテストコードはバグが存在する可能性があります)。
少なくともこの1点について、静的型付き言語はコンパイル時にコンパイラによって保障されたチェックが可能なわけですから、テストコードまで含めて一つのプロダクトだと考えると一長一短ではありませんか。どなたかがおっしゃっていましたが、トレードオフの関係です。どちらが優れているというのではなく、*あなたが*重要視しているコードの簡潔性を実現するためには動的型付き言語が適している、というだけではありませんか。

perlcodesampleperlcodesample 2013/02/28 10:12 わた春香さん

>モヒカンさん達の言っているのは、「機械的な計算で除去できる間違いは機械に探させたほうが良い」ということです。例えば java のヌルポや一般的な LL の意図しない nil 値エラーの類は強力な型付けによって除去できることが数学的に証明できるとか。

 それは、理論的に、コンパイル時にチェックできるという意味ですよね。実際の開発のことを考えれば、型間違いのコンパイルエラーなんて普段そんなに目にしないと思うんです。プログラムするときに、数値を意図している変数に文字列を代入したりはしないし、その逆もないと思います。オブジェクトを代入しようと意図している変数に、数値を代入したりはしないと思います。

 もし仮に間違えていれば、一度実行したときに気づいて修正できると思うんです。

perlcodesampleperlcodesample 2013/02/28 10:28 anonymousさん

>input/outputのテストだけとおっしゃいますが、それはあくまでビヘイビアであってユニットテストとしては不足していますよね。

 不足しません。条件分岐のすべてをとおる試験を用意すれば、関数の単体試験しなくっても、その条件分岐に関して、カバレッジは100%になります。試験は必要でなければ、細かくしすぎないほうがよいと思います。型チェックのための試験の量が増えるというのは、間違いです。


>少なくともこの1点について、静的型付き言語はコンパイル時にコンパイラによって保障されたチェックが可能なわけですから、テストコードまで含めて一つのプロダクトだと考えると一長一短ではありませんか。

 スクリプト言語は、コンパイルチェックを行うので、多くの文法エラーをはじいてくれます。しないのは、型に関してです。静的な型をコンパイル時にチェックしてくれるから、品質があがるというのは、信じられません。やっぱり品質は、試験で担保すべきです。

perlcodesampleperlcodesample 2013/02/28 10:34 わた春香

>静的型付き関数言語のプログラミングは型エラーとの格闘です。

 Perlではあんまり闘った記憶がないなぁ。

perlcodesampleperlcodesample 2013/02/28 10:41 TANUKIMARU

>ただ現実を見れば、安全性、保守性の点でどうしても手放しでは賛成できない。

 これはJavaやC#を使うという意味でしょうか? どうして、静的な型づけ言語を使うと、安全性が上がるのかが理解できないです。

 安全性、保守性というのが、多くの人が経験を持っていて、人員が確保しやすいという意味であれば、この議論とはぜんぜん関係のない話です。

perlcodesampleperlcodesample 2013/02/28 10:49 sumiiさん

>単に実行時テストの「一部」が不要(かつ完全)になるだけです。

 はい。そのとおりだと思います。でも結局、静的型付き言語でも、実行時試験をしなくっちゃいけないので、確認する項目が減るわけでもないと思います。

わた春香わた春香 2013/02/28 11:01 > オブジェクトを代入しようと意図している変数に、数値を代入したりはしないと思います。

僕はするね!(確信

まあ静的型付き関数言語の型というのは、単に数値型かオブジェクトかというような違いではなくもっと面倒なものなので、感覚は違うかと思います。

> もし仮に間違えていれば、一度実行したときに気づいて修正できると思うんです。

運が良ければ。悪かったらロケットが墜落しますね^^

> Perlではあんまり闘った記憶がないなぁ。

前述しましたが、型の概念が違うからです。強力な型付けというのは、型エラーをたくさん出すことによって、実行可能なコードが出来た時にある一定レベルの間違い(このレベルが動的な方の言語よりもかなり高い)が存在しないことを保証しているんです。perl で書くのと同じ感覚で haskell や ocaml を書くと、型エラーに振り回されてPCを投げ捨てたくなるのも前述したとおりです。

> でも結局、静的型付き言語でも、実行時試験をしなくっちゃいけないので、確認する項目が減るわけでもないと思います。

試験の項目は減ります。原理的にそうですし、経験上でもそうです。型を決めてコードを書いてコンパイラが型チェックをするという部分で、LL で書く試験のうちのいくらかを代わりに行なっていると考えてください。違いは、後者はそれをしなくても「動き」ますが,前者はそれをしないと実行すら出来ないということです。

要は、多くのエラーは「慎重にやれば」除けますが、モヒカンという人間は手を抜くことに全力を注ぐので、そんな作業はハノイの塔を動かすのと同義なのです。あとは手作業では 100% 取り除いたと確信するのは難しいのだから、それを 100% にする手段があるならそうするべきでは?という理性的な意見も一部にはあります。

大規模開発の話でも触れられていましたが、LL 系の言語の最大の利点は習得のしやすさだと思います。人手がかかるものを作るときには特に重視されますね。多少の厳密さを犠牲にしても、その分を「慎重にやる」事によってカバーしているんです。そのための優秀な手法やツールもたくさんありますしね。

結局言語もツールにすぎないので、要は適材適所ということではないかと。あとは宗教の話になりますから。それでも、型理論というのは C++ や Java では語り尽くせない深淵が広がっている世界です。一つ覗きこんでみるのも一興かと。除き返された時にはモヒカンになっているかもしれませんが。

anonymousanonymous 2013/02/28 11:13 > 条件分岐のすべてをとおる試験を用意すれば、関数の単体試験しなくっても
条件分岐の全てを通るのに、関数の単体試験をしないとはどのような状況でしょうか。
(そもそも条件分岐の全てを通る試験はinput/outputだけの試験ではないですよね。)

> スクリプト言語は、コンパイルチェックを行うので、多くの文法エラーをはじいてくれます。しないのは、型に関してです。静的な型をコンパイル時にチェックしてくれるから、品質があがるというのは、信じられません。やっぱり品質は、試験で担保すべきです。
どなたも、静的型付き言語なら試験を行わないとはおっしゃっていないと思いますよ。
それに、コンパイラによる型チェックも試験の一種でしょう。テストコードを書いていないというだけです。

恐らく想定している環境・対象がperlcodesampleさんと他の方々とで異なるのだと思うのですが、
例えば世の中には万が一にも失敗してはいけないシステムというものが存在します。そういったものは往々にして複雑なロジックを有していて、
単純に動作確認をしてエラーが起きたら修正すればよい、というわけには行かないものです。
そのようなシステムの場合、エラーが起きる*可能性*は極力排除しなければなりません。
動的型付き言語の場合、どんなに慎重に頑張っても型によるエラーが起きる*可能性*は0ではありません。その点で、静的型付き言語を選択するメリットが出てくるのです。

また、プロジェクトの規模が何十人規模になってくると、(良くないことではありますが)自分のあずかり知らぬところで関数の型が変わるというようなことも有り得ます。

あくまで想定するプロダクトの性質や開発方針によって選択するものであって、すべてにおいてどちらの方が優れている、というような基準は存在しないのではないかと。
あなたが接しているプロダクトがこの世の全てではない、ということを理解して頂けると、他の方がコメントで言及されているいろいろな事が腑に落ちると思います。

foofoo 2013/02/28 11:22 Haskell勉強しないでこんな文章かけるなんてすごい!
(無知を公開する勇気が)

くけーくけー 2013/02/28 11:34 > Cookpad、Github、mixi、はてな、faccbook、amazon、みんな動的な型を持つスクリプト言語を使って、大規模サイトを作っています

このうちの1つの中の人ですが, 紹介されたようなコードは保守性が低いという理由でレビューで拒否される可能性が高いです.

perlcodesampleperlcodesample 2013/02/28 11:42 くけーさん

>このうちの1つの中の人ですが, 紹介されたようなコードは保守性が低いという理由でレビューで拒否される可能性が高いです.

 どのコードでしょうか。

perlcodesampleperlcodesample 2013/02/28 11:44 fooさん

>Haskell勉強しないでこんな文章かけるなんてすごい!(無知を公開する勇気が)

 すべての知識なんてだれも持ってないんですから、議論するのに全部知っているという前提はおかしいと思います。そういう風に言うと、何の話もできなくなっちゃいます。

sumiisumii 2013/02/28 11:54 > でも結局、静的型付き言語でも、実行時試験をしなくっちゃいけないので、確認する項目が減るわけでもないと思います。

まっとうな型システムは健全なので、型システムやコンパイラのバグがなければ、型システムが保証している性質は実行時テストが不要になるので、減ります。

(すみません、書く場所を間違えた&削除できないので再投稿です)

perlcodesampleperlcodesample 2013/02/28 12:01 anonymousさん

>条件分岐の全てを通るのに、関数の単体試験をしないとはどのような状況でしょうか。
>(そもそも条件分岐の全てを通る試験はinput/outputだけの試験ではないですよね。)

 どうして入り口から到達できない条件分岐があるのかを知りたいです。その処理は、どこからアクセスされるのでしょうか?

>例えば世の中には万が一にも失敗してはいけないシステムというものが存在します。
>そういったものは往々にして複雑なロジックを有していて、
>単純に動作確認をしてエラーが起きたら修正すればよい、というわけには行かないものです。

 そのシステムは、ソースコードの変更をした後に、確認をしないで、本番に投入されるのでしょうか。複雑なロジックを有していることは、静的な型の議論とは何の関係もないと思います。

>また、プロジェクトの規模が何十人規模になってくると、(良くないことではありますが)自分のあずかり知らぬところで関数の型が変わるというようなことも有り得ます。

 試験したら見つかると思いますよ。コンパイルチェックか実行時チェックかの差だけであると思います。

>あくまで想定するプロダクトの性質や開発方針によって選択するものであって、すべてにおいてどちらの方が優れている、というような基準は存在しないのではないかと。

 そんなことを議論しているのではないです。「変数に型がないということの利点」についての議論です。他の言語の用途を否定したことは、一度もないです。

perlcodesampleperlcodesample 2013/02/28 12:13 わた春香さん

>運が良ければ。悪かったらロケットが墜落しますね^^

 シミュレーターなどで、試験せずに、ロケットに投入ということを意味しておられますか。試験で、一度実行すれば、エラーがわかるということを僕はいっているのであって、本番でいきなり実行するということは言っていないです。

>要は、多くのエラーは「慎重にやれば」除けますが、モヒカンという人間は手を抜くことに全力を注ぐので、そんな作業はハノイの塔を動かすのと同義なのです。あとは手作業では 100% 取り除いたと確信するのは難しいのだから、それを 100% にする手段があるならそうするべきでは?という理性的な意見も一部にはあります。

 ソースコードの中では、プログラムのロジックを記述する部分が圧倒的に多いのに、、なぜ型の部分のチェックで信頼性を高めることができると考えているのかがわからないです。

 型チェックの分岐なんてソースコード全体の5%にみたないはずです。5%の信頼性をあげても、残りの95%の信頼性は上がらないです。

>結局言語もツールにすぎないので、要は適材適所ということではないかと。

 それはそのとおりで、僕がもともと認めているところです。でも今回の議論はぜんぜんそんな話をしているのではないです。「変数に型がないことの利点」について議論しているんです。言語否定とかは、一切していないです。

perlcodesampleperlcodesample 2013/02/28 12:18 sumiiさん

>まっとうな型システムは健全なので、型システムやコンパイラのバグがなければ、型システムが保証している性質は実行時テストが不要になるので、減ります。

 試験と言うのは、必ずしも型の試験をする必要があるわけではないです。ある入力に対して、正しい出力が得られることを試験すれば、十分なことがほとんどです。考えられるパターンで、網羅すれば大丈夫だと思います。

くけーくけー 2013/02/28 12:19 型を意識していないコードが感じられるコードはレビューで拒否されると思います.

たとえば
> 関数のオーバーロードが不要になる
のコードは, Strategy/Stateパターンにするか, 分割して1つの手続きでは1つの型しか受けいれないようにするインタフェイスの変更(その上で共通部分があればそこを1つの関数にするのはよい)が求められるでしょう.

わた春香わた春香 2013/02/28 12:29 > シミュレーターなどで、試験せずに、ロケットに投入ということを意味しておられますか。試験で、一度実行すれば、エラーがわかるということを僕はいっているのであって、本番でいきなり実行するということは言っていないです。

それは昔本当にそういうケースがあったということです。どんなに優秀な人材を集めて慎重に慎重を期しても人の手ですべてのテストを網羅するのは難しい。数学的に証明された検査は、それがカバーできるエラーは 100% 取り除けるので機械的なメソッドは信頼性の向上に大変有用である、ということです。

> 型チェックの分岐なんてソースコード全体の5%にみたないはずです。5%の信頼性をあげても、残りの95%の信頼性は上がらないです。

それがそうでもないのでモヒカンの皆さんが怒りかけているのです。型付きラムダ計算という理論から始まる、おそらく貴方がこの投稿をされた時に想定しておられなかった型理論というものが存在しており、それを元にした言語がここ10年やっと日の目を見るようになり、それが今ニッチな業界でトレンドを起こしているのです。貴方が想定している型というものと、世間で知られている型というものは大きく違う可能性があるので、少しお調べになってから結論を出されても遅くはないのではないかと思います。

anonymousanonymous 2013/02/28 12:31 > どうして入り口から到達できない条件分岐があるのかを知りたいです。その処理は、どこからアクセスされるのでしょうか?

上の方で入力と出力だけテストすれば良いとおっしゃっていたので、全分岐をテストするのは入出力の確認だけではないですよね、と申し上げました。それに、全分岐テストしていれば関数単体のテストもそこに含まれるのではないかと。
到達できない条件分岐があるなどとは一言も書いておりません。

> そのシステムは、ソースコードの変更をした後に、確認をしないで、本番に投入されるのでしょうか。複雑なロジックを有していることは、静的な型の議論とは何の関係もないと思います。

確かに複雑なロジックは関係ないですね。撤回します。
改めて"止まってはいけない"という一点のみで言及すると、動的型付き言語はどんなに慎重にテストを頑張っても型エラーが起きる*可能性を排除できない*ため、
例示したようなシステムには向いていない = *このケースでは*動的型けがデメリットになる という事です。
(perlcodesampleさんは、このエラーが起きる可能性というものを甘く見ているように思います。可能性が限りなく0に近づこうとも、0ではありません。万が一が本番運用時に起きてはまずいのです。誰かの首が飛ぶ可能性がある程度には。)

> そんなことを議論しているのではないです。「変数に型がないということの利点」についての議論です。他の言語の用途を否定したことは、一度もないです。

あなたの文章からは、動的型付けであることのデメリットがパフォーマンス面しかないように読み取れます。
利点を議論するためには欠点の議論も必要ですよね。
私がお伝えしたいのは、あなたが「利点」として挙げている項目は対象の性質によっては「欠点」にもなり得るので、その点についてもちゃんと考えましょうよ、という事です。
動的型付けが悪いとは全く思っていませんし、他の言語の用途を否定されたとも思っていません。

(ただ、動的型付けであろうとなかろうと裏にある「型」は意識しないとまずいとは思いますが…。)

perlcodesampleperlcodesample 2013/02/28 12:37 くけーさん

>関数のオーバーロードが不要になるのコードは, Strategy/Stateパターンにするか, 分割して1つの手続きでは1つの型しか受けいれないようにするインタフェイスの変更(その上で共通部分があればそこを1つの関数にするのはよい)が求められるでしょう.


 方針としては、よいと思いますが、異なる型の間で類似があった場合は、許容される場合もあります。

 たとえば文字列あるいは、オブジェクトを受け取ることができる関数があったとします。URLを文字列で受け取ることもできるし、URLオブジェクトを受け取ることができるような場合です。

my $url_str = 'http://some.host.com';
my $url_obj = URL->new('http://some.host.com');

このような場合は「Strategy/Stateパターンにするか, 分割して1つの手続きでは1つの型しか受けいれないようにする」という原則を、貫く必要がないと思います。

some_func($url_str);
some_func($url_obj);

# こちらは、くけーさんの方法
some_func_str($url_str);
some_func_obj($url_obj);

どちらを選択するかは、実装者が利用者にどう使ってほしいかと思うかによると思います。最初のパターンであれば、関数がひとつですむので、重複が少なく、保守性が上がりますね。

ふえぇふえぇ 2013/02/28 12:37 あの…あきらかにブログ主様の勉強不足ってだけの話ではあるんだけど。
米欄でボコボコ叩いたところで、型理論に関する下地かできてないのでスッと受け入れられるもんでは無いかと。

ちゃんと理論を勉強できれば良いけど、型付きラムダ計算はいきなり敷居が高すぎるし…
とにかく、もっと色んな言語を触ってみましょう。できればOCamlやHaskellなどで関数プログラミングの考え方を身に付けると良いかな。
2年も勉強すればこの記事は消したくなりますぜ(ニヤッ

perlcodesampleperlcodesample 2013/02/28 12:51 わた春香さん

>数学的に証明された検査は、それがカバーできるエラーは 100% 取り除けるので機械的なメソッドは信頼性の向上に大変有用である、ということです。

 でも計算間違い、分岐間違い、ロジックの間違い、画面の表示のエラーとか、プログラムで書く大半の部分のバグは、取り除けないですよね。カバーできる範囲が多いという論拠が、どこにあるのかが僕にはよく理解できないです。

>それが今ニッチな業界でトレンドを起こしているのです。貴方が想定している型というものと、世間で知られている型というものは大きく違う可能性があるので、少しお調べになってから結論を出されても遅くはないのではないかと思います。

 どの業界で、どんな分野で、信頼性を高めるのに役立っているのかを教えてください。それを教えてくれれば、あぁこの分野ではこうなのかぁということが理解できますが、すべての議論は漠然としていて、たんなる過剰不安なんじゃないかなぁと言う気持ちを僕に起こさせます。

perlcodesampleperlcodesample 2013/02/28 12:55 ふえぇさん

>あの…あきらかにブログ主様の勉強不足ってだけの話ではあるんだけど。

 そういうふうにいったら、何かに疑問をもっている人とかが、何も書けなくなるでしょう。この記事は「静的な型を持たないことの利点」について書いているのであって、関数型言語との比較について書いているのではないです。

ukayareukayare 2013/02/28 12:56 > でも計算間違い、分岐間違い、ロジックの間違い、画面の表示のエラーとか、プログラムで書く大半の部分のバグは、取り除けないですよね。カバーできる範囲が多いという論拠が、どこにあるのかが僕にはよく理解できないです。

あなたがコンピューターよりも性格に網羅的にカバーできるという根拠を教えてください

DryadDryad 2013/02/28 12:57 > どの業界で、どんな分野で、信頼性を高めるのに役立っているのか
こちらの記事とか良いのではないでしょうか。ちと長いですが(´・ω・`) http://ymotongpoo.hatenablog.com/entry/20111105/1320506449

sumiisumii 2013/02/28 13:05 > ある入力に対して、正しい出力が得られることを試験すれば、十分なことがほとんどです。考えられるパターンで、網羅すれば大丈夫だと思います。

それを人間がやるのは困難なので現に多くの人が苦労していて、実際に漏れが生じてバグやセキュリティホールになっているから、場合分けなどの漏れをコンパイル時に防ぐ静的検査が有用なのだと思いますが、まあそう思わないというのであれば仕方がないです。

ふえぇふえぇ 2013/02/28 13:14 学ぶべきは道具(関数型言語)の使い方、ではなく、プログラミングそのものに対する考え方(思想)のほうです。
変数に値を代入するというのはどういう事か、その値を計算/演算するというのはどういうことか、関数やメソッドを呼び出すというのはどういうことか、そこに型がどのように関わってくるのか…プログラミングは単なる手続きの記述では無いのです。
静的型付の関数型言語を身に付けることはそのための近道だと言っています。

主様が「型」という難しい題材について議論するのは、それからでも遅くないでしょう。

perlcodesampleperlcodesample 2013/02/28 13:15 anonymousさん

普通単体試験というのは、小さくわけた部品自体の試験をいうのだと思っています。

入力 -> A -> B -> C -> D -> E -> 出力

と続くとすれば、B,C,Dなどの細かな部分のチェックをしなくても、入力と出力をチェックできればよいという意味で書きました。

>改めて"止まってはいけない"という一点のみで言及すると、動的型付き言語はどんなに慎重に>テストを頑張っても型エラーが起きる*可能性を排除できない*ため、例示したようなシステムには向いていない = *このケースでは*動的型けがデメリットになる という事です。
(perlcodesampleさんは、このエラーが起きる可能性というものを甘く見ているように思います。可能性が限りなく0に近づこうとも、0ではありません。万が一が本番運用時に起きてはまずいのです。誰かの首が飛ぶ可能性がある程度には。)

 はい。このエラーが起きる可能性を甘く見ています。プログラムのロジックのバグのほうが圧倒的に量が多いと思いますし、それを排除できないのは、どのプログラミング言語も同じだからです。みなさんの反応を見ると、過剰不安ではないかと思っています。

わた春香わた春香 2013/02/28 13:19 > でも計算間違い、分岐間違い、ロジックの間違い、画面の表示のエラーとか、プログラムで書く大半の部分のバグは、取り除けないですよね。カバーできる範囲が多いという論拠が、どこにあるのかが僕にはよく理解できないです。 

その理解できない理由が型理論に対する不理解にあるということです。

> どの業界で、どんな分野で、信頼性を高めるのに役立っているのかを教えてください。

ニッチな業界ってのはある程度の狭い範囲の人たちの間でというくらいの意味にとってくださいな。

> たんなる過剰不安なんじゃないかなぁと言う気持ちを僕に起こさせます。 

それ以上は怒られるから言わん方がいい。


結局つまりみなさんが言っているのは、貴方がこの投稿で挙げた「利点」というのは、(習得のしやすさを除けば)型が強い言語でも等価なものが実現されているということです。この記事は単に perl が java や c++ より優れている点を述べているのみであって、その利点は perl の型が「弱い」ために生じているのではありません。

perlcodesampleperlcodesample 2013/02/28 13:30 Dryadさん

> どの業界で、どんな分野で、信頼性を高めるのに役立っているのか
> こちらの記事とか良いのではないでしょうか。ちと長いですが(´・ω・`)

 読みました。以下のように書いてありました。

>もちろん実際はそうは行きません。OCamlの型システムは多くのバグに対して役に立ちません。しかしながら、テストではかなり見つけにくいようなバグも含め、型システムが効果的なバグというのは驚くほどたくさんあります。

 でも実際の例が少ないので、もう少し、関数型言語の関連記事を読もうと思います。

わた春香わた春香 2013/02/28 13:30 うーんちょっと違うか。
perl は型を弱くすることによってその利点を身につけたけど、ある言語は型をより強くすることによってその利点を身につけた、くらいですか。C++ はしょうがないけど Java の型の強さはホント中途半端。

くけーくけー 2013/02/28 13:32 程度問題ではあるので許容されることもあるのは否定しません.

ただし, コメントの例では

1.

some_func_str($url_str)
some_func_obj($url_obj)
の両方を作って

some_func_obj($url_obj) の実装は
{
some_func_str($url_obj->as_string);
}

とする($url_obj は 標準の URI のようなものとする)か

2.

some_func_str($url_str) だけにして
呼び出し側で $url_obj->as_string を呼ぶ

のどちらかへの変更で, ソースの可読性
(この手続きだけでなく, 利用する側も含めて)
が上がり保守性が向上すると考えます.

perlcodesampleperlcodesample 2013/02/28 13:36 くけーさん

 一般的には、ケースバイケースだと思いますよ。規約がある程度社内に存在するなら、それを守るのがよいと思います。

anonymousanonymous 2013/02/28 13:38 > 入力 -> A -> B -> C -> D -> E -> 出力
> と続くとすれば、B,C,Dなどの細かな部分のチェックをしなくても、入力と出力をチェックできればよいという意味で書きました。

perlcodesampleさんを除く、コメントされた(少なくともカバレッジという言葉を持ち出された)全ての方は、単体テストとはA,B,C,D,E全てテストすることだという前提で考えられていると思います。
私もそうです。
そうしないと出力以外の副作用を確認できませんし、もしかしたらその出力はたまたまあっていただけかもしれません。
B、C共にバグっていたため結果が正しく見えた、ということが有り得るからです。実際よくあります。

> はい。このエラーが起きる可能性を甘く見ています。プログラムのロジックのバグのほうが圧倒的に量が多いと思いますし、それを排除できないのは、どのプログラミング言語も同じだからです。みなさんの反応を見ると、過剰不安ではないかと思っています。

上記の通り、少なくとも私が言及したようなミッションクリティカルなシステムにおいては(他も程度の差こそあれそうだと思いますが)厳密なテストが求められます。
確かにバグを全て排除できるとは言いませんが、*上記のようなテストを行った上で*更に信頼性を高めるためには、型は非常に有用なのです。コンパイラによって保障されているのですから。
甘いテストによる抜け漏れを後からフォローするよりも、過剰不安であっても極限まで信頼性を高める必要があるシステムも存在するという事をご理解ください。

最後に一点補足しますが、どなたも静的型付けだからテストしなくていいとは言っていないですが、そこは伝わっているのでしょうか。
そこが少し気になりました。

...... 2013/02/28 13:42 > この記事は「静的な型を持たないことの利点」について書いているのであって、関数型言語との比較について書いているのではないです。
「型」に関する記事で避けて通れない「型理論」の話がしたくて出てきている関数型言語の話なのに、
どうして「関数型言語との比較について書いているのではない」と逃げてしまうのだろう?
自分が型理論について疎いのなら少し調べてみればよいだけなのに。

perlcodesampleperlcodesample 2013/02/28 13:45 ふふぇさん

>学ぶべきは道具(関数型言語)の使い方、ではなく、プログラミングそのものに対する考え方(思想)のほうです。変数に値を代入するというのはどういう事か、その値を計算/演算するというのはどういうことか、関数やメソッドを呼び出すというのはどういうことか、そこに型がどのように関わってくるのか…プログラミングは単なる手続きの記述では無いのです。静的型付の関数型言語を身に付けることはそのための近道だと言っています。主様が「型」という難しい題材について議論するのは、それからでも遅くないでしょう。

 僕はこの記事で型理論について書いているわけではないですし、型理論の専門家でもないです。僕はこの記事で、変数にどのような型の値でも代入できることの利点を書いているだけです。

ふふぇwふふぇw 2013/02/28 14:05 理論を知らずに何故「型」について語れるんだろう…

まぁ…
あなたが無知を認めず、間違いだらけのこのエントリーに胸を張り続けたいならそうすれば良いでしょう。

perlcodesampleperlcodesample 2013/02/28 14:09 anonymousさん

>そうしないと出力以外の副作用を確認できませんし、もしかしたらその出力はたまたまあっていただけかもしれません。B、C共にバグっていたため結果が正しく見えた、ということが有り得るからです。実際よくあります。

 でも粒度を小さくするかどうかは、信頼性がどれだけ求められるかに依存すると思います。試験を増やすと、ソースコードを書き換えたときに、関連する試験すべてを書き直さないといけないので、内部の変更が行いにくくなるので、ケースバイケースだと思います。

 テストケースをうまく選択すれば、入力と出力の結果確認でよい場合も多いと思います。

>確かにバグを全て排除できるとは言いませんが、*上記のようなテストを行った上で*更に信頼性を高めるためには、型は非常に有用なのです。コンパイラによって保障されているのですから。

 ミッションクリティカルなシステムには静的な型を持つ言語が必要と主張されますか。それは言いすぎだと思います。たとえば、Webから取引するような証券システムをPerlやRubyやPythonで組んでもよいと僕は思います。

通りすがりの者ですが・・・通りすがりの者ですが・・・ 2013/02/28 14:16 > すべての知識なんてだれも持ってないんですから、議論するのに全部知っているという前提>はおかしいと思います。そういう風に言うと、何の話もできなくなっちゃいます。

このブログが香ばしいことになってるのは、無知な為の誤謬を識者が諭してくれているのに無知な故それを理解せず足りない知識の上に成り立つオレオレ理論をひけらかしてるところ。リアルでいたらほんとに香ばしいと思いますよ( ´ー`)y-~~

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証