2005/07/29

ある人が『好きな言葉は四文字熟語』というとき、その人が本当に四文字熟語が好きだとすると、四文字熟語は四文字熟語ではないから、実は四文字熟語が好きではない。一方、四文字熟語が好きではないとすると、四文字熟語は四文字熟語でないから、やっぱり四文字熟語が好き(ハイチュウ率)。この『四文字熟語のパラドクス』は、命題中の「四文字熟語」を「四字熟語」に言い換えると解決する。しねえよ。基礎論すっかり忘れちゃったなあ。蒸しあついなあ。ウナギ食べたい。

2005/07/28

いまさら気が付いたしょうもないこと。Scheme と Haskell では fold の動作が違うんですね……
どちらもこんな風に書くわけだけど(Haskellの場合は foldl)、

fold proc 種 (x_1 x_2 ... x_n)

これが Scheme では

proc (x_n ... (proc x_1 種)...)

と評価されるのに対し、Haskell では

proc (...(proc 種 x_1) ... x_n)

とみなされる。

「種とリストの要素のどちらを先に proc に渡すか」が正反対なので、除算みたいな可逆でない演算の場合に思い悩む。

gosh-rl> (fold / 128 '(8 4 2))
0.03125

Hugs.Base> foldl (/) 128 [8,4,2]
2.0

この例では Haskell のほうが感覚にマッチするなあ。Scheme で Haskell と同じことがしたい場合には無名関数を使うしかないのかしらん。

gosh-rl> (fold (lambda (x y) (/ y x)) 128 '(8 4 2))
2


なんでこんなことが気になったかというと、情報処理学会誌6月号の Haskell の数当てゲームの記事に、0~9 の自然数からなるリストを各数字が各桁に対応する1つの自然数に移す関数 pack: (a b c ..) → abc.. が foldl で実装されていたから。こんなやつ。

Hugs.Base> foldl (\ x y -> 10 * x + y) 0 [1,2,3]
123

上記のような理由で、これをそのまま Scheme に置き換えても期待した結果は得られない。

gosh-rl> (fold (lambda (x y) (+ (* 10 x) y)) 0 '(1 2 3))
60

lambda 内の x と y を逆にすればいいだけなんだけどさ。

2005/07/26

会社のDebianサーバがいかれて復旧で一日が終わってしまった。せっかく台風なのに。それにつけても本業がちっとも進まないのはなぜだろう?

2005/07/25

台風がくるというので定時に帰宅してみた。そしたら、きた。それにしても汚い屋根だ。
まったく関係ないけど、先々週に東北地方を車で廻ったときに撮ったストーンサークルの写真をいつの間にか自分でFlickr!に上げていたみたい。

2005/07/19

依然として調子が悪いな。目をつぶると意識は鮮明なんだけど、目を開けていると倒れそう。というわけで、早いけど帰宅して寝る。

2005/07/18

三河島駅前に「若松」という居酒屋がある。毎日のように店の前を通るたび、やきとりと鰻の香にため息をついてきた。なんとなく入る機会もなく、この地に移り住んで5年目、今日初めて店に入ってみた。
店内は休日の18:00すぎだというのにすでに満員状態。かろうじて空いた6人がけの座敷に相席で、念願のやきとりやら鰻やらを注文した。5年間毎日予想してきたとおり、焼がうまい。とりたてて高価な素材をつかっているわけではないのに、焼の上手さで何を頼んでも期待をうらぎらない。しかも安い。
こういう居酒屋が目の前にあるのは素晴らしいことだけど、いかんせん奥様としか利用する機会が持てないのが残念なところ。このあいだも、ちかぢか結婚する友人が東東京に越したいと言ったところ、相手に強行に反対されたらしい。東東京は恐いんだって。むべなるかな。きょうび東京の西のほうが文化的だと思われてるからな。しかし、自分の偏見では、東京は東のほうにこそ文化がかたまっていると思うんだけどなあ。
くそ暑いので献血センターですずやかに読書でもしようと思ったら、血小板を200ml抜いたところで貧血を起こしてしまった。看護婦さんが3人で処置してくれたのですぐに回復したけど、手は痺れるし、意識はふらつくし、早めに気持ちが悪いと申告してよかった。看護婦さんの話しを統合すると、どうやら暑さで脱水ぎみになったらしい。あと、個人的には、最近あんまり肉々しいものを食べてないことも理由のひとつだと思う。そこで、とりあえず帰りがけに吉野屋で牛焼肉丼。

2005/07/15

スターウォーズ エピソード3を見にいったら、コルサント→モンテカルロみたいな連想が働いてしまって、長方形が重なるかどうかを面積の差で解決する問題(参照)ってモンテカルロで解けるじゃん。

(use gauche.uvector)
(use srfi-27)
(use math.mt-random)

;; make random vector
(define (make-random-vector! n)
(mt-random-fill-f64vector! (make-random-source) (make-f64vector n)))

(define (ith-random randoms i)
(f64vector-ref randoms i))

(define (ith-random-pair randoms i)
(list (ith-random randoms (* 2 i))
(ith-random randoms (+ (* 2 i) 1))))

;; rect as ((x0 x1) (y0 y1))
(define (point-inner-closed? point closed)
(and (< (car closed) point) (< point (cadr closed))))

(define (pair-inner-rects? pair rects) ; not cps !
(let ((rect (car rects)))
(if (null? (cdr rects))
(and (point-inner-closed? (car pair) (car rect))
(point-inner-closed? (cadr pair) (cadr rect)))
(or (pair-inner-rects? pair (list rect))
(pair-inner-rects? pair (cdr rects))))))

;; monte-carlo
;; area as '(rect1 rect2 ...)
(define (monte-carlo area n)
(let ((randoms (make-random-vector! (* 2 (+ n 1)))))
(let f ((i 0))
(if (> i n)
0
(if (pair-inner-rects? (ith-random-pair randoms i) area)
(+ (f (+ i 1)) 1)
(f (+ i 1)))))))

;; main
(define times 10000)
(define rect1 (list (list 0.0 0.2) (list 0.0 0.2)))
(define rect2 (list (list 0.1 0.3) (list 0.1 0.3)))

(define s1 (monte-carlo (list rect1) times))
(define s2 (monte-carlo (list rect2) times))
(define s1-and-s2 (monte-carlo (list rect1 rect2) times))

(display (< s1-and-s2 (+ s1 s2)))

=> #t

これなら長方形を実数で指定できる! ハエを殺すのに焼夷弾を持ち出すみたいな話だってのはわかってますって。

2005/07/07

Haskell と継続について。いただいたコメントによるとモナドで継続を実現できるんですね。Haskellのコードで理解するのはつらいので、ここを読み返してみた。

f: x→y により実行される計算の継続は、f': x→((y→k)→k) となるような f': x→M(y) と見なせる。ここで M はモナド則を満たす。という理解でいいのかな。

にしても、これがHaskellのプログラミングで意味があるのかどうかは、あいかわらずよくわからない。実際に Haskell でプログラミングしているわけじゃないので、わからなくて当然といえばそれまでなんだけど、応用を生み出す妄想力の欠如を我ながら痛感するところ。ところで、あちこちで「Haskell では遅延評価があるから無理に継続引き渡しにしなくてもいい」って言及されているのは、まるで継続と遅延評価とが同じ概念の2つの表現みたいに読めてしまうから、いけないと思う。実際には、評価の順番が問題視されなければ継続引き渡しで処理が最適化されるわけじゃないってだけのことだと思うんだけど、僕のほうが勘違い?

2005/07/06

だらだらとWebを見ながら、howm形式でばしばしメモるためのBookmarklet。Firefox1.0.4でのみ動作を確認。改行が便宜的なものであるのはいわずもがな。

javascript:
var pageTitle=document.title;
var pageURL=document.URL;
var userSelection=document.getSelection();
function nomdic(cc){if(cc<10){cc='0'+cc};return cc};
var nowDate=new Date();
var yyyy=nowDate.getFullYear();
var mm=(nowDate.getMonth()+1);
var dd=nowDate.getDate();
var hh=nowDate.getHours();
var min=nowDate.getMinutes();
var ss=nowDate.getSeconds();
var howmName=yyyy+'-'+nomdic(mm)+'-'+nomdic(dd)+'-'+nomdic(hh)+nomdic(min)+nomdic(ss)+'.howm';
var howmDate=yyyy+'-'+nomdic(mm)+'-'+nomdic(dd);
var openWin=window.open('',howmName,'innerWidth=600,innerHeight=400,scrollbars,menubar');
openWin.document.writeln
(howmName + '<br/>= ' + 'URLメモ ' + pageTitle + '<br/>' + '['+howmDate+']' + ' &lt;&lt;&lt; '
+ pageURL + '<br/><br/>' + userSelection); void(openWin.document.close());

本当は、$HOME/howm/以下へ自動的に吐き出したいんだけど、javascriptだけでは無理で、XPCOMを使うしかないっぽい。それにしてもこういうのを書くと生気を吸われるきもち。