『例外』を発生しないように Maybe や Either を徹底的に使うとしても、バグがなくなるわけじゃないよ。 bottom やメモリ不足で落ちることもあるし、undefined だってあらゆる値に紛れ込む可能性がある。 だいたい、head や undefined が存在したり div :: a -> a -> Maybe a じゃないことから見ても、Haskell はそういう設計思想を持つわけじゃない。 失敗しうるからといって div :: a -> a -> Maybe a にしたりすると、パフォーマンスにも致命的な影響が出る。 そして『例外』を徹底的に防ごう
バグを抑えやすい、かー (スコア:2)
Haskellを触ってみた感じ、デバッグが難しそうなんだけど、バグ自体が少ないから構わないって言うのかな?
Re: (スコア:4, 参考になる)
バグ自体が少ないと言っているのは,
・プロジェクト数が少ない
・実行時バグの余地が少ない
と2通りあります.
前者は仕方のないことで,
別に批判されるべきことじゃありませんよね.
後者については型システム(およびコンパイラ)が,
性質を静的に保障してくれることが多く,
これは開発のうえで非常に強力です.
デバッグの難しさについては,
ちょっと真面目にすごいH [amazon.co.jp]で勉強した私はそうは思いません.
まず, テストのしやすさは手続型言語よりも容易です.
また, 従来再現しにくいバ
Re: (スコア:0)
すごいH本にデバッギングの解説ってあったっけ?あんまり精読してないので、見落としたかも。
今ちょっと日本語版が手元にないので英語版 [learnyouahaskell.com](無料で全部読めるよ!)の目次見たけど、
それっぽいのが見当たらない
Re: (スコア:2)
デバッギングの解説はないですが,
実行中の挙動について表示させる例はありましたよね.
そう, 12章の"Walk in the line"の例です.
失敗するかもしれない関数landLeft,landRightの仕様をMaybeという文脈つけて変更していました.
でも実はこれだけじゃなくて,
純粋な関数であったとしても, トレースを使えます.
山本先生のブログ記事 [hatena.ne.jp]
究極的には, プログラムがstuckするのは,
パターンマッチに転けた場合が多いです.
そのときパターンマッチした際の値を得ることで,
原因は大体わかりますよね
Re: (スコア:5, 参考になる)
自分の書いたコードのパターンマッチングで落っこちるとちゃんと行番号が出てくるし、オプションつければ漏れがあっても警告出るから問題ないね。
困るのはゼロ除算や head [] で落ちたりとか、クラッシュせずに誤った結果を返してくるときとかかな。
head [] なんて、エラーメッセージは "Prelude.head: empty list" だけだからね。どうやって原因を突き止めろと。
trace を埋め込む場所がわかるなら、バグは半分見つけたようなもので……。
自分はその山本さんの記事も読んだことあるんだけど、
あと、例外がどこから来たのか知りたい場合は、GHC のデバッガを使うといいでしょう。
という一文にがっかりした覚えが。その GHCi のデバッガが、ほとんど役に立たないんだよ……。
だいたい GHCi (Haskell 処理系のデファクトスタンダードだね)のデバッガのマニュアルがこんな調子なんだよ。
プログラムをデバッグしている時にしばしば問われる問いの一つに、「どうやってここに来たんだ?」というものがある。伝統的な命令的デバッガは通常何らかのスタックトレースの機能を持っていて、それを使ってアクティブな関数呼び出しのスタック(字句的呼び出しスタックと呼ばれることもある)を確認することができる。このスタックによって、現在の地点に至るまでのコード上の道のりが分かる。残念なことに、これをHaskellで用意するのは難しい。正格な言語と違って、実行は深さ優先ではなく必要に応じて進むからである。
も
Re: (スコア:0)
場当たり的なコメントで申し訳ないですが,
head []はパターンマッチで書く方が筋が良い.
(listToMaybe的なものをつかっても一緒)
ゼロ除算はcatchするよりも,
Integerを使うか最初から除算に気をつければいい.
失敗するかもしれない演算なんだから.
手続き型言語の例外は最初から想定しているもので,
それぞれcatchすればいいよね, という風潮だけど,
関数型言語の例外は, 発生しないように書くという前提.
究極的には関数型言語を好きになるかどうかって,
例外が発生しうる範囲が非常に限定されているんだから, 最初から避けて設計するよね,
というのを受け入れるか否かの違いだと思う.
Re: (スコア:0)
最初から除算に気をつければいい.
『気を付ければいい』って具体的に何をすればいいの?
『例外』を発生しないように Maybe や Either を徹底的に使うとしても、バグがなくなるわけじゃないよ。
bottom やメモリ不足で落ちることもあるし、undefined だってあらゆる値に紛れ込む可能性がある。
だいたい、head や undefined が存在したり div :: a -> a -> Maybe a じゃないことから見ても、Haskell はそういう設計思想を持つわけじゃない。
失敗しうるからといって div :: a -> a -> Maybe a にしたりすると、パフォーマンスにも致命的な影響が出る。
そして『例外』を徹底的に防ごう
Re:バグを抑えやすい、かー (スコア:0)
あっ コメント消えたかと思ってたら、投稿できててかぶっちゃった。↑は気にしないでね