型なし言語逝ってよし
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
NGNG0738731
NGNGそうね、rand()はまずいね。スマソ。
じゃ、引数に適当な整数を取って、それが0か非0かで分岐するってことで。
つまり>>735と同じ問題に帰着する。(735は動的型付、731は静的型付という違いはあるが)
実行コンテキストにおいて具体的な実パラメータが確定しなければ
関数の実体における仮パラメータを用いた式の型を確定させることはできないっしょ?
あ、ひょっとして実行コンテキストが確定して、今まさにその式を評価しているという時の話?
0739728
NGNG参照透過性を云々するのって奇妙な気がするんだけど。
MLにおける多相のようにすれば、静的に型決定できるわけで。
0740731
NGNGそのMLにおける多相ってのが>>731の1. parametric polymorphismなんだけど…
つまり型変数を使って任意の型の値を扱えるようにしたりとか(parametric polymorphism)
subtypeを使って型階層の部分木の任意の型の値を扱えるようにしたりとか(inclusion polymorphism)
演算子(または関数)オーバーロードや暗黙的型変換を使って複数の型の値を扱えるようにしたりとか(ad-hoc polymorphism)
参照の透明性があっても、ある変数が指す値(オブジェクト)の型は一意に制限されることはなく、
多様な値を取ることが出来る、ってこと。
0741728
NGNG参照透過性を確保することはデバッグしやすさに寄与
するでしょ。731は何がいいたいの?
0742731
NGNG静的に型決定できることと参照透明性は直接関係ない。
すなわち参照透明性を保障しても型は一意に決定できない。
また、型が一意に決定できることはデバッグしやすさに寄与しない。
MLの多相型などは型を一意に決定しないことで再利用性を確保し、
多相型に基づく型推論によってデバッグを支援している。
0743728
NGNGまあ、そうなんだけど、静的に型を決定できるようにコーディング
することはできるし、また、参照透過性を確保するようにコーディ
ングすることもできる。そのようなコーディングをすることがデバッ
グしやすさに貢献すると俺は考えているんだよ。
「型が一意に決定できることはデバッグしやすさに寄与しない」
ってのはどういう根拠によるの?
動的に型が決定する言語の場合、実行時にメソッドディスパッチ
するまで、そのメソッドの正当性を決定できないでしょ。それが
動的に型を決定する言語のメリットかつデメリットな部分だよね?
意識してメリットを享受している場合は良いけれど、無意識にデ
メリットをかぶるのは困るわけ。
それで、僕は、僕なりに動的に型を決定する言語においても、型
を静的に決定できるようなコーディングスタイルを励行すべきだ、
と考えているのだがね。参照透過性についても同様です。
0744731
NGNG> 静的に型を決定できるようにコーディングすることはできるし、
これは確かに可能ではあるよ。でもさ、これをやっちゃうと行き着く先はどうなるかというと、
「関数(メッセージ式)の返り値の型が一意に決定できるようにするためには、
関数(メッセージ式)の型が一意に決定できていなければならない。」
これが何を意味するかというと、
オブジェクト指向言語では、継承を放棄しなければならないということになる。いいの?
そこまで極論しなくても、メッセージ式の返り値の型を一意に決定できるようにするには
メソッドを定義するときには既存のメソッド名とは別の名前をつける必要があるよね。
それって、オブジェクト指向とは逆行するものだと思うよ。
例えば適当なSmalltalkの処理系、とりあえずSqueakでもいいや、
「at:」という名前のメソッドを列挙すると46個あったりするけど、
これはat:という名前から46個のメソッドが有り得てしまうという「混沌」かな?
それとも、46個の異なるメソッドを1つの名前に統一する「秩序」かな?
返り値が何だか全然わからないという点では「混沌」かもね。
でも、その「混沌」を排除しようとすると、「秩序」を破壊してしまって、
「さらなる混沌」が待っているよ。
0745731
NGNG> ってのはどういう根拠によるの?
「1つのバグの潰しやすさ」を「デバッグのしやすさ」とするのなら
多少は寄与する部分もあるかもね。しかし、
「1つのプログラム中のバグの数の減らしやすさ」を「デバッグのしやすさ」と捉えれば
関数(メソッド)の型を一意に決定することは逆効果だよ。
関数の型を一意に決定することは再利用を妨げることになり、
結果的にバグが混入する可能性を高めることにしかならない。
0746731
NGNGで、長くなっちゃったけど、
デバッグしやすいコーディングスタイルを模索することは素晴らしいことだと思うし、
無用な破壊的代入を減らすことはよいことだと思う。
しかし、それを「型を一意に決定する」に繋げるためには、
あまりにも大きな代償を払わなければならないし、
あるいはその代償を払わずに「型が一意に決定されている」という
誤った幻想を持つことも危険だよ。
0747横レス
NGNG>メソッドを定義するときには既存のメソッド名とは別の名前をつける必要があるよね。
>それって、オブジェクト指向とは逆行するものだと思うよ。
>例えば適当なSmalltalkの処理系、とりあえずSqueakでもいいや、
>「at:」という名前のメソッドを列挙すると46個あったりするけど、
>これはat:という名前から46個のメソッドが有り得てしまうという「混沌」かな?
総称は本来静的な考え方でしょ。同名の関数(メソッド)がいくつあっても
コンパイラや解釈系がどんな型へのメッセージかを一意に決定できて、別のものになる。
ソースコードのレベルで多相を実現しているに過ぎない。静的型の技術を用いている。
>「1つのプログラム中のバグの数の減らしやすさ」を「デバッグのしやすさ」と捉えれば
>関数(メソッド)の型を一意に決定することは逆効果だよ。
>関数の型を一意に決定することは再利用を妨げることになり、
>結果的にバグが混入する可能性を高めることにしかならない。
再設計とかリファクタリングの話をしているの?「型を一意に決定する」って
「オブジェクト指向な開発スタイルなのに、全部最初に矛盾なく決めてからやる」
ってことじゃないですよ。
0749728
NGNG戻り値が多様な型を持つ関数が見通しの良いコードに
貢献するってことでしょ。それは認めるよ。
でもさ、総称的な関数は、引数から戻り値を決定でき
るわけでしょ。たいていの場合は戻り値の型は容易に
推測できるよね? 容易に推測できない=慎重に使わ
ないと危険な総称的関数など、誰も使いたがらないだ
ろうし。
0750デフォルトの名無しさん
NGNG> でもさ、総称的な関数は、引数から戻り値を決定できるわけでしょ。
じゃあ、引数の型はどうやって決定する?
その引数の値を作った関数適用(メッセージ送信)の引数の型から?
じゃあ、そのまた引数の型は?
ってなことが延々と続くなり。
どっかでリテラルコンスタントにあたって型が決定できたとしても、
今度は>>731の2. inclusion polymorphismの例のようなコードはどうする?
あるいはAbstract Factoryなんかもいい例かもしんない。
ちなみに>>731は静的型付けしている場合の例だよ。
動的型付け言語では、もっとエキセントリックな事が極自然に行われる。
>>747
> 同名の関数(メソッド)がいくつあっても
> コンパイラや解釈系がどんな型へのメッセージかを一意に決定できて、別のものになる。
???
メソッド選択の話?
変数の型ではなくオブジェクトの型から決定しているところからしても、
いかにも動的型的だと思うのだが…
静的型の処理系であっても、いわゆるvirtualなメソッド探索なら
すごく動的言語的じゃない?
0751デフォルトの名無しさん
NGNG戻り値の型を明示しているから。
template<class T> T min(T a, T b) { return (a < b)? a : b; }
引数a、bと戻り値の型がTであり、同じ型だということを示している。
型なし言語の場合、明示しないから、戻り値の型は容易には推測できない。
0752デフォルトの名無しさん
NGNGダウト。正確にはTまたはTのサブタイプ(サブクラス)。
したがってその返り値にvirtualなメッセージ送信をした場合には
どのメソッドがディスパッチされるのかは確定できない。
保障されるのは、「対応するメソッドが存在する」ということだけ。
0753728
NGNGその変数の型を表現するよね。
aObject = Object::new()
クラス名を利用することもあるし、
if prodocut.code == target.code
return product.price
end
メソッド名を統一したりして、使うことも多いね。
もちろん、そういうコーディング規則では不十分なケースも
時々あります。でもね、たいていの場合は十分なんでありま
して、UnitTestを併用するなどして動的な型付けの言語でも、
型の不一致で予想外の挙動になることを避けることはできる
わけですよ。
で、僕が728で言ったことは「静的な型付けのおかげで回避
できるバグってどの程度のもの?」ということなんだけど、
悪いけど、ここで述べたようなコーディング規約で回避でき
る程度のバグだけなんじゃないの? って気がするわけ。
# ハンガリアン記法など、変数名で型を表現しているわけで、
# 静的に型を決定する言語においても、そのようなコーディ
# ング規約が有用であることを示していると思いますけどね。
0754751
NGNG継承も一緒に議論されているので、そっちの方が良かったですね。
あと次のような場合、その言い方であっているかわからなかったので。
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()));
}
0755751
NGNG私の場合、C言語ではアドレス演算子の付け忘れや、
ポインタ演算子の数の間違えなどのイージーミスを
エラーにしてくれるので、非常に助かっています。
っていうか、このスレを頭から「ミス」で検索してみるのがよいかと。
0757751
NGNG構造体を関数に渡すときに、変数のアドレスを渡す。foo(&record) ってな具合に。
で、ポインタ型の仮引数precordで受けたら、今度はbar(precord)というようにアドレスを渡す。
そんなんで、偶に付け忘れるわけです。
アドレス演算はあまり使わないようにはしているけど、どうしても必要な場面はありますから。
0758447
NGNG>できるバグってどの程度のもの?」ということなんだけど、
>悪いけど、ここで述べたようなコーディング規約で回避でき
>る程度のバグだけなんじゃないの? って気がするわけ。
あ、いや、僕もまさにそう(ソースコードレベルでのバグチェック)
だと思うんですけど。ほんで総称もソースコードレベルでの多態に過ぎないと
思ってたわけです。
0759デフォルトの名無しさん
NGNGソースコードレベルでの多態ってどういう意味?
0760デフォルトの名無しさん
NGNGこのスレ面白かったんで、勝手に適当に議論の一部分だけWikiにまとめてみました。
気が向いた人がいたら修正、加筆してくれるとうれしいです。構成とかも、全然変えて良いんで。
0761デフォルトの名無しさん
NGNG途中から関数言語ユーザーが乱入してきて
理解不能になってしまったんだけど...
関数型言語の考え方理解するとC++/Javaな
手続き型・オブジェクト指向言語でのコーディングに
良い影響を与えることってあるのかな?
それがあるならやりたいなとは思うんだけど。
0762デフォルトの名無しさん
NGNG> 逆に、型あり言語は実行時にそのようなエラーが起きる可能性があります。
の部分は?
0763デフォルトの名無しさん
NGNGおれとってはよい影響はあったよ。高階関数とか、マクロ(Lisp)とか。
逆に C/C++/Java がじれったくなることもあるけどね。
0764デフォルトの名無しさん
NGNGまあ、そこは型無し言語は、の間違いだろうけど、
静的型付け言語でも実行時型チェックが必要な場合は
結構多いよね。
JavaでいうNarrowing Type Conversionとか。
0765デフォルトの名無しさん
NGNG同意。
宣言的プログラミングのスタイルと
高階関数とカリー化と遅延評価に触れたことで、
手続き型ベースのオブジェクト指向言語でも
考え方の幅を広げるのにとても役に立ったと思う。
0766デフォルトの名無しさん
NGNGIt 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.
0767素朴な疑問
NGNGの暗黙の変換が行われる可能性がある型無し言語には、多大なリスクが
潜んでいると考えるのだが、どうなんだろ。
0768デフォルトの名無しさん
NGNGノイマン型がどう関係するんだろうか……
>暗黙の変換
型有りの C でも計算途中で型変換が起きるけど。
言語仕様に定められているので不測ではないが。
0769デフォルトの名無しさん
NGNG典型的な静的強型付けなJavaでも
計算途中に暗黙の変換が大量発生するよ。
そのうち、Narrowing type conversionは
動的型付け言語と同じリスクが潜んでいる。
静的型付けだと思って安心してると
とんでもないことになるぞ。
0770デフォルトの名無しさん
NGNGJLSちょっと見てみたけど、どれが危険なNarrowing conversion
かわからんかった。暗黙に行われるNarrowing conversionって
- 文字列化 (e.g., String s = "a" + 1 ;)
- 固定プリミティブ値のコンパイル時型変換 (e.g., byte b = 1 ;)
の2つだけのようだったけど。
0771769
NGNGうわ、スマソ。
> > 計算途中に暗黙の変換が大量発生するよ。
> > そのうち、Narrowing type conversionは
これじゃ確かに「暗黙のNarrowing conversionが発生してる」って意味になるな。
「そのうち」を「それ以外にも」と読み替えてくだされ。
欝だ。
0772デフォルトの名無しさん
NGNG暗黙のうちにやってくれるわけでしょ。滅多に発生
しないなら、明示的に変換するようにプログラマに
要求して良いわけだし。
ついでにいうと、型なし言語だからといって、暗黙
の型変換が行われると決まっているわけではないよ
ね。SmallTalkなんか、メソッドディスパッチを実
行時に行ないはしても、暗黙の型変換はないわけだ
し。
多大なリスクっていうけどさ、たとえばStandard
MLで書かれたプログラムは実行時に未定義の操作を
実行してシステムを停止させることが起こりえない
ことが証明されているわけだけど、C言語なんかは
まったく保証されていないよね。そういう意味では
Cで書かれたプログラムはStandard MLで書かれた
プログラムと比較して「多大なリスク」が潜んでい
ることになるわね。
でも、そんなStandard MLにしても、アルゴリズム
の正当性、すなわち「バグのなさ」について静的に
検証する方法はない。真に「宣言的プログラミング」
をサポートした言語「hoge」と比較したとき、
Standard MLは「多大なリスク」が潜んでいるとい
えるだろうね。
型なし言語がなくならないのは、現実的な理由から
だよね、つまるところ。現に便利なんだよ。リスク
があるのは確かだけれど、リスクが問題になりにく
い応用分野もあるし(たとえば繰り返し使わない、
使い捨てのスクリプトなどはリスクは問題にならな
い)、リスクを想定して対策をこうじることもでき
る(実行前にファイルをバックアップしておくとか
ね)。簡単に対策をこうじられて、プログラミング
が楽になるなら、リスクは受け入れることができる
んだよ。
0773デフォルトの名無しさん
NGNG0774デフォルトの名無しさん
NGNG0775デフォルトの名無しさん
NGNG(+ 1 2.0)は?
0776デフォルトの名無しさん
NGNGフローティング掲示板の欠陥ですね…
0777デフォルトの名無しさん
NGNGそいつは盲点ダターヨ
どうなるんだろうね。
規格書よんだらわかるかしら。
0779デフォルトの名無しさん
NGNG0780デフォルトの名無しさん
NGNGおまえがageるから落ちないのだ
0781デフォルトの名無しさん
NGNG0782デフォルトの名無しさん
NGNG0783デフォルトの名無しさん
NGNG0784デフォルトの名無しさん
NGNGつまりは「人間のミスをどこが補うか?」ってことでよろしいでしょうか。
0785shige
NGNG何かと思って触ったら鳥のフンだった。(ちょっと湿り気味の)
その瞬間を女子高生の集団に目撃され、
「うわっ、あの人超悲惨!」と大声で言われた。
0786デフォルトの名無しさん
NGNGひろゆきのカスにクッキ〜食われたぞこんちくしょおお
0787デフォルトの名無しさん
NGNGその定義で言うとPerlは型無し言語には入らない。
0788デフォルトの名無しさん
NGNG嫌なら自分で作ればいいのでは?
■ このスレッドは過去ログ倉庫に格納されています