型なし言語逝ってよし

このエントリーをはてなブックマークに追加
739728:02/02/23 09:08
わざわざ静的な型決定ができなくなるような書き方をする場合に、
参照透過性を云々するのって奇妙な気がするんだけど。
MLにおける多相のようにすれば、静的に型決定できるわけで。
740731:02/02/23 10:39
>>739
そのMLにおける多相ってのが>>731の1. parametric polymorphismなんだけど…
つまり型変数を使って任意の型の値を扱えるようにしたりとか(parametric polymorphism)
subtypeを使って型階層の部分木の任意の型の値を扱えるようにしたりとか(inclusion polymorphism)
演算子(または関数)オーバーロードや暗黙的型変換を使って複数の型の値を扱えるようにしたりとか(ad-hoc polymorphism)
参照の透明性があっても、ある変数が指す値(オブジェクト)の型は一意に制限されることはなく、
多様な値を取ることが出来る、ってこと。
741728:02/02/23 13:29
だから静的に型決定できるようにコーディングして、
参照透過性を確保することはデバッグしやすさに寄与
するでしょ。731は何がいいたいの?
742731:02/02/23 13:42
>>741
静的に型決定できることと参照透明性は直接関係ない。
すなわち参照透明性を保障しても型は一意に決定できない。
また、型が一意に決定できることはデバッグしやすさに寄与しない。
MLの多相型などは型を一意に決定しないことで再利用性を確保し、
多相型に基づく型推論によってデバッグを支援している。
743728:02/02/23 14:20
>>742
まあ、そうなんだけど、静的に型を決定できるようにコーディング
することはできるし、また、参照透過性を確保するようにコーディ
ングすることもできる。そのようなコーディングをすることがデバッ
グしやすさに貢献すると俺は考えているんだよ。

「型が一意に決定できることはデバッグしやすさに寄与しない」
ってのはどういう根拠によるの?
動的に型が決定する言語の場合、実行時にメソッドディスパッチ
するまで、そのメソッドの正当性を決定できないでしょ。それが
動的に型を決定する言語のメリットかつデメリットな部分だよね?
意識してメリットを享受している場合は良いけれど、無意識にデ
メリットをかぶるのは困るわけ。
それで、僕は、僕なりに動的に型を決定する言語においても、型
を静的に決定できるようなコーディングスタイルを励行すべきだ、
と考えているのだがね。参照透過性についても同様です。
744731:02/02/23 16:41
>>743
> 静的に型を決定できるようにコーディングすることはできるし、
これは確かに可能ではあるよ。でもさ、これをやっちゃうと行き着く先はどうなるかというと、
「関数(メッセージ式)の返り値の型が一意に決定できるようにするためには、
関数(メッセージ式)の型が一意に決定できていなければならない。」
これが何を意味するかというと、
オブジェクト指向言語では、継承を放棄しなければならないということになる。いいの?
そこまで極論しなくても、メッセージ式の返り値の型を一意に決定できるようにするには
メソッドを定義するときには既存のメソッド名とは別の名前をつける必要があるよね。
それって、オブジェクト指向とは逆行するものだと思うよ。
例えば適当なSmalltalkの処理系、とりあえずSqueakでもいいや、
「at:」という名前のメソッドを列挙すると46個あったりするけど、
これはat:という名前から46個のメソッドが有り得てしまうという「混沌」かな?
それとも、46個の異なるメソッドを1つの名前に統一する「秩序」かな?
返り値が何だか全然わからないという点では「混沌」かもね。
でも、その「混沌」を排除しようとすると、「秩序」を破壊してしまって、
「さらなる混沌」が待っているよ。
745731:02/02/23 16:49
> 「型が一意に決定できることはデバッグしやすさに寄与しない」
> ってのはどういう根拠によるの?
「1つのバグの潰しやすさ」を「デバッグのしやすさ」とするのなら
多少は寄与する部分もあるかもね。しかし、
「1つのプログラム中のバグの数の減らしやすさ」を「デバッグのしやすさ」と捉えれば
関数(メソッド)の型を一意に決定することは逆効果だよ。
関数の型を一意に決定することは再利用を妨げることになり、
結果的にバグが混入する可能性を高めることにしかならない。
746731:02/02/23 16:56
sage忘れた。スマソ。

