海野秀之(うんのひでゆき)の外部記憶
Twitter (twilog) / RSS / アンテナ / ぶくま
少し間が空いてしまった。まだ7章。
https://github.com/unnohideyuki/Tiger-in-Haskell
Frame.Frag を定義、Semant.transDec では [TL.Exp] や [Frame.Frag] を出力するようにし、LetExp の処理では [TL.Exp] を変数初期化式として用いるように。
[Frags] は、transDec の出力に加えるだけでは不十分で、transExp, transDec がつねに引き回さないといけない(状態)。
つぎは、[Frags] を状態として引き回す改造から、ソース部分としてのつづきは trexp for ArrayExp のあたりから続き。
また、Alex で Unicode を扱う方法についても、少し調べた。
Alex 3.x では UTF-8 を自然に扱えるようになっている。GHC のコードでは、Alex 2.x との互換性のために、getChar のなかで種別を判定して、種別ごとに「つぶした」値を返すようなトリックが用いられている。
Alex 3.x では、そのようなトリックは使わなくてもいいが、$uniwhite などを自前で定義してやらないといけない。
手で書いてはいられないので、生成するプログラムを書いた。
(unicateg.hs, まだローカルにしかない)
Lex.x にコピペで埋め込むのは可読性を下げるので、include しよう。少し不本意だけど cpp -P する。
https://github.com/unnohideyuki/Tiger-in-Haskell/tree/master/chap7
うーん、もうちょいか。
テストというか、動作確認はぼちぼちやりつつ、8章に進んでもいいかな。
といいつつ、明らかな誤りや未実装もあり。
あと、そろそろ pretty print ほしい。Real World Haskell に書いてあったの、読もう。
すっかり習慣化していたようなことでも、ある日ぴたりとやめることは、案外簡単かも。
「上手につきあう」よりは、よほど。
Ask, or it will not be given to you.
つまり、「本当はそう願っているだけ♪」ではいけないな、と。
「きゃりーは日本民族の誇り」、ワーナー会長が語る快挙
http://business.nikkeibp.co.jp/article/interview/20140711/268522/
それ、きゃりーぱみゅぱみゅと ystk がすごいという話であって、「日本」に広げるの無理では。
「プログラミング言語の基礎概念」読みたいので、買うか悩む。
買っても積んどくだけちゃうんかという点で。
これ以上、積むだけのために本を買いたくない。
短期目標は、Pretty Print を会得する、かな。
RWH では、べつに Pretty Print ライブラリに言及してないのか。
Text.PrettyPrint が簡単/便利すぎて感動する暇がなかった
Haskell はハードタブの幅を 8 だと思って処理するが、F# だったかな、は 4 だと思っているらしい。
これは、Unix 文化か Windows 文化か、という話らしいのだが、
「ハードタブつかうな」で済む話でもあるような。Haskeller はつかわないので、あんまりピンとこない。
The implementation of functional programming language の 5 章、Efficient Compilation of pattern-matching を読みながら、パターンコンパイラのお試しコードを書いてみた。
ファイルはこちら:Patterns.hs
たとえば、
mappairs f [] ys = []
mappairs f (x:xs) [] = []
mappairs f (x:xs) (y:ys) = f x y : mappairs f xs ys
↑これは、こうなる↓
-- demo1
case xs' of
Nil ->
[]
Cons x xs ->
case ys' of
Nil -> []
Cons y ys ->
f x y : mappairs f xs ys
nodups [] = []
nodups [x] = []
nodups (y:x:xs) = if y == x then nodups (x:xs) else y:nodups (x:xs)
↑これは、こうなる↓
-- demo3
case xs'' of
Nil ->
[]
Cons x' xs' ->
case xs' of
Nil -> [ x' ]
Cons x xs ->
if x' == x then nodups ( x : xs ) else x' : nodups ( x : xs )
case e of
[x,True] -> x
[False] -> True
z -> False
↑これは、こうなる↓んだけど、あってんのかなぁ。
-- demo4
case e of
Nil ->
False
Cons _u2 _u3 ->
case _u3 of
Nil -> case _u2 of
True -> False
False -> case _u3 of Nil -> True
Cons _u4 _u5 -> False
Cons _u4 _u5 ->
case _u4 of
True -> case _u5 of Nil -> _u2
Cons _u6 _u7 -> case _u2 of True -> False
False -> case _u3 of Nil -> True
Cons _u4 _u5 -> False
False -> case _u2 of True -> False
False -> case _u3 of Nil -> True
Cons _u4 _u5 -> False
foo True = 1 -- missing a pattern for False
↑これは、こう↓
-- demo5
case _u1 of
True ->
1
False ->
error
まだ、しっくり理解できているわけじゃなくて、とりあえず動くコードを書いてみた段階。
また、オーバーラップのあるパターンの対処はしてない (demo 2 がとばされているのは、そのため)。
水曜なのに、おそく帰ってきてしまい、しょっく。
今日はもう1時間くらいしかない。
今日は、Let it go の movie をヘビロテ気味に視聴。
これが、シナリオ書き換えまで引き起こしたという歌かーとか思いつつ。
The cold never bothered me anyway.
定冠詞だなーとは思ったけど、よく見ると過去形だったのか。
let it go は、雪の結晶が自己相似形である点について高らかにシャウトしていてすばらしいと思います(konami
Fractal には、自己相似形みたいな数学的なニュアンスを含まない、日常的な意味が先にある(あった)のかな。
すこし調べてみたけど、わかんない。
さいきん、VMPlayer 起動すんのがめんどくさくて、家でも会社でも、ぜんぜんつかってない。
もっぱら、Haskell Platform for Windows.
ターミナルがまともじゃなくて、ときどき萎える。
たまに Mac book がうらやましい。
Source Han Sans 素敵っぽい
同じ字でも言語ごとに異なる字体を用意してあるとか。
アドビは、デジタルエクスペリエンスを通じて世界を変えようとしており…
http://blog.typekit.com/alternate/source-han-sans-jp/
https://github.com/unnohideyuki/Tiger-in-Haskell/tree/master/chap7
今日は(あ、もう日付変わってる!)、帰ってくるの遅くなってしまって、痛恨。
static link の扱いあたりを追加してみたけど、動作がいろいろおかしい。
$ ./driver.exe < ../testcases/test6.tig
(UNIT,
[Proc {body = EXP (ESEQ (EXP (CONST 0)) (CALL (NAME "L0_do_nothing1") [TEMP 0,CONST 0,NAME "L3"])),
frame = Frame {name = "main", formals = [InFrame (-3)], locals = [], fp = 0}},
Proc {body = EXP (CALL (NAME "L0_do_nothing1") [TEMP 2,MEM (BINOP PLUS (CONST (-3)) (TEMP 2)),NAME "L2"]),
frame = Frame {name = "L1_do_nothing2", formals = [InFrame (-3),InReg 2], locals = [], fp = 2}},
Str "L2" "str",
Proc {body = EXP (CALL (NAME "L1_do_nothing2") [TEMP 1,BINOP PLUS (MEM (BINOPPLUS (CONST (-3)) (TEMP 1))) (CONST 1)]),
frame = Frame {name = "L0_do_nothing1", formals = [InFrame (-3),InReg 2,InReg 1], locals = [], fp = 1}}
])
落ちついてコードを追ってみよう。
そして、いまなお文字列比較まわりは未実装。
https://www.google.com/fonts/specimen/Noto+Sans
"No 豆腐" で Noto だったのか。(Adobe からは Source Han Sans)
Arrows Me 上でついった見てると、よく見かける気がする、豆腐。
(フォントなに選んでたかな?)
つかれてんのかな、「めばちこ」っぽい。めやにが…
MHonARC の mhmimetypes.pl に xlsx, pptx, docx に関するものがなかったので、足した。
どこかにメモっておかねば。(これは仕事の話)
やっぱ、よく考えずにつぶやくの、よくなかった。(知ってた)
(F.InFrame (-3 - n) : acc, temp)
ここの temp は t じゃないとだめ。このせいで、かならず formals の最初(static_link はいつも escapes)で temp が先祖がえりしてた。
平気で変数を shadow してる命名がよくない気がした。
Str "L3" はどこへ行った問題が未だ。
frame の formals には static_link を積んだのに、それを用いる側でそれを考慮できてない問題もまだ。
-fwarn-name-shadowing なのかな。-Wall つけるか。最初は大変そう。いまのうち、ではあるか。
http://www.kotha.net/ghcguide_ja/7.0.4/options-sanity.html
frame の formals には static_link を積んだのに、それを用いる側でそれを考慮できてない問題
わかった。
(_:as) = TL.acc_formals lev
こう直して、static_link の access を捨てればいい。(なんかイマイチの方法ではあるが)
気付いている問題は、あといっこか。> Str "L3" どこ?
週4回、夜だけのプログラミングでは、なかなか進まないけど、自分が書いたコードがわかんなくなるほど間はあかないので、
なんとか少しずつだが進めることができる。
「遅い」と「進まない」はチガウのが実感できて、ちょっとうれしい。
今日はコーディングしない日なので、気づいた直し方については、つぶやくだけ。明日やる。
今日は、サンチャにいくのである
@c_nyan せんせいの写真が追加された!(どこに?)
こないだのドック、1週間ながびいた夏風邪の最中にうけたんだよなぁ。なおったかなと思ってたけど、そのあとぶり返した。
白血球がどうの。
よく風邪はひくので、やだなと思うけど、
なんじゃかんじゃで治るってところがすばらしい。
休ませておけば治るような機械を、自分の体以外には持っていない。
サンチャってどこだ?
溝口から田園都市線か。
夏風邪ながびいたときに、ずっとマスクしてて(寝る時も)、そのときに耳のところかぶれたのが治らない。
メガネのツルがあたるので、かぶれてる場所にストレスかかりっぱなし。
メガネのツルをアルコール消毒してみた。
もういっこの問題もわかった(Str "L3" はどこへ行った問題)
https://github.com/unnohideyuki/Tiger-in-Haskell/blob/c7c03b76c16d8dfda8d56645687e3413d055518c/chap7/src/Semant.hs#L214
frgs じゃなくて frgs' を返すべきだった(それをしてないので、SeqExp 評価ないでつくられた String Fragment が捨てられてる)
temp やら frgs やら level やらの状態を引数わたししているから、こんな風にバグる。
なんらかの Monad m => m ExpTy にして、「配管」を隠し、引き回しは bind に任せるべきだ。
Tiger Compiler はこのままいこう。
つぎにコンパイラつくるときには、状態をもつ木変換にはモナドつかう。
# うんの [tempもだ]
Tiger in Haskell のコンパイルに -Wall つけたら、おびただしい数の警告が。
はじめから -Wall つけておくべきだったか。
新しく書くコードでは警告でないように。すでに書いたコードからも、すこしずつ警告の数は減らしていこう。
8章は、もうひととおり読んだので、 canon.sml を Canon.hs へ翻訳写経する。
これから書くコードは -Wall でも警告でないように。
https://github.com/unnohideyuki/Tiger-in-Haskell/tree/master/chap7
きのう、おととい気づいた修正をやって、さらに、文字列比較を実装。
$ cat ../testcases/test6.tig
/* define valid mutually recursive procedures */
let
function do_nothing1(a: int, b: string)=
do_nothing2(a+1)
function do_nothing2(d: int) =
do_nothing1(d, "str")
in
do_nothing1(0, "str2")
end
↑の処理結果は、こうなった↓(すこし手で整形してる)
$ ./driver.exe < ../testcases/test6.tig
(UNIT,[Proc {body = EXP (ESEQ (EXP (CONST 0)) (CALL (NAME "L0_do_nothing1") [TEMP 0,CONST 0,NAME "L3"])),
frame = Frame {name = "main", formals = [InFrame (-3)], locals = [], fp = 0}},
Str "L3" "str2",
Proc {body = EXP (CALL (NAME "L0_do_nothing1") [TEMP 5,TEMP 4,NAME "L2"]),
frame = Frame {name = "L1_do_nothing2", formals = [InFrame (-3),InReg 4], locals = [], fp = 5}},
Str "L2" "str",
Proc {body = EXP (CALL (NAME "L1_do_nothing2") [TEMP 3,BINOP PLUS (TEMP 2) (CONST 1)]),
frame = Frame {name = "L0_do_nothing1", formals = [InFrame (-3),InReg 2,InReg 1], locals = [], fp = 3}}])
以下の問題はいずれも直ってる:
また、
$ cat ../additonalcases/teststrcmp.tig
"ab" > "cd"
↑これは、↓こうなるようにしてみた。
$ ./driver.exe < ../additonalcases/teststrcmp.tig
(INT,[Proc {body = EXP (ESEQ (SEQ (CJUMP GT (CALL (NAME "_strcmp") [NAME "L0",NAME "L1"]) (CONST 0) "L2" "L2") (LABEL "L2")) (CONST 0)),
frame = Frame {name = "main", formals = [InFrame (-3)], locals = [], fp = 0}},
Str "L1" "cd",
Str "L0" "ab"])
results.log はボチボチ確認していくこととして、8章にすすもう。
https://github.com/unnohideyuki/Tiger-in-Haskell/blob/master/chap8/src/Canon.hs
canon.sml から Canon.hs への写経完。
8章からは、ghc に -Wall つけて確認するようにしていて、今回書いた部分は警告でないようにしてある。
すでに書いたコードではでまくるので、今後減らしていく。
ところで、Tiger book では、transExp やら transDec の書き方は、tenv や venv を共通にとる関数群を上手にまとめて書いてあって、上手いなぁと思ってまねしていたんだけど、あれは「ML 的」だな。
Haskell で書くなら、tenv, venv 以外にも temp やら frags やらの状態を明に扱わなくちゃならなくて煩雑になっていくし、あそこはやはり、状態モナドの出番だ。
と、Typing Haskell in Haskell を読みながら思った。
師走の翁センセによる不本意な壁ドンへの対処法(虎王)
http://togetter.com/li/699389
すばらしい。絵が描けるっていいな。
おまわりさん、みんな半日でコンパイラ書ける発言はココです。
http://www.kmonos.net/wlog/135.html#_2115140728
Tigerbook 買ってから、かれこれ7年経っている私に謝っ(ry
"Tofu" が、noto フォントの由来にあるような意味で英語化してるんだとして、
京コンピュータの誇る Tofu は、大丈夫だったのだろうか?
http://www.amazon.com/gp/product/193398869X/
なんじゃこりゃ。>表紙
夏風邪をこじらせて、寝るときもずっとマスクしていたときにかぶれてしまった耳の後ろを守るために、メガネをやめて、コンタクトレンズにしている。
メガネなしの自分の顔を見るのが久しぶりすぎて、なんだか新鮮。
Frame と DalvikFrame の関係を整理しようと思ってたけど、
また今度にしよう。
Typing Haskell in Haskell もがんばって読み進めて、11.2 まで来た。
うれしい。
少しずつしか時間とれなくても、少しずつなら進む。
(当たり前っぽい話ではある)
「毎日コードを書く」のは無理でも。
自分の場合は、月水金土の夜と決めた。
コードを書かずに、妻と二人で深夜番組を眺めるだけの夜もあったほうが良いだろうと。
これは、会社の SNS 上で話していて気づいた。
というわけで、そろそろ腕立て伏せして寝る。
体を鍛えるのは、起きて頭を使える時間を増やすためなのです。
略すと、「腕立て伏せするのは、Haskell 書けるようになるため」となる。
# うんの [パターンマッチのコンパイル前後で等価になっているかどうかは、Quickcheck を用いたテストができるような気がし..]
# うんの [> Quickcheck を用いたテスト こんな感じかな。こりゃいいや。 http://uhideyuki...]
# うんの [感想: QuickCheck すげぇ。]