この自分専用 Wiki とかの文章編集を、ブラウザの Text まどでやるのはつらいので、w3m + xyzzy なんかをつかっていたんだけど、 ふと思い立って、Chrome 拡張でいいのがないか探してみた…んだけど、Chrome 拡張ではいまいちいいのが見つからず。
どうも、Firemacs がいいらしいので、ひさしぶりに Firefox をインストールした。 なんか、最新の Firefox には対処中とのことで、ESR をインストールして、firemacs をインストール。
わー、良い。とても良い。
ぼちぼち、ユーザ定義型などの実装にとりかかろうと考えて、 data 宣言の取り込みをきれいにすることを考えていた。 data 宣言は、型推論向けの仮定 ([Assump] )だけでなく、パターンマッチのための arity, constructors のために蓄積されていく必要がある。
そこで、Efficient Compilation of pattern-matching を読み直しつつコードの見直しを していこうとし始めた(昨日あたりから)。
ふと、この論文にのっている mappairs や nodups は処理できるんかなと 試してみたら…だめじゃん! ふつうの map にあたる mymap サンプルでもだめ。
でも、まだ nodup はだめ。こちらは、ガードが未対応なんだと思う。
そこで、ガードを用いない nodup0 を用意してみたけど、そちらも、辞書渡し形式のところでだめっぽい。
$ ./test-compile.sh testcases/nodup0.hs source file: testcases/nodup0.hs dst dir: /nodup0 doCompile ... done. implicitPrelude ... done. doCompile ... bunnyc.exe: Error: dictionary not found: Prelude.==, (Tyvar ".t23" Star,[(Tyvar ".t26" Star,TVar (Tyvar ".t11" Star)),(Tyvar ".t3" Star,TVar (Tyvar ".t11" Star)),(Tyvar ".t5" Star,TVar (Tyvar ".t11" Star)),(Tyvar ".v119" Star,TVar (Tyvar ".t11" Star)),(Tyvar ".t6" Star,TVar (Tyvar ".t12" Star)),(Tyvar ".t23" Star,TVar (Tyvar ".t12" Star))]) CallStack (from HasCallStack): error, called at src\DictPass.hs:168:32 in main:DictPass
調査なんかは明日以降にするとして、もしかして型推論がしくってるのか?と思って --ddump-assump で確認してみたが、nodup 関数の型推論はあっているっぽい。(nodups :: Eq a => [a] -> [a] にあたる内容)
Main.nodups :: Forall [Star] ([IsIn "Prelude.Eq" (TGen 0)] :=> ([g0] -> [g0]))
というわけで、型推論はあってるけど辞書渡しがうまくないということで継続。 Case の scrut の処理がまだなのが怪しいな。
いちばん長大だった Semant にここ数日とりかかっていて、そういえば、 これを書いていたときは色々悩みながらで混乱していたり、 Haskell 的な書き方がいまいちだったりで、今見ると結構書き直すところがあった。 そうすると多少は行数も減るのだが、やっぱり 900 行は長すぎる。 書き直しでこれが半分以下になるわけではない。
そこで、Semant は、リネーミング部とトポロジカルソート部に分割することにした。 リネーミング部は、それでもまだ長かったので、さらに RenUtil と Rename の2つにわけた。
各モジュールは500行以内を目安にしよう。 そうなると Typing がオーバしているが、これは分割したくないので特例でおっけいしておきたい。
$ ./showlogs.sh src/Absyn.hs 151 lines 0 warnings 0 hint src/BindGrouping.hs 164 lines 0 warnings 0 hint src/CodeGen.hs 469 lines 0 warnings 2 hints src/CompilerOpts.hs 91 lines 0 warnings 0 hint src/Core.hs 44 lines 0 warnings 0 hint src/DDumpAssump.hs 15 lines 0 warnings 0 hint src/DDumpCore.hs 15 lines 0 warnings 0 hint src/Desugar.hs 18 lines 0 warnings 0 hint src/DictPass.hs 221 lines 0 warnings 0 hint src/NameMangle.hs 27 lines 0 warnings 0 hint src/Pattern.hs 121 lines 0 warnings 0 hint src/PreDefined.hs 182 lines 0 warnings 0 hint src/Rename.hs 496 lines 0 warnings 0 hint src/RenUtil.hs 213 lines 0 warnings 0 hint src/Semant.hs 50 lines 0 warnings 0 hint src/STG.hs 78 lines 0 warnings 0 hint src/Symbol.hs 39 lines 0 warnings 0 hint src/TrCore.hs 257 lines 0 warnings 1 hint src/TrSTG.hs 38 lines 0 warnings 0 hint src/Types.hs 47 lines 0 warnings 0 hint src/Typing.hs 644 lines 0 warnings 0 hint app/Main.hs 110 lines 0 warnings 0 hint ---- 3490 lines 0 warnings 3 hints
かつては無視していたコンパイラ警告に対処していて気付いたんだけど、 パタンを網羅していないといって怒られるのは、 データ定義が適切でないのが本質的な問題のようだ。
たとえば、クラス宣言だけに作用するような関数を書いたら、 「宣言はほかにもあるのに網羅してないよ」となる。 これは、それぞれ異なる処理が行われる、つまり、本質的に異なるものをまぜた データ型を定義しているのがよろしくないのかなと思う。
いまは、ワイルドカードでうけて error "must not occur" とかしているのだが、 こんなその場しのぎ対処ではなくて、Absyn の定義みなおそう。
あと、この調子でやっていくと、ある程度までは急激にコードがよくなっていくのだけど、 ある程度以上は「凝りすぎ」になってしまう傾向にあるので、 そうならないよう注意した方がよさそう。ずーっと同じ目でみるより、 すこし経ってから見た方かいいというのもあるし。
cwalk1 ブランチの目標期限をきめて、ちゃちゃっと次に進みたい。
あ、そうだ、書き直していて「おっ」と思ったことを、忘れぬうちにメモっておこう。
ほかにもあった気がしたけど…。やっぱり、データ型の階層みなおす必要を実感できたのが一番大きいかな。