で、長くなっちゃったけど、
デバッグしやすいコーディングスタイルを模索することは素晴らしいことだと思うし、
無用な破壊的代入を減らすことはよいことだと思う。
しかし、それを「型を一意に決定する」に繋げるためには、
あまりにも大きな代償を払わなければならないし、
あるいはその代償を払わずに「型が一意に決定されている」という
誤った幻想を持つことも危険だよ。
747横レス:02/02/23 18:59
>こまで極論しなくても、メッセージ式の返り値の型を一意に決定できるようにするには
>メソッドを定義するときには既存のメソッド名とは別の名前をつける必要があるよね。
>それって、オブジェクト指向とは逆行するものだと思うよ。
>例えば適当なSmalltalkの処理系、とりあえずSqueakでもいいや、
>「at:」という名前のメソッドを列挙すると46個あったりするけど、
>これはat:という名前から46個のメソッドが有り得てしまうという「混沌」かな?

総称は本来静的な考え方でしょ。同名の関数(メソッド)がいくつあっても
コンパイラや解釈系がどんな型へのメッセージかを一意に決定できて、別のものになる。
ソースコードのレベルで多相を実現しているに過ぎない。静的型の技術を用いている。

>「1つのプログラム中のバグの数の減らしやすさ」を「デバッグのしやすさ」と捉えれば
>関数(メソッド)の型を一意に決定することは逆効果だよ。
>関数の型を一意に決定することは再利用を妨げることになり、
>結果的にバグが混入する可能性を高めることにしかならない。

再設計とかリファクタリングの話をしているの?「型を一意に決定する」って
「オブジェクト指向な開発スタイルなのに、全部最初に矛盾なく決めてからやる」
ってことじゃないですよ。
748747:02/02/23 19:02
すいません、過去レス読んだら、議論の最中に>>747みたいな蒸し返しレスを
入れちゃうパターンが延々と続いてましたね。これからは気を付けます。
749728:02/02/23 20:00
731が言っているのはあれでしょ、総称的な関数とか、
戻り値が多様な型を持つ関数が見通しの良いコードに
貢献するってことでしょ。それは認めるよ。
でもさ、総称的な関数は、引数から戻り値を決定でき
るわけでしょ。たいていの場合は戻り値の型は容易に
推測できるよね? 容易に推測できない=慎重に使わ
ないと危険な総称的関数など、誰も使いたがらないだ
ろうし。
>>749
> でもさ、総称的な関数は、引数から戻り値を決定できるわけでしょ。
じゃあ、引数の型はどうやって決定する?
その引数の値を作った関数適用(メッセージ送信)の引数の型から?
じゃあ、そのまた引数の型は?
ってなことが延々と続くなり。

どっかでリテラルコンスタントにあたって型が決定できたとしても、
今度は>>731の2. inclusion polymorphismの例のようなコードはどうする?
あるいはAbstract Factoryなんかもいい例かもしんない。
ちなみに>>731は静的型付けしている場合の例だよ。
動的型付け言語では、もっとエキセントリックな事が極自然に行われる。

>>747
> 同名の関数(メソッド)がいくつあっても
> コンパイラや解釈系がどんな型へのメッセージかを一意に決定できて、別のものになる。
???
メソッド選択の話?
変数の型ではなくオブジェクトの型から決定しているところからしても、
いかにも動的型的だと思うのだが…
静的型の処理系であっても、いわゆるvirtualなメソッド探索なら
すごく動的言語的じゃない?
型あり言語が総称を使った場合に戻り値の型が容易に推測できるのは、
戻り値の型を明示しているから。
template<class T> T min(T a, T b) { return (a < b)? a : b; }

引数a、bと戻り値の型がTであり、同じ型だということを示している。
型なし言語の場合、明示しないから、戻り値の型は容易には推測できない。
> 引数a、bと戻り値の型がTであり、同じ型だということを示している。

ダウト。正確にはTまたはTのサブタイプ(サブクラス)。
したがってその返り値にvirtualなメッセージ送信をした場合には
どのメソッドがディスパッチされるのかは確定できない。
保障されるのは、「対応するメソッドが存在する」ということだけ。
753728:02/02/24 11:24
動的な言語でコーディングするときは、しばしば変数名で
その変数の型を表現するよね。

aObject = Object::new()

クラス名を利用することもあるし、

if prodocut.code == target.code
  return product.price
end

メソッド名を統一したりして、使うことも多いね。

もちろん、そういうコーディング規則では不十分なケースも
時々あります。でもね、たいていの場合は十分なんでありま
して、UnitTestを併用するなどして動的な型付けの言語でも、
型の不一致で予想外の挙動になることを避けることはできる
わけですよ。

