view-source on iPhone

そーいや Mobile Safari って HTML ソース見らんないよなーと思ったけど bookmarklet 使えばいいのかと気付いて

javascript:document.body.textContent=document.documentElement.outerHTML

とかやってみたけどコレだと既存 css の影響とか受けまくるので

javascript:document.documentElement.textContent=document.documentElement.outerHTML

にしたら解決したけど, どちらにせよ見辛いという問題が残って, 結局こんな感じになった.

javascript:(function(d,de,c){c=d.createElement('div');c.textContent=de.outerHTML;de.innerHTML='<body><pre>'+c.innerHTML+'</pre></body>';})(document,document.documentElement)

まあコレも HTTP Response としての HTML ソースではないので, 結論として Debug Console はソース表示をサポートすべき.

foldr on Gauche/GHC

なんか Gauche と GHC で foldr の挙動が違うのでメモ.

Gauche (fold)
$ gosh -V
Gauche scheme interpreter, version 0.8.12 [utf-8,pthreads]
$ gosh -u srfi-1 -E 'display (fold - 0 (iota 10 1))' -E exit
5
GHC (foldr)
$ ghc -V
The Glorious Glasgow Haskell Compilation System, version 6.8.2
$ ghc -e 'foldr (-) 0 [1..10]'
-5
GHC (foldl)
$ ghc -e 'foldl (-) 0 [1..10]'
-55

Gauche の fold は foldr っぽいけど, Gauche のは

(- 10 (- 9 (- 8 (- 7 (- 6 (- 5 (- 4 (- 3 (- 2 (- 1 0))))))))))

で, GHC のは

(- 1 (- 2 (- 3 (- 4 (- 5 (- 6 (- 7 (- 8 (- 9 (- 10 0))))))))))

となっている.

何がどう困るのか困らないのか分からないけど.

Twitter Active User Icons (ja)

Twitter Streaming API を使って, 流れゆくアイコンを眺める Web アプリを作ってみた.

Twitter Active User Icons (ja)
http://phoneme.homelinux.org/twitter_icons/

発言を全部拾うと量が多いので /[ぁ-んァ-ン]/ で日本語っぽい発言だけ引っかけた. どうでもいいけど [ぁ-んァ-ン] って何かエロい.

Streaming API 自体が結構取りこぼすので, 発言しながら眺めていてもなかなか自分のアイコンが表示されない. ちぇー.

Locate It

最近, 拙作 Yaiku で, 経緯度による location nanoformat の投稿機能をサポートした.

Locate It: On Yaiku しかし, Yaiku 上では L: タグが地図へリンクされるのだが,

Locate It: On Jaiku jaiku.com のタイムラインから見ると発言全体がスレッドへの permalink となっているし,

Locate It: On Jaiku Permalink スレッド上では単なる文字列扱いとなっていて面白くない.

Locate It: On Jaiku Permalink というわけで, L: タグを Google Maps にリンクする user script を書いた.

前述の通り, Jaiku のタイムライン上では発言全体が permalink へのアンカーになっており 「発言に含まれた URL がリンクされない・クリックできない」 という問題があるため, 以前 これを解消するための user script を書いたことがある.

同様に, L: タグをリンクするためには一度リンクを外す必要があるため, 上記 user script とは競合する. 利用する際には "Jaiku pretty-good link embosser" を無効にされたい.

Locate It: identi.ca 今回の user script には

  • リンクになっている発言からリンクを外して, 文中に含まれる URL を新たにリンクして, スレッドへの permalink を挿入する
  • ページ中に含まれる L: タグを Google Maps にリンクする

という二つの機能があるが, Jaiku specific なのは前者だけで, 後者はサイトを選ばないはずだ.

なので, デフォルトでは jaiku.com 上でしか機能しないが, 適当に修正すると任意のサイト上で機能させることもできる.

動作は Safari 4.0.2 + GreaseKit 1.5, Firefox 3.5.2 + Greasemonkey 0.8, Opera 9.63 で確認した. Autopagerize 対応. ダウンロード・インストールは以下から.

enjoy.

scheme で coroutine に挑戦する

さて,前回よりは継続できるようになったところで (ほんとか!?) 早速 coroutine を試してみたい.

Web 上で比較的目に付きやすい coroutine の例として "call/cc 入門 (Coroutine with call/cc) — MAYAH.JP" があるのだが,幾つか気になる点がある.

  1. coroutine 内で call/cc を呼んでいて気持ち悪い
  2. 実行コンテキストが大域変数に bind されているので複数の文脈で coroutine を実行できない

1 について. 要は coroutine は coroutine としての処理に専念させたいという話. 例えば,引数として受けとった関数 yield を呼び出すと継続を保持しつつ caller に値を返せることにすればこんな風にシンプルになりそう (てか他の言語でもよく見るパターン).

(define (counter yield)
  (let loop ((count 1))
    (yield count)
    (loop (+ 1 count))))

で,これを実行コンテキスト毎に lambda で包んであげれば 2 の問題を解決できるはず. こんな感じ.

(define (make-coroutine f)
  (lambda ()
    ...
    (f ...)
    ...))

(define n (make-coroutine counter))
(define m (make-coroutine counter))
(n) ; => 1
(m) ; => 1
(n) ; => 2
(n) ; => 3
(m) ; => 2

上記のような挙動を実現するには,適切に "..." を埋めてあげる必要がある.さてどうしよう.

とりあえず,caller には大域脱出用の call/cc を使って値を返すことにする. f が引数として与えられた yield を呼び出し,yield が継続を呼び出すことで値が返る.

(define (make-coroutine f)
  (lambda ()
    (call/cc (lambda (return)
               (f (lambda (value)
                    "used as yield"
                    (return value)))))))

このままだと延々と 1 が返ってくるだけなので,return するまえに新たに継続を作って保持しておく. call/cc 時には (return value) されるけど,保存される継続は (yield count) 直後を指しているというのがミソだと思う.

(define (make-coroutine f)
  (let ((continue #f))
    (lambda ()
      (call/cc (lambda (return)
                 (f (lambda (value)
                      "used as yield"
                      (call/cc (lambda (c)
                                 (set! continue c)
                                 (return value))))))))))

で,まだ保存された継続を使っていないのでw 使うようにする. 初回は直接 f を呼んで,次回以降は継続を呼び出す.

(define (make-coroutine f)
  (let ((continue #f))
    (lambda ()
      (call/cc (lambda (return)
                 (if continue
                     (continue)
                     (f (lambda (value)
                          "used as yield"
                          (call/cc (lambda (c)
                                     (set! continue c)
                                     (return value)))))))))))

一応,これで当初の理想通りの挙動を見せる coroutine が実現できた. 果たしてコレでベストなのか全く分からない,というか大抵のジェネレータ的なものは無理に call/cc 使わなくても書けると思うし,需要が低いのは分かる気がした.

トップに戻る