で、僕が728で言ったことは「静的な型付けのおかげで回避
できるバグってどの程度のもの?」ということなんだけど、
悪いけど、ここで述べたようなコーディング規約で回避でき
る程度のバグだけなんじゃないの? って気がするわけ。

# ハンガリアン記法など、変数名で型を表現しているわけで、
# 静的に型を決定する言語においても、そのようなコーディ
# ング規約が有用であることを示していると思いますけどね。
754751:02/02/24 11:44
>>752
継承も一緒に議論されているので、そっちの方が良かったですね。
あと次のような場合、その言い方であっているかわからなかったので。

class A {};
class B : public A {};

A& foo() { static B b; return b; }
char* bar(A a) { return "a"; }
char* bar(B b) { return "b"; }

void main() {
puts(bar(foo()));
}
755751:02/02/24 12:11
>>753
私の場合、C言語ではアドレス演算子の付け忘れや、
ポインタ演算子の数の間違えなどのイージーミスを
エラーにしてくれるので、非常に助かっています。
っていうか、このスレを頭から「ミス」で検索してみるのがよいかと。
756728:02/02/24 14:00
>>755
ありがと。でも、アドレス演算なんかそもそもバグの温床では?
757751:02/02/24 16:42
>>756
構造体を関数に渡すときに、変数のアドレスを渡す。foo(&record) ってな具合に。
で、ポインタ型の仮引数precordで受けたら、今度はbar(precord)というようにアドレスを渡す。
そんなんで、偶に付け忘れるわけです。
アドレス演算はあまり使わないようにはしているけど、どうしても必要な場面はありますから。
758447:02/02/24 23:27
>で、僕が728で言ったことは「静的な型付けのおかげで回避
>できるバグってどの程度のもの?」ということなんだけど、
>悪いけど、ここで述べたようなコーディング規約で回避でき
>る程度のバグだけなんじゃないの? って気がするわけ。
あ、いや、僕もまさにそう(ソースコードレベルでのバグチェック)
だと思うんですけど。ほんで総称もソースコードレベルでの多態に過ぎないと
思ってたわけです。
759デフォルトの名無しさん:02/02/25 03:20
>>758
ソースコードレベルでの多態ってどういう意味?
760デフォルトの名無しさん:02/02/27 22:23
http://hoge.s7.xrea.com/tiki/tiki.cgi?c=v&p=%B7%BF%A4%CA%A4%B7%B8%C0%B8%EC%C0%C2%A4%C3%A4%C6%A4%E8%A4%B7
このスレ面白かったんで、勝手に適当に議論の一部分だけWikiにまとめてみました。
気が向いた人がいたら修正、加筆してくれるとうれしいです。構成とかも、全然変えて良いんで。
761デフォルトの名無しさん:02/02/27 22:41
>1-9あたりまでは完全な糞スレだったのに良く伸びたね。
途中から関数言語ユーザーが乱入してきて
理解不能になってしまったんだけど...

関数型言語の考え方理解するとC++/Javaな
手続き型・オブジェクト指向言語でのコーディングに
良い影響を与えることってあるのかな?
それがあるならやりたいなとは思うんだけど。
>>760
> 逆に、型あり言語は実行時にそのようなエラーが起きる可能性があります。
の部分は?
763デフォルトの名無しさん:02/02/28 09:20
>>761
おれとってはよい影響はあったよ。高階関数とか、マクロ(Lisp)とか。
逆に C/C++/Java がじれったくなることもあるけどね。
764デフォルトの名無しさん:02/02/28 19:23
>>762
まあ、そこは型無し言語は、の間違いだろうけど、
静的型付け言語でも実行時型チェックが必要な場合は
結構多いよね。
JavaでいうNarrowing Type Conversionとか。
765デフォルトの名無しさん:02/02/28 19:30
>>763
同意。
宣言的プログラミングのスタイルと
高階関数とカリー化と遅延評価に触れたことで、
手続き型ベースのオブジェクト指向言語でも
考え方の幅を広げるのにとても役に立ったと思う。
SICPの序文にこうあるよね。
It is better to have 100 functions operate on one data structure
than to have 10 functions operate on 10 data structures.
As a result the pyramid must stand unchanged for a millennium;
the organism must evolve or perish.
767素朴な疑問:02/03/03 05:12
現在のコンピュータがノイマン型である以上、プログラマにとって不測
の暗黙の変換が行われる可能性がある型無し言語には、多大なリスクが
潜んでいると考えるのだが、どうなんだろ。
>>767
ノイマン型がどう関係するんだろうか……

>暗黙の変換
型有りの C でも計算途中で型変換が起きるけど。
言語仕様に定められているので不測ではないが。
769デフォルトの名無しさん:02/03/03 07:22
>>767
典型的な静的強型付けなJavaでも
計算途中に暗黙の変換が大量発生するよ。
そのうち、Narrowing type conversionは
動的型付け言語と同じリスクが潜んでいる。
静的型付けだと思って安心してると
とんでもないことになるぞ。
>>769
JLSちょっと見てみたけど、どれが危険なNarrowing conversion
かわからんかった。暗黙に行われるNarrowing conversionって
- 文字列化 (e.g., String s = "a" + 1 ;)
- 固定プリミティブ値のコンパイル時型変換 (e.g., byte b = 1 ;)
の2つだけのようだったけど。
771769:02/03/03 08:20
>>770

うわ、スマソ。

> > 計算途中に暗黙の変換が大量発生するよ。
> > そのうち、Narrowing type conversionは

これじゃ確かに「暗黙のNarrowing conversionが発生してる」って意味になるな。
「そのうち」を「それ以外にも」と読み替えてくだされ。
欝だ。
暗黙の型変換ってのは、頻繁に行われるからこそ、
暗黙のうちにやってくれるわけでしょ。滅多に発生
しないなら、明示的に変換するようにプログラマに
要求して良いわけだし。

ついでにいうと、型なし言語だからといって、暗黙
の型変換が行われると決まっているわけではないよ
ね。SmallTalkなんか、メソッドディスパッチを実
行時に行ないはしても、暗黙の型変換はないわけだ
し。

多大なリスクっていうけどさ、たとえばStandard
MLで書かれたプログラムは実行時に未定義の操作を
実行してシステムを停止させることが起こりえない
ことが証明されているわけだけど、C言語なんかは
まったく保証されていないよね。そういう意味では
Cで書かれたプログラムはStandard MLで書かれた
プログラムと比較して「多大なリスク」が潜んでい
ることになるわね。

でも、そんなStandard MLにしても、アルゴリズム
の正当性、すなわち「バグのなさ」について静的に
検証する方法はない。真に「宣言的プログラミング」
をサポートした言語「hoge」と比較したとき、
Standard MLは「多大なリスク」が潜んでいるとい
えるだろうね。

型なし言語がなくならないのは、現実的な理由から
だよね、つまるところ。現に便利なんだよ。リスク
があるのは確かだけれど、リスクが問題になりにく
い応用分野もあるし(たとえば繰り返し使わない、
使い捨てのスクリプトなどはリスクは問題にならな
い)、リスクを想定して対策をこうじることもでき
る(実行前にファイルをバックアップしておくとか
ね)。簡単に対策をこうじられて、プログラミング
が楽になるなら、リスクは受け入れることができる
んだよ。
LISPやschemeは型付け緩いけど暗黙の型変換は無いよ。
ここって、何回も同じ議論繰り返してるみたいね
775デフォルトの名無しさん:02/03/03 13:04
>>773
(+ 1 2.0)は?
>>774 分枝スレッドや、同意のとれた事項を分かりやすくまとめていけない、
フローティング掲示板の欠陥ですね…
>>775
そいつは盲点ダターヨ
どうなるんだろうね。
規格書よんだらわかるかしら。
778ネタ:02/03/04 03:28
>>774
議論に意味があるのではない。
議論することに意味があるのだ。
779デフォルトの名無しさん:02/04/13 21:53
なぜかこのスレdat落ちしないねage
>>779
おまえがageるから落ちないのだ
一年以上続いてるんだ。もはやム板の定番スレのひとつ?
ム板くるなら一度はおいでヽ(´ー`)ノ
783デフォルトの名無しさん:02/04/14 01:07
記念かきこ
784デフォルトの名無しさん:02/04/24 04:29
最初は面白かったのですけど、後半(300くらいから)は読んでませんが、

つまりは「人間のミスをどこが補うか?」ってことでよろしいでしょうか。
785shige:02/04/24 04:41
商店街を歩いていたら頭にポタッと何か落ちてきた。
何かと思って触ったら鳥のフンだった。(ちょっと湿り気味の)
その瞬間を女子高生の集団に目撃され、
「うわっ、あの人超悲惨!」と大声で言われた。

786デフォルトの名無しさん:02/04/24 04:52
しまったああああああああ
ひろゆきのカスにクッキ〜食われたぞこんちくしょおお
>50
その定義で言うとPerlは型無し言語には入らない。
>876
嫌なら自分で作ればいいのでは?