<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-9197115</id><updated>2012-02-12T11:43:35.495+09:00</updated><category term='Panasonic Let&apos;s Note CF-R4J Debian GNU/Linux インストールまとめ'/><category term='PHS Willcom Debian'/><title type='text'>k16's note</title><subtitle type='html'>Shikano Keiichirou (k16) → 
&lt;a href="http://twitter.com/golden_lucky"&gt;twitter&lt;/a&gt; &amp;amp; &lt;a href="http://golden-lucky.tumblr.com/"&gt;tumblr&lt;/a&gt;</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default?start-index=101&amp;max-results=100'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>597</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-9197115.post-9105309501030361352</id><published>2012-01-13T12:42:00.000+09:00</published><updated>2012-01-13T12:48:29.140+09:00</updated><title type='text'>n進数で文字列探索</title><content type='html'>&lt;p&gt;4桁の整数のなかで「42」という並びを含むものを探すことを考えます（10進で考えます）。こんな二階建ての再帰でいけそうです。&lt;/p&gt;&lt;blockquote style="background-color:#eeeecc; padding:5px;"&gt;『「末尾が42の数を全部集める」』→&lt;br&gt;『「末尾が420の数を全部集める」→「末尾が421の数を全部集める」→…→「末尾が429の数を全部集める」』→&lt;br&gt;『「末尾が4200の数を全部集める」→…』&lt;br&gt;&lt;/blockquote&gt;&lt;p&gt;『…』の再帰は、こんな感じ。&lt;/p&gt;&lt;pre&gt;(define (migi base hidari)&lt;br /&gt;  (iota (expt 10 base) hidari))&lt;/pre&gt;&lt;p&gt;「42」が出現してる場所より右側をなめるので、&lt;code&gt;migi&lt;/code&gt; という名前にしました。引数の &lt;code&gt;hidari&lt;/code&gt; には「42なんとか」（なんとかは空か数字の列）が順番に入る、という気持ちです。&lt;code&gt;base&lt;/code&gt; が 0 なら「42」、&lt;code&gt;base&lt;/code&gt; が 1 なら「420から429」、&lt;code&gt;base&lt;/code&gt; が 2なら「4200から4299」、…という具合。「42なんとか」を始点に、10 の &lt;code&gt;base&lt;/code&gt; 乗個とってくればよいので、&lt;code&gt;iota&lt;/code&gt; を使っています。&lt;/p&gt;&lt;p&gt;「…」の再帰については、&lt;code&gt;migi&lt;/code&gt; を受けて &lt;code&gt;hidari&lt;/code&gt; の全パターンを集めるので、こんな &lt;code&gt;unfold&lt;/code&gt; で書けます。&lt;/p&gt;&lt;pre&gt;(define (hidari-all upper order)&lt;br /&gt;  (lambda (migi)&lt;br /&gt;    (unfold (pa$ &lt; upper) values&lt;br /&gt;            (pa$ + (expt 10 order))&lt;br /&gt;            migi)))&lt;/pre&gt;&lt;p&gt;ようするに、 &lt;code&gt;migi&lt;/code&gt; が「42」の場合には「&lt;i&gt;xx&lt;/i&gt;42」の &lt;i&gt;xx&lt;/i&gt; にあらゆる数字の組み合わせをぶちこんだリストです。&lt;code&gt;migi&lt;/code&gt; が「420から429」なら「0420, ..., 9420, 0421, ..., 9421, ..., 0429, ..., 9429」で、&lt;code&gt;migi&lt;/code&gt; が「4200から4299」ならそのものです。 &lt;code&gt;migi&lt;/code&gt; の要素が2桁である「42」のときは10の2乗（ = 100）を次々に加えていったもの全部、3桁である「420から429」のときは10の3乗（ = 1000）をそれぞれに次々加えていったもの全部、…という具合です。これらを &lt;code&gt;unfold&lt;/code&gt; で作り出しています。&lt;/p&gt;&lt;p&gt;以上の2つの再帰を組み合わせれば完成です。（&lt;code&gt;hidari-all&lt;/code&gt; の &lt;code&gt;order&lt;/code&gt; を決めるときにちょっと苦心しました。）&lt;/p&gt;&lt;pre&gt;(define (intseek order num)&lt;br /&gt;  (let1 upper (+ 1 (expt 10 order)) ;&lt;font color="green"&gt; 9999 + 1&lt;/font&gt;&lt;br /&gt;    (let R ((b 0) (hidari num))&lt;br /&gt;      (if (&gt; b (- order (ord num)))&lt;br /&gt;          '()&lt;br /&gt;          (append&lt;br /&gt;            (append-map (hidari-all upper (+ b (ord num))) (migi b hidari))&lt;br /&gt;            (R (+ b 1) (* hidari 10)))))))&lt;br /&gt;&lt;br /&gt;&lt;font color="green"&gt;; 最近のGaucheなら(log x 10)で済むのだけど。&lt;/font&gt;&lt;br /&gt;(define (ord x)&lt;br /&gt;  (x-&gt;integer (/ (log x) (log 10))))&lt;/pre&gt;結果はこうなります（途中は省略）。&lt;pre&gt;&lt;font color="blue"&gt;gosh&gt;&lt;/font&gt;&lt;b&gt; (intseek 4 42)&lt;/b&gt;&lt;br /&gt;(42 142 242 342 442 542 642 742 842 942 1042 1142 ... 4295 4296 4297 4298 4299)&lt;/pre&gt;&lt;p&gt;この遊び、なにも10進に限る必要はありません。2進表記で10桁の整数から「11」の並びを含むものを探すとか、16進表記で4桁の整数から「aa」の並びを含むものを探すとか、簡単に応用できます。&lt;/p&gt;&lt;pre&gt;(define (intseek order str radix max-digit)&lt;br /&gt;  (define (hidari-all upper order)&lt;br /&gt;    (lambda (migi)&lt;br /&gt;      (unfold (pa$ &lt; upper) values&lt;br /&gt;              (pa$ + (expt radix order))&lt;br /&gt;              migi)))&lt;br /&gt;  (define (migi b hidari)&lt;br /&gt;    (iota (expt radix b) hidari))&lt;br /&gt;  (let1 upper &lt;font color="green"&gt;; radix進でorder桁の最大数 + 1&lt;/font&gt;&lt;br /&gt;      (+ 1 (string-&gt;number (make-string order max-digit) radix))&lt;br /&gt;    (let R ((b 0) (hidari (string-&gt;number str radix)))&lt;br /&gt;      (if (&gt; b (- order (string-length str)))&lt;br /&gt;          '()&lt;br /&gt;          (append&lt;br /&gt;            (append-map (hidari-all upper (+ b (string-length str)))&lt;br /&gt;                        (migi b hidari))&lt;br /&gt;            (R (+ b 1) (* hidari radix)))))))&lt;/pre&gt;&lt;pre&gt;&lt;font color="blue"&gt;gosh&gt;&lt;/font&gt;&lt;b&gt; (map (cut format "~x" &lt;&gt;) (intseek 4 "aa" 16 #\F))&lt;/b&gt;&lt;br /&gt;("aa" "1aa" "2aa" "3aa" "4aa" "5aa" "6aa" "7aa" ... "aafd" "aafe" "aaff")&lt;/pre&gt;&lt;p&gt;さらに、26進の数字で特定の並びを含むものを探すこともできるはずです。ということは、26進の数字とアルファベット26文字を対応させてやれば、&lt;i&gt;n&lt;/i&gt;文字のアルファベット文字列から特定の文字の並びを含むものを見つける、といった問題にも応用できることになります。さすがに26進だと表記につかう26個の文字を扱うのつらいのでやる気になりませんが、次の問題くらいなら4進で済むので、この方法を使って解けそうです。&lt;/p&gt;&lt;blockquote&gt;&lt;a href="http://www.cgios.com/far1/recruit/prod/sp/wif"&gt;4種類のアルファベット "A,C,G,T" から成るn文字の文字列のうち、"AAG"という並びが含まれる文字列を全て列挙するプログラムを書きなさい。ただし、nは3以上の整数とし、文字列内に同じアルファベットが出現しても構わないものとし、出力順序は問わないものとします。... 適性検査に合格された方はその生産性を実現可能な方です。生産性に見合う初任給として年俸1000万円をご用意しております。&lt;/a&gt;&lt;br/&gt;（via: &lt;a href="http://nagoyascala.yoshihiro503.cloudbees.net/bbs/thread/114001"&gt;名古屋Scala掲示板 年俸1000万の会社の試験問題&lt;/a&gt;）&lt;/blockquote&gt;&lt;p&gt;アルファベットと4進数との変換だけ定義してやれば、1000万ゲット。&lt;/p&gt;&lt;pre&gt;&lt;br /&gt;(define mapping&lt;br /&gt;  '((#\A #\3) (#\C #\2) (#\G #\1) (#\T #\0)))&lt;br /&gt;&lt;br /&gt;(define (acgts n ls)&lt;br /&gt;  (map (lambda (int)&lt;br /&gt;         (ints-&gt;acgt (string-pad (number-&gt;string int 4) n #\0)))&lt;br /&gt;       ls))&lt;br /&gt;&lt;br /&gt;(define (acgt-&gt;ints str)&lt;br /&gt;  (string-map (lambda (c) (cadr (assoc c mapping))) str))&lt;br /&gt;&lt;br /&gt;(define (ints-&gt;acgt str)&lt;br /&gt;  (string-map (lambda (c) (cadr (assoc c (map reverse mapping)))) str))&lt;/pre&gt;&lt;pre&gt;&lt;font color="blue"&gt;gosh&gt;&lt;/font&gt;&lt;b&gt; (acgts 5 (intseek 5 (acgt-&gt;ints "AAG") 4 #\3))&lt;/b&gt;&lt;br /&gt;("TTAAG" "TGAAG" "TCAAG" "TAAAG" "GTAAG" "GGAAG" "GCAAG" "GAAAG" "CTAAG"&lt;br /&gt; "CGAAG" "CCAAG" "CAAAG" "ATAAG" "AGAAG" "ACAAG" "AAAAG" "TAAGT" "GAAGT"&lt;br /&gt; "CAAGT" "AAAGT" "TAAGG" "GAAGG" "CAAGG" "AAAGG" "TAAGC" "GAAGC" "CAAGC"&lt;br /&gt; "AAAGC" "TAAGA" "GAAGA" "CAAGA" "AAAGA" "AAGTT" "AAGTG" "AAGTC" "AAGTA"&lt;br /&gt; "AAGGT" "AAGGG" "AAGGC" "AAGGA" "AAGCT" "AAGCG" "AAGCC" "AAGCA" "AAGAT"&lt;br /&gt; "AAGAG" "AAGAC" "AAGAA")&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-9105309501030361352?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/9105309501030361352/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=9105309501030361352' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/9105309501030361352'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/9105309501030361352'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2012/01/n.html' title='n進数で文字列探索'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-5001104643303946316</id><published>2012-01-06T00:45:00.000+09:00</published><updated>2012-01-06T00:54:53.712+09:00</updated><title type='text'>一筆書きドラゴン曲線</title><content type='html'>&lt;p&gt;TeX でドラゴン曲線を描こうと思ったのですが、クヌース先生がとっくにやってしまっていて、あろうことか『TeXブック』にまで載せていました。出力結果は『TeXブック』に載っていないので、とりあえず&lt;a href="http://qiita.com/items/1551"&gt;写経&lt;/a&gt;して pdftex にかけてみたら、確かに&lt;a href="http://www.scribd.com/doc/77092245/Dragon-Curve"&gt;きれいな龍が現れました&lt;/a&gt;。&lt;/p&gt;&lt;p&gt;そのクヌース先生のコードですが、実際にドラゴン曲線を描くコードはたったの 2行です。&lt;/p&gt;&lt;pre&gt;&lt;br /&gt;\def\dragon{\ifnum\n&gt;0{\advance\n-1 \dragon\L\nogard}\fi}&lt;br /&gt;\def\nogard{\ifnum\n&gt;0{\advance\n-1 \dragon\R\nogard}\fi}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;どうやら相互再帰みたいですね。 Scheme で書くならこんな感じでしょうか。&lt;/p&gt;&lt;pre&gt;&lt;br /&gt;(define (dragon-curve dim)&lt;br /&gt;  (define (dragon i)&lt;br /&gt;    (if (&gt; i 0)&lt;br /&gt;        (append (dragon (- i 1)) &lt;br /&gt;                turn-left&lt;br /&gt;                (nogard (- i 1)))&lt;br /&gt;        '()))&lt;br /&gt;  (define (nogard i)&lt;br /&gt;    (if (&gt; i 0)&lt;br /&gt;        (append (dragon (- i 1))&lt;br /&gt;                turn-right&lt;br /&gt;                (nogard (- i 1)))&lt;br /&gt;        '()))&lt;br /&gt;  (dragon dim))&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;ドラゴン曲線は、「線分を真ん中で直角に折る」という操作を、折り曲げてできた 2つの線分に繰り返し適用して得られる自己相似なフラクタル図形です。ただし、折り曲げてできた 2つの線分を再び折り曲げる際には、それぞれ違う向きに操作を適用します。最初の線分の向きが「→→」だとしたら、「→←」という具合に、折り曲げてできた 2つの線分の双方に対して逆向きに繰り返し操作を適用するわけです。&lt;/p&gt;&lt;p&gt;で、クヌース先生はこれをうまく利用することで、&lt;code&gt;\dragon&lt;/code&gt; と &lt;code&gt;\nogard&lt;/code&gt; （dragon を逆から読んだ）を相互再帰させているわけですね。それぞれの真ん中にある &lt;code&gt;\L&lt;/code&gt; と &lt;code&gt;\R&lt;/code&gt; は曲げる方向で、結果として &lt;code&gt;\dragon&lt;/code&gt; は &lt;code&gt;\L&lt;/code&gt; と &lt;code&gt;\R&lt;/code&gt; からなる列に展開されます。この &lt;code&gt;\L&lt;/code&gt; と &lt;code&gt;\R&lt;/code&gt; にしたがって頭から進んでいけば、一筆書きの要領でドラゴン曲線が得られるという寸法です。&lt;/p&gt;&lt;p&gt;TeXもいいですが、一筆書きといったら&lt;a href="http://www.amazon.co.jp/dp/4764901811"&gt;『関数プログラミング』&lt;/a&gt;（R. バード,P.ワドラー著/武市 正人訳）の亀の子図形でしょう。むかし書いた &lt;a href="http://note.golden-lucky.net/2007/03/r.html"&gt;Scheme 版&lt;/a&gt;でドラゴン曲線をやってみます。切り貼りして説明書くの面倒くさくなったのでファイルまるごと掲載。&lt;/p&gt;&lt;pre&gt;&lt;font color="green"&gt;;;;; dragon.scm&lt;/font&gt;&lt;br /&gt;(use srfi-1)&lt;br /&gt;(use srfi-42)&lt;br /&gt;(use util.match)&lt;br /&gt;&lt;br /&gt;&lt;font color="green"&gt;;; state -&gt; state&lt;/font&gt;&lt;br /&gt;(define (move state)&lt;br /&gt;  (match state&lt;br /&gt;    (`((,x ,y) 0) (make-state (- x 1) y 0))    &lt;font color="green"&gt;;; N&lt;/font&gt;&lt;br /&gt;    (`((,x ,y) 1) (make-state x (- y 1) 1))    &lt;font color="green"&gt;;; W&lt;/font&gt;&lt;br /&gt;    (`((,x ,y) 2) (make-state (+ x 1) y 2))    &lt;font color="green"&gt;;; S&lt;/font&gt;&lt;br /&gt;    (`((,x ,y) 3) (make-state x (+ y 1) 3))    &lt;font color="green"&gt;;; E&lt;/font&gt;&lt;br /&gt;    ))&lt;br /&gt;&lt;br /&gt;(define-syntax let-state&lt;br /&gt;  (syntax-rules ()&lt;br /&gt;    ((_ e1 (e2 e3 e4) e5 ...)&lt;br /&gt;     (let ((e2 (caar e1))&lt;br /&gt;           (e3 (cadar e1))&lt;br /&gt;           (e4 (cadr e1)))&lt;br /&gt;       e5 ...))))&lt;br /&gt;&lt;br /&gt;&lt;font color="green"&gt;;; state -&gt; state&lt;/font&gt;&lt;br /&gt;(define (turn-left state)&lt;br /&gt;  (let-state state&lt;br /&gt;      (x y d)&lt;br /&gt;    (make-state x y (remainder (+ d 1) 4))))&lt;br /&gt;&lt;br /&gt;&lt;font color="green"&gt;;; state -&gt; state&lt;/font&gt;&lt;br /&gt;(define (turn-right state)&lt;br /&gt;  (let-state state&lt;br /&gt;      (x y d)&lt;br /&gt;    (make-state x y (remainder (+ d 3) 4))))&lt;br /&gt;&lt;br /&gt;&lt;font color="green"&gt;;; state&lt;/font&gt;&lt;br /&gt;(define (make-state x y d)&lt;br /&gt;  (list (list x y) d))&lt;br /&gt;&lt;br /&gt;&lt;font color="green"&gt;;; state -&gt; [state -&gt; state] -&gt; [state]&lt;/font&gt;&lt;br /&gt;(define (scanf init procs)&lt;br /&gt;  (if (null? procs)&lt;br /&gt;      '()&lt;br /&gt;      (let ((value ((car procs) init)))&lt;br /&gt;        (cons value&lt;br /&gt;              (scanf value (cdr procs))))))&lt;br /&gt;&lt;br /&gt;&lt;font color="green"&gt;;; draw as ASCII art&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="green"&gt;;; [state] -&gt; [[boole]]&lt;/font&gt;&lt;br /&gt;(define (to-bitmap ps)&lt;br /&gt;  (define (range xs)&lt;br /&gt;    (list-ec (: i (apply min xs) (+ (apply max xs) 1)) i))&lt;br /&gt;  (define (orlist ls)&lt;br /&gt;    (cond ((null? ls) #f)&lt;br /&gt;          ((car ls) #t)&lt;br /&gt;          (else&lt;br /&gt;           (orlist (cdr ls)))))&lt;br /&gt;  (define (in? x xs)&lt;br /&gt;    (orlist (map (cut equal? &amp;lt;&gt; x) xs)))&lt;br /&gt;  (let ((codes (map car ps)))&lt;br /&gt;    (list-ec (: x (range (map car codes)))&lt;br /&gt;             (list-ec (: y (range (map cadr codes)))&lt;br /&gt;                      (in? (list x y) codes)))))&lt;br /&gt;&lt;br /&gt;&lt;font color="green"&gt;;; [[boole]] -&gt; string&lt;/font&gt;&lt;br /&gt;(define (draw bitmap)&lt;br /&gt;  (string-join&lt;br /&gt;   (map (lambda (y)&lt;br /&gt;          (string-join (map (lambda (x) (if x &lt;font color="brown"&gt;"#" " "&lt;/font&gt;)) y)&lt;br /&gt;                       &lt;font color="brown"&gt;""&lt;/font&gt; 'strict-infix))&lt;br /&gt;        bitmap)&lt;br /&gt;   &lt;font color="brown"&gt;"\n"&lt;/font&gt; 'strict-infix))&lt;br /&gt;&lt;br /&gt;(define (dragon-curve dim)&lt;br /&gt;  (define (dragon i)&lt;br /&gt;    (if (&gt; i 0)&lt;br /&gt;        (append (nogard (- i 1))&lt;br /&gt;                (list move turn-left)&lt;br /&gt;                (dragon (- i 1)))&lt;br /&gt;        '()))&lt;br /&gt;  (define (nogard i)&lt;br /&gt;    (if (&gt; i 0)&lt;br /&gt;        (append (nogard (- i 1))&lt;br /&gt;                (list move turn-right)&lt;br /&gt;                (dragon (- i 1)))&lt;br /&gt;        '()))&lt;br /&gt;  (scanf (make-state 0 0 0) (dragon dim)))&lt;br /&gt;&lt;br /&gt;(define (main args)&lt;br /&gt;  (print&lt;br /&gt;   (draw&lt;br /&gt;    (to-bitmap&lt;br /&gt;     (dragon-curve (x-&gt;integer (cadr args))))))&lt;br /&gt;  0)&lt;/pre&gt;&lt;pre&gt;$ &lt;b&gt;gosh dragon.scm 8&lt;/b&gt;&lt;br /&gt;     ####    ####       &lt;br /&gt;    #####   #####       &lt;br /&gt;    ####### #######     &lt;br /&gt;      #####   #####     &lt;br /&gt; #################      &lt;br /&gt;#################       &lt;br /&gt;###### ### ########     &lt;br /&gt;  ####  ## ########     &lt;br /&gt; ###       #######      &lt;br /&gt;####       ######    ## &lt;br /&gt;####  #    ### ####   ##&lt;br /&gt;  #####     ## ####   ##&lt;br /&gt;  ####         #########&lt;br /&gt;               #########&lt;br /&gt;               ### ###  &lt;br /&gt;                ##  ##  &lt;/pre&gt;&lt;p&gt;なんかひっくり返ってますが、無事にドラゴン出ました。&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-5001104643303946316?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/5001104643303946316/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=5001104643303946316' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/5001104643303946316'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/5001104643303946316'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2012/01/blog-post.html' title='一筆書きドラゴン曲線'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-2735845336580622089</id><published>2011-12-31T00:04:00.000+09:00</published><updated>2011-12-31T00:04:09.201+09:00</updated><title type='text'>OLYMPUS SH-21 がきた</title><content type='html'>&lt;p&gt;年末感あふれる進行でへろへろになりながら会社の納会に遅れてったら、余興の景品で豪華賞品を獲得してしまいました。オリンパスのSH-21。なんか今年はずいぶんカメラづいてるなあ。レビューを書く約束をしたのでファーストインプレッションを。&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.flickr.com/photos/k16/6599923793/" title="景品 by Keiichirou Shikano, on Flickr"&gt;&lt;img src="http://farm8.staticflickr.com/7147/6599923793_82416d408a.jpg" width="500" height="332" alt="景品"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;帰宅してすぐに箱から出し、インテリジェントオートで何枚か撮ってみましたが、背面の液晶でプレビューすると、やたらに明るく写ってるけど何となくしゃきっとしない絵。設定いじれば変わるかなと思って、プログラムオートでいじってみるものの、さっぱり勝手がわからない。オールインワンカメラなんて、自分ではまず買わないタイプなので、かなり戸惑います。まあでもふだん使っているパナソニックのコンデジよりモノとしては楽しいので、翌日子どもと散歩に出かけるときに持って行こうと決めました。&lt;/p&gt;&lt;p&gt;翌朝、つまり今朝、散歩に出る前にフォーカスを合わせるコツをさぐりながら撮ったのがこれ。なんというひどいボケだw。こういう写真を見ると、ソフトウェアでは得られずハードの質で左右される部分がまだまだあるんだと自分に言い聞かせてD90用にレンズを買う口実になります。まあ、これくらい寄れるとそれだけで単純に楽しくなってしまうので、気楽に撮り流していくことにしましょう。&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.flickr.com/photos/k16/6599843227/" title="PC300002 by Keiichirou Shikano, on Flickr"&gt;&lt;img src="http://farm8.staticflickr.com/7154/6599843227_7a8f103165.jpg" width="500" height="375" alt="PC300002"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;このカメラ、背面液晶がタッチパネルになってて、タッチした場所でAFロックするようにできます。でも、それなりに明るい場所なら、従来のコンデジの要領でシャッターボタン半押しから構図を決めて撮るほうが楽でした。タッチパネルでAF操作するのに慣れてないわけではなくて、HTC Desireでは便利に使っているんですが、このカメラはタッチパネルの感度がいまいちよろしくない気がします。それにつけてもAFは楽ちんだ。&lt;/p&gt;&lt;p&gt;昨晩はしゃっきりしないと感じた肝心の絵ですが、晴天下ではずいぶん印象が変わりました。相変わらずインテリジェントオートはいまいちですが、プログラムオートにしてホワイトバランスのみオートにしてやると、完全にシャッター押すだけでソフトウェア支援をバリバリに受けたぱきっとした絵を快適に撮れるようになりました。&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.flickr.com/photos/k16/6599843839/" title="山手線 by Keiichirou Shikano, on Flickr"&gt;&lt;img src="http://farm8.staticflickr.com/7143/6599843839_742008659c.jpg" width="500" height="375" alt="山手線"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.flickr.com/photos/k16/6599846343/" title="PC300035 by Keiichirou Shikano, on Flickr"&gt;&lt;img src="http://farm8.staticflickr.com/7020/6599846343_4b620b2196.jpg" width="500" height="375" alt="PC300035"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.flickr.com/photos/k16/6599863517/" title="キリンキャンディー by Keiichirou Shikano, on Flickr"&gt;&lt;img src="http://farm8.staticflickr.com/7034/6599863517_8f0385dcc4.jpg" width="500" height="375" alt="キリンキャンディー"&gt;&lt;/a&gt;&lt;/p&gt;&lt;a href="http://www.flickr.com/photos/k16/6599847079/" title="PC300036 by Keiichirou Shikano, on Flickr"&gt;&lt;img src="http://farm8.staticflickr.com/7007/6599847079_0c9eacbdf2.jpg" width="500" height="375" alt="PC300036"&gt;&lt;/a&gt;&lt;p&gt;無駄に広角側があるのもスナップにはうれしい。&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.flickr.com/photos/k16/6599844423/" title="PC300021 by Keiichirou Shikano, on Flickr"&gt;&lt;img src="http://farm8.staticflickr.com/7169/6599844423_5dae2fb0fd.jpg" width="500" height="375" alt="PC300021"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.flickr.com/photos/k16/6599849985/" title="ライドオンストライダー by Keiichirou Shikano, on Flickr"&gt;&lt;img src="http://farm8.staticflickr.com/7158/6599849985_dd5af02aae.jpg" width="500" height="375" alt="ライドオンストライダー"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;でも、こういう写真はむずい。&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.flickr.com/photos/k16/6599848813/" title="PC300060 by Keiichirou Shikano, on Flickr"&gt;&lt;img src="http://farm8.staticflickr.com/7170/6599848813_16384b167c.jpg" width="500" height="375" alt="PC300060"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;暗いシーンでも何も考えずにシャッター押すだけ。&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.flickr.com/photos/k16/6599850789/" title="仲町商店街 by Keiichirou Shikano, on Flickr"&gt;&lt;img src="http://farm8.staticflickr.com/7004/6599850789_b794d20393.jpg" width="500" height="375" alt="仲町商店街"&gt;&lt;/a&gt;&lt;/p&gt;&lt;a href="http://www.flickr.com/photos/k16/6599852449/" title="日暮里 by Keiichirou Shikano, on Flickr"&gt;&lt;img src="http://farm8.staticflickr.com/7033/6599852449_b465492d98.jpg" width="375" height="500" alt="日暮里"&gt;&lt;/a&gt;&lt;p&gt;おもしろ機能として、パノラマが撮れちゃう。これはかなり興奮しました。このためだけに、これを登山に持っていこうと思った。高さが720ピクセルなのでPCで見るとそれほど迫力ないけど、背面液晶ではアニメーションでプレビューしてくれるので、かなり「おおっ」となります。&lt;/p&gt;&lt;a href="http://www.flickr.com/photos/k16/6599850133/" title="谷中コミュニティセンター by Keiichirou Shikano, on Flickr"&gt;&lt;img src="http://farm8.staticflickr.com/7152/6599850133_2131399ebc.jpg" width="500" height="77" alt="谷中コミュニティセンター"&gt;&lt;/a&gt;&lt;p&gt;あと連写が楽しいです。これも背面液晶ではアニメーションとしてプレビューでき、やはり異様に楽しい。flickrが中心の自分にとっては、しょせん静止画なのでハンドリングが楽なのもうれしいです。ハイビジョン動画とか、正直もてあます。あれってみんな、撮影したやつをどうやって保管してるんだろう。もちろんこのカメラも当たり前のようにハイビジョン動画撮れるのですが。&lt;/p&gt;&lt;p&gt;もうひとつ、3Dが取れる機能があって気になってるのですが、背面液晶は3D対応じゃないので、3Dモニターがないと楽しめないらしい。残念。&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-2735845336580622089?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/2735845336580622089/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=2735845336580622089' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/2735845336580622089'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/2735845336580622089'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2011/12/olympus-sh-21.html' title='OLYMPUS SH-21 がきた'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-2437499299085210544</id><published>2011-12-11T13:37:00.001+09:00</published><updated>2011-12-11T15:00:26.068+09:00</updated><title type='text'>2012年賀状</title><content type='html'>&lt;p&gt;年賀状書いた。&lt;/p&gt;&lt;pre&gt;%!&lt;br /&gt;&amp;lt;&amp;lt; &lt;font color="brown"&gt;/PageSize&lt;/font&gt; [285 420] &gt;&gt; setpagedevice&lt;br /&gt;&lt;br /&gt;&lt;font color="blue"&gt;/fun&lt;/font&gt; { &lt;font color="green"&gt;% y=x^2/81 for x&amp;lt;9, y=(x-18)^2/81 for x&gt;=9&lt;/font&gt;&lt;br /&gt;  dup 9 le {dup mul 81 div} {18 sub dup mul 81 div} &lt;font color="purple"&gt;ifelse&lt;/font&gt;&lt;br /&gt;} &lt;font color="purple"&gt;def&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="blue"&gt;/colwidth&lt;/font&gt; 62 &lt;font color="purple"&gt;def&lt;/font&gt; &lt;font color="green"&gt;% set column width&lt;/font&gt;&lt;br /&gt;&lt;font color="blue"&gt;/xoffset&lt;/font&gt; 15 &lt;font color="purple"&gt;def&lt;/font&gt;&lt;br /&gt;&lt;font color="blue"&gt;/linehfactor&lt;/font&gt; 1.3 &lt;font color="purple"&gt;def&lt;/font&gt;&lt;br /&gt;&lt;font color="blue"&gt;/fontsize&lt;/font&gt; 170 &lt;font color="purple"&gt;def&lt;/font&gt;&lt;br /&gt;&lt;font color="blue"&gt;/numfont&lt;/font&gt; {&lt;br /&gt;    &lt;font color="brown"&gt;/Sixties&lt;/font&gt; &lt;font color="green"&gt;% /Bookman-Demi or /Times-Bold are also good&lt;/font&gt;&lt;br /&gt;} &lt;font color="purple"&gt;def&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="blue"&gt;/setrandcolor&lt;/font&gt; { &lt;font color="green"&gt;% def&lt;/font&gt;&lt;br /&gt;  &lt;font color="brown"&gt;/m&lt;/font&gt; exch &lt;font color="purple"&gt;def&lt;/font&gt;&lt;br /&gt;  &lt;font color="brown"&gt;/r1&lt;/font&gt; {rand 10 mod 7 div 1 m fun sub mul m 9 eq {1 add} &lt;font color="purple"&gt;if&lt;/font&gt;} &lt;font color="purple"&gt;def&lt;/font&gt;&lt;br /&gt;  &lt;font color="brown"&gt;/r2&lt;/font&gt; {rand 10 mod 7 div 1 m fun sub mul 0 add} &lt;font color="purple"&gt;def&lt;/font&gt;&lt;br /&gt;  &lt;font color="brown"&gt;/r3&lt;/font&gt; {rand 10 mod 7 div 1 m fun sub mul 0 add} &lt;font color="purple"&gt;def&lt;/font&gt;&lt;br /&gt;  r1 r2 r3 setrgbcolor&lt;br /&gt;} &lt;font color="purple"&gt;def&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="blue"&gt;/centeringchar&lt;/font&gt; { &lt;font color="green"&gt;% def&lt;/font&gt;&lt;br /&gt;  dup stringwidth pop&lt;br /&gt;  colwidth exch sub 2 div 0 rmoveto&lt;br /&gt;} &lt;font color="purple"&gt;def&lt;/font&gt; &lt;font color="green"&gt;% remaining a character string on top of the opstack&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;xoffset 0 moveto&lt;br /&gt;&lt;br /&gt;0 1 3 { &lt;font color="green"&gt;% for&lt;/font&gt;&lt;br /&gt;  &lt;font color="brown"&gt;/i&lt;/font&gt; exch &lt;font color="purple"&gt;def&lt;/font&gt;&lt;br /&gt;  i colwidth mul 0 rmoveto&lt;br /&gt;  [3 1 2 3] i get &lt;font color="green"&gt;% map (+1) (2 0 1 2)&lt;/font&gt;&lt;br /&gt;  &lt;font color="brown"&gt;/base&lt;/font&gt; exch &lt;font color="purple"&gt;def&lt;/font&gt;&lt;br /&gt;  0 1 10 { &lt;font color="green"&gt;% for&lt;/font&gt;&lt;br /&gt;    &lt;font color="brown"&gt;/t&lt;/font&gt; exch &lt;font color="purple"&gt;def&lt;/font&gt;&lt;br /&gt;    &lt;font color="brown"&gt;/num&lt;/font&gt; t base add 10 mod &lt;font color="purple"&gt;def&lt;/font&gt;&lt;br /&gt;    &lt;font color="brown"&gt;/f&lt;/font&gt; {i 3 eq {12} {9} &lt;font color="purple"&gt;ifelse&lt;/font&gt;} &lt;font color="purple"&gt;def&lt;/font&gt;&lt;br /&gt;    &lt;font color="brown"&gt;/h&lt;/font&gt; {t 9 mul fun 2 mul f add} &lt;font color="purple"&gt;def&lt;/font&gt;&lt;br /&gt;    numfont findfont&lt;br /&gt;      [fontsize 1 0 linehfactor h mul 1 0]&lt;br /&gt;      makefont setfont&lt;br /&gt;    t setrandcolor&lt;br /&gt;    num 10 1 string cvrs&lt;br /&gt;    currentpoint&lt;br /&gt;      &lt;font color="brown"&gt;/y&lt;/font&gt; exch &lt;font color="purple"&gt;def&lt;/font&gt;&lt;br /&gt;      &lt;font color="brown"&gt;/x&lt;/font&gt; exch &lt;font color="purple"&gt;def&lt;/font&gt;&lt;br /&gt;    centeringchar&lt;br /&gt;    &lt;font color="purple"&gt;true&lt;/font&gt; charpath &lt;font color="purple"&gt;gsave&lt;/font&gt; fill &lt;font color="purple"&gt;grestore&lt;/font&gt;&lt;br /&gt;    0.5 setgray stroke&lt;br /&gt;    x h y add moveto&lt;br /&gt;  } &lt;font color="purple"&gt;for&lt;/font&gt;&lt;br /&gt;  xoffset 0 moveto&lt;br /&gt;} &lt;font color="purple"&gt;for&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="purple"&gt;showpage&lt;/font&gt;&lt;/pre&gt;&lt;p&gt;去年まではちゃんと印刷して写真をとっていたのだけど、今年は ps2pdf の出力を Scribd にアップするだけというていたらくです。&lt;/p&gt;&lt;a title="View 2012 on Scribd" href="http://www.scribd.com/doc/75345332/2012" style="margin: 12px auto 6px auto; font-family: Helvetica,Arial,Sans-serif; font-style: normal; font-variant: normal; font-weight: normal; font-size: 14px; line-height: normal; font-size-adjust: none; font-stretch: normal; -x-system-font: none; display: block; text-decoration: underline;"&gt;2012&lt;/a&gt;&lt;iframe class="scribd_iframe_embed" src="http://www.scribd.com/embeds/75345332/content?start_page=1&amp;view_mode=list&amp;access_key=key-1so6l79szdg09cq7qlmf" data-auto-height="false" data-aspect-ratio="0.678492239467849" scrolling="no" id="doc_23675" width="400" height="650" frameborder="0"&gt;&lt;/iframe&gt;&lt;p&gt;&lt;a href="http://note.golden-lucky.net/2009/12/setpagedevice-1-1-25-n-exch-def-0-12.html"&gt;2010年&lt;/a&gt;、&lt;a href="http://note.golden-lucky.net/2010/12/2011.html"&gt;2011年&lt;/a&gt;と、ぐるぐる回す系のデザインが続いたので、今年は縦スクロールにしてみました。回す系より地味だけど、縦のセンターを合わせなければいけないので、カラム幅と文字幅をもとに座標を調整したり、座標のリセットをしたり、見た目から想像されるよりも手間がかかります。&lt;/p&gt;&lt;p&gt;ナンバリング風の演出は、最初は円周の割合でフォントの高さの変化率を決めてみたのだけど、どうにも格好がつかず、適当な二次曲線（上記の &lt;code&gt;/fun&lt;/code&gt; ）を使ったらなんかいい具合になりました。あと「2012」だけが目に飛び込むような配色に苦労した。&lt;/p&gt;&lt;p&gt;今回の作例で使ったフォントは &lt;a href="http://www.1001freefonts.com/Sixties.php"&gt;Sixties&lt;/a&gt; というフリーフォントです。他の一般的なフォントを使う場合は、Bookman-Demi とか Times-Bold のようなひげのあるフォントがおすすめ。&lt;/p&gt;&lt;hr/&gt;&lt;p&gt;ここから Ghostscript で TrueType フォントを使うときのメモを書くけれど、自分ではよくわかってない話なので、個人マシンで遊ぶときとか意外には参考にしないでください。&lt;/p&gt;&lt;p&gt;Web から入手したフリーの TrueType フォントを PostScript 遊びで使いたいとき、インタプリタが Acrobat なら Windows や Mac にフォントをインストールすれば勝手に使ってくれるけれど、Ghostscript ではそうはいかない。基本的な手順は、&lt;ol&gt;&lt;li&gt;TrueType フォントの名前を調べる&lt;/li&gt;&lt;li&gt;GS から見える場所に置く&lt;/li&gt;&lt;li&gt;GS の Fontmap に登録（&lt;code&gt;/usr/share/ghostscript/8.71/Resource/Init/&lt;/code&gt; とかにあるやつ）&lt;/li&gt;&lt;/ol&gt;だけど、1つめの手順でつまずく。&lt;a href="http://linuxjf.sourceforge.jp/JFdocs/Font-HOWTO/x268.html"&gt;Font HOWTO&lt;/a&gt;とか読むと、こんな手が紹介されていた。&lt;pre&gt;&lt;font color="green"&gt;$&lt;/font&gt; ttf2pt1 -GA -l latin1 Sixties.ttf - 2&gt; /dev/null | grep FontName&lt;br /&gt;&lt;b&gt;FontName Sixties&lt;/b&gt;&lt;/pre&gt;フォントの置き場所もなかなか一筋縄ではいかなくて、Fontmap に絶対パスを書きさえすればどこに置いてもいいのかと思いきや、GS が見に行ってくれる場所（&lt;code&gt;/usr/share/ghostscript/fonts/&lt;/code&gt; とか）にないとだめっぽい。&lt;/p&gt;&lt;p&gt;Fontmap への登録も、システムワイドな Fontmap ファイルに直接書かないと有効にならないようで、今回は Sixties.ttf を &lt;code&gt; /usr/share/ghostscript/8.71/Resource/Init/Fontmap&lt;/code&gt; にこんなふうに登録した。&lt;pre&gt;%!&lt;br /&gt;% See Fontmap.GS for the syntax of real Fontmap files.&lt;br /&gt;%% Replace 1 (Fontmap.GS)&lt;br /&gt;(Fontmap.GS) .runlibfile&lt;br /&gt;&lt;br /&gt;&lt;b&gt;(Sixties) (Sixties.ttf) ;&lt;/b&gt;&lt;/pre&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-2437499299085210544?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/2437499299085210544/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=2437499299085210544' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/2437499299085210544'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/2437499299085210544'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2011/12/pagesize-setpagedevice-fun-9-dup-9-le.html' title='2012年賀状'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-2125343206906787212</id><published>2011-11-03T00:56:00.000+09:00</published><updated>2011-11-03T01:00:04.786+09:00</updated><title type='text'>TeX ユーザーの集い 2011 雑感</title><content type='html'>&lt;p&gt;10月22日に催された「 TeX ユーザーの集い 2011」に参加しました。「ユーザーの集い」というゆるい名前にもかかわらず、主要パッケージメンテナが一同に会する円卓会議で標準的な日本語 TeX 環境に向けた議論がなされたり、 LuaTeX 日本語化の開発状況の報告があったり、単なるエンドユーザーの集まりとは思えない雰囲気で楽しかったです。&lt;/p&gt;&lt;p&gt;そんな雰囲気の中、自分は一人のエンドユーザーとして、パッケージメンテナの方々や開発者を含む「 TeX ユーザー」たちがどこを目指してるのかを考えてました。ざっくり言うと、こんな 2つのベクトルがあるような気がします。&lt;/p&gt;&lt;ol&gt;&lt;li&gt;TeX は、数式や図を含む組版に使える便利なツールである&lt;/li&gt;&lt;li&gt;TeX は、ドキュメントのための形式のひとつである&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;当日の発表も、どちらかに大別できそう。たとえば、インプレスさんや達人出版会、奥村先生の招待講演のうち美文書の話、それにオーム社の事例は、主に 1 の立場でしょう。 KeTpic も 1 ですよね。一方、村上真雄さんの招待講演や解析概論プロジェクト、 OpenOffice は、 2 という見方だと思います。 LuaTeX の開発や TeXLive の報告は、ひとによってどんな立場の話としても聞ける類の内容で、その意味では、発表者ではない参加者の立場もまた上記 2 つのどちらかに当てはめることができそうです。&lt;/p&gt;&lt;p&gt;自分が今年の「 TeX ユーザーの集い 2011」であらためて感じたのが、2 の立場の重要性でした。ドキュメントのあり方というか、そういうレイヤで TeX 環境をとらえるべきなのではなかろうかと思い直しました。&lt;/p&gt;&lt;p&gt;TeX 環境には、きれいな組版ができるという出力側の優れた機能と、テキスト形式であるという入力側の利便性、それにプログラミング可能という特徴があります。それらをうまく使うことで、ドキュメント構造とスタイルという 2 つの抽象を分離できます。「うまく使う」というのがポイントです。うまく使わないと、まるで分離できない。でもうまく使えば、 XML/CSS のような固定的な分離だけでなく、ユーザにとって都合のよい分離を設計することさえできるはず。プログラミング可能というのはそういうことです。&lt;/p&gt;&lt;p&gt;（だから、なにも原稿が XML である必要はないのです。とはいえ、現実には補助線もなく適切な分離を毎回設計してそれを守り抜くのは誰にでもできることではありません。漏れのない抽象化は至難。だから、原稿そのものは XML 風だったり Wiki 風だったりするテンプレートを使って書くというのも次善策でしょう。閑話休題）&lt;/p&gt;&lt;p&gt;こういう話、実は予稿集の「ごあいさつ」にもきちんと書いてありました。実行委員の方々が2の立場を意識しているからこそ、村上さんの招待講演に結びついたのだろうし、実行委員の皆様には本当にどうもありがとうございました。勝手なことを言うと、さらに武藤さんによる「 InDesign 自動組版の可能性と限界」とかあってもよかったかも。テキスト原稿から InDesign への変換ツールを使った商業出版は、自分もほかに知ってるし、けっこう事例がありそうですが、 TeX との比較とかできるのは武藤さんくらいではないかと。そういう、構造/スタイルをはじめとする抽象分離を意識したドキュメント全般の事例をもっと聞いてみたかったです。 LaTeX から EPUB への展開とか、 TeX ユーザーにとって直接役立つヒントも多いはず。（昨今の電子書籍ブームみると、これらが来年のネタの提案としてふさわしいかはちょっと疑問ですが。）&lt;/p&gt;&lt;p&gt;gdgdな内容ですが、だから雑感だといったでしょ。あと、山本さんと八登さんの発表はおもしろかったです。そういえば、上記 1, 2 のような立場だけでなく、おもちゃとしての TeX という路線もありますよね。&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-2125343206906787212?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/2125343206906787212/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=2125343206906787212' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/2125343206906787212'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/2125343206906787212'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2011/11/tex-2011.html' title='TeX ユーザーの集い 2011 雑感'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-1828919424137432239</id><published>2011-10-24T21:08:00.000+09:00</published><updated>2011-10-24T21:08:43.798+09:00</updated><title type='text'>コダクロームの自家現像（ただし白黒）</title><content type='html'>&lt;p&gt;コダクローム（&lt;a href="http://www.google.com/search?hl=en&amp;q=kodachrome&amp;gs_sm=e&amp;gs_upl=1632l6066l0l6147l10l6l0l0l0l0l428l729l3-1.1l2l0&amp;um=1&amp;ie=UTF-8&amp;tbm=isch&amp;source=og&amp;sa=N&amp;tab=wi&amp;biw=999&amp;bih=859"&gt;Kodachrome&lt;/a&gt;）というリバーサルフィルムがあります。というか、&lt;a href="http://dc.watch.impress.co.jp/docs/news/20090623_295759.html"&gt;ありました&lt;/a&gt;。Kodak社ではコダクロームの製造を2009年6月22日に終了しています。だからいまはもう手に入らない。&lt;/p&gt;&lt;p&gt;製造中止そのものは、一部のファンには悲しいことだったのだろうけど、まあオールドメディアの終焉の一幕に過ぎません。コダクロームの本当の終了は、世界で最後の現像所が取り扱いを停止した2010年12月30日でした。これが「本当の終了」だったのは、コダクロームが自家現像のできないフィルムだからです。&lt;/p&gt;&lt;p&gt;現代のふつうのカラーフィルムは、フィルムそのものが発色の機能を備えています。だから、所定の薬品を使って一定の手順を踏めば、撮影した画像をカラーで取り出せます。そのへんの現像所はもちろん、おうちの台所でも現像ができるということです。ところがコダクロームは、フィルムそのものには発色の機能がなく、現像の過程で何段階か露光させることにより発色させるという特殊な方式でした（耳知識）。そのため、家庭はもちろん、そのへんの現像所でもコダクロームの現像はできません。だから2010年12月30日を最後に、それまで世界中で販売された未現像のコダクロームはただのゴミになってしまいました。ある種のDRMのようなものですね。人類はちっとも学習しない。&lt;/p&gt;&lt;p&gt;そんなゴミが、我が家からも一本発掘されました。とはいえ、古いカメラの中に入っていた撮影済みのフィルムを取り出したらコダクロームだった！という事情なので、個人的には安易にゴミ認定しかねます（どうせスナップではあるのですが）。必死になって調べてみたところ、どうやら英語圏では白黒ネガフィルムとしての自家現像にチャレンジしている人たちがいるようです。&lt;/p&gt;&lt;p&gt;というわけで、さっそく試してみます。&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.flickr.com/photos/k16/6272223859/" title="Kodachrome by Keiichirou Shikano, on Flickr"&gt;&lt;img src="http://farm7.static.flickr.com/6224/6272223859_8f74c931b6.jpg" width="500" height="332" alt="Kodachrome"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;プロセスは &lt;a href="http://michaelraso.blogspot.com/2011/01/kodachrome-in-2011-process-as-black-and.html"&gt;"Kodachrome in 2011 – Process as Black and White"&lt;/a&gt; というサイトのものを参考にしました。参考というより、まるまる利用。現像マニアというわけではないので、その程度が限界です。以下はあくまでも素人による結果報告なので、もし参考にされる場合は、撮影画像が抜けてしまう覚悟でお願いします。&lt;/p&gt;&lt;dl&gt;&lt;dt&gt;水洗い&lt;/dt&gt;&lt;dd&gt;水道水（30°C だった）で攪拌しながら 3分。排水はかなり黄色くなります。&lt;/dd&gt;&lt;dt&gt;T-Max現像液で現像&lt;/dt&gt;&lt;dd&gt;標準希釈（1:4）、20°C で計 6分30秒。最初の 3分間を連続攪拌、50秒停止→10秒攪拌を 3セット。排水に 30秒&lt;/dd&gt;&lt;dt&gt;コダフィックスソリューションで定着&lt;/dt&gt;&lt;dd&gt;標準希釈（1:7）、28°C で計 8分。最初の1分を連続攪拌、50秒停止→10秒攪拌を6セット、30秒停止→排水30秒&lt;/dd&gt;&lt;dt&gt;水洗い&lt;/dt&gt;&lt;dd&gt;20°C の水で2分程度の攪拌後、水道水（30°C だった）からの流水で 15分&lt;/dd&gt;&lt;dt&gt;こそぐ&lt;/dt&gt;&lt;dd&gt;ちょっと何を言ってるのか分からないかもしれないが、アクリルたわしで感光剤のない面（つるつるのほう）をこすり、黒ずみのようなものをこそいだ。フィルムワイパーかければ取れるのかなと思ったら、けっこうしっかり付いてるので、感光剤を傷つけないように注意しながら、けっこうしっかり黒ずみをおとしてやる。勇気がいる。&lt;/dd&gt;&lt;dt&gt;ナニワカラーキットNの漂白定着液で処理&lt;/dt&gt;&lt;dd&gt;上記サイトによるとC-41の漂白をしたほうがヌケがよくなる、ということなので、いちおうやっておく。標準希釈で 1分攪拌し、すぐ排水。&lt;/dd&gt;&lt;dt&gt;ドライウェル&lt;/dt&gt;&lt;dd&gt;上記サイトではフォトフローを使っているけど、そんなものヨドバシカメラに売ってない&lt;/dd&gt;&lt;dt&gt;乾燥&lt;/dt&gt;&lt;dd&gt;子供が留守のあいだに&lt;/dd&gt;&lt;/dl&gt;&lt;p&gt;結果です。EPSON GT-X800 でスキャンしただけの状態。ソフトウェアでは手を加えていません。長いことカメラに入りっぱなしなのを考慮して、もっと現像時の水温を下げるべきだったと後悔してますが、何が映ってるかは判明したのですっきりしました。&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.flickr.com/photos/k16/6272657188/" title="11 by Keiichirou Shikano, on Flickr"&gt;&lt;img src="http://farm7.static.flickr.com/6046/6272657188_2a0ef7a7a7.jpg" width="500" height="357" alt="11"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.flickr.com/photos/k16/6272658010/" title="8 by Keiichirou Shikano, on Flickr"&gt;&lt;img src="http://farm7.static.flickr.com/6151/6272658010_a502990a72.jpg" width="344" height="500" alt="8"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.flickr.com/photos/k16/6272131111/" title="4 by Keiichirou Shikano, on Flickr"&gt;&lt;img src="http://farm7.static.flickr.com/6229/6272131111_e933393676.jpg" width="352" height="500" alt="4"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;出来上がりについては、わたしの現像が未熟なのをおいておいても、残念な感じだと思いました（ところどころある白点は、こそぎ切れかなった黒ずみと思われ）。今回のような事情でもない限り、わざわざ余っているコダクロームを使ってモノクロ撮影をするようなものでもなさそう。&lt;/p&gt;&lt;p&gt;最後にいいわけっぽく、このコダクロームが眠っていたオリンパスのペンFというカメラと、同じカメラによるT-MAX100による自家現像作例も張り付けておきます。10年以上前の香港のようすです。&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.flickr.com/photos/k16/6272657444/" title="14 by Keiichirou Shikano, on Flickr"&gt;&lt;img src="http://farm7.static.flickr.com/6119/6272657444_2976f5145a.jpg" width="500" height="352" alt="14"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.flickr.com/photos/k16/6272657528/" title="15 by Keiichirou Shikano, on Flickr"&gt;&lt;img src="http://farm7.static.flickr.com/6108/6272657528_c21cbfeca1.jpg" width="372" height="500" alt="15"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.flickr.com/photos/k16/6272657602/" title="16 by Keiichirou Shikano, on Flickr"&gt;&lt;img src="http://farm7.static.flickr.com/6213/6272657602_f4e210367e.jpg" width="500" height="360" alt="16"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.flickr.com/photos/k16/6272751300/" title="Olympus Pen F with pancake by Keiichirou Shikano, on Flickr"&gt;&lt;img src="http://farm7.static.flickr.com/6046/6272751300_195fbfb8d6.jpg" width="500" height="332" alt="Olympus Pen F with pancake"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;なんてすてきなレンズ！&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-1828919424137432239?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/1828919424137432239/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=1828919424137432239' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/1828919424137432239'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/1828919424137432239'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2011/10/blog-post.html' title='コダクロームの自家現像（ただし白黒）'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm7.static.flickr.com/6224/6272223859_8f74c931b6_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-6853454174647022031</id><published>2011-10-12T22:36:00.000+09:00</published><updated>2011-10-12T22:57:52.352+09:00</updated><title type='text'>D90がきた</title><content type='html'>&lt;p&gt;デジカメを買いました。それも、3年まえに発売され、すでにカタログ落ちしている Nikon D90 をいまさら購入です。まったくそんなつもりはなかったのですが、まる7年にわたって使い倒した D70 がいよいよデータ保存時に深刻なエラーを引き起こすようになって、サービスセンターに持ち込むつもりで Nikon のサイトをのぞいたところ、アウトレットで D90 のボディが 59,800 円で売り出していたのに引っかかってしまったのでした。でもまあ、D70 を修理するにしても2万円は出費を覚悟しなければならないし、買い換えるにしても D7000 はなんかちがうし、D90 なら当分は腐らないし、ニコンダイレクトで3年保証だというし。。&lt;/p&gt;&lt;p&gt;なにはともあれ、さっそく試し撮りです。被写体はいつもの FM-2 WILDCAT。下が以前とった D70。レンズはどちらも東独ツァイスのフレクトゴン35mm。&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.flickr.com/photos/k16/6237630410/" title="FM-2 WILDCAT 1/144 Sweet by Keiichirou Shikano, on Flickr"&gt;&lt;img src="http://farm7.static.flickr.com/6093/6237630410_27bba62dc1.jpg" width="500" height="332" alt="FM-2 WILDCAT 1/144 Sweet"&gt;&lt;/a&gt;&lt;/p&gt;&lt;a href="http://www.flickr.com/photos/k16/2540244999/" title="DSC_0235 by Keiichirou Shikano, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2106/2540244999_680f234cdf.jpg" width="500" height="333" alt="DSC_0235"&gt;&lt;/a&gt;&lt;p&gt;やっぱり画素数が D70 の二倍というだけで単純にバージョンアップ感ある（でも D70 のほうはなぜか画質が FINE じゃなかったっぽいなあ）。被写体は実はこんなに小さい。&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.flickr.com/photos/k16/6237108319/" title="FM-2 WILDCAT 1/144 Sweet by Keiichirou Shikano, on Flickr"&gt;&lt;img src="http://farm7.static.flickr.com/6120/6237108319_0a827f912f.jpg" width="500" height="332" alt="FM-2 WILDCAT 1/144 Sweet"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;関係ないけど、久しぶりにSWEETのページをみたら二式水戦が新商品とな！ パーツは2機分入っているのだろうし、これは二枚反転ペラに改造してオレンジに塗るしか。。&lt;/p&gt;&lt;p&gt;そして、おつかれさまの D70。問題の原因はわかっているので、そのうち自分で修理してから息子に与える予定。&lt;/p&gt;&lt;a href="http://www.flickr.com/photos/k16/6237632230/" title="D70 with Tamron 18mm-200mm by Keiichirou Shikano, on Flickr"&gt;&lt;img src="http://farm7.static.flickr.com/6113/6237632230_30dc5491bb.jpg" width="500" height="332" alt="D70 with Tamron 18mm-200mm"&gt;&lt;/a&gt;&lt;p&gt;この D70 が最後に活躍したのが先週末の息子の運動会でした（閉会式で脈略なく担任でもない先生に抱擁されている図）。この運動会の写真をあやうく全部ロストしそうになったことで買い替えを決意したみたいなものなのだけど。chkdsk でも fsck でもどうにもならなくなってしまうと、さすがにねえ。&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.flickr.com/photos/k16/6222747717/" title="DSC_0088 by Keiichirou Shikano, on Flickr"&gt;&lt;img src="http://farm7.static.flickr.com/6154/6222747717_a8ef0a73a1.jpg" width="500" height="333" alt="DSC_0088"&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-6853454174647022031?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/6853454174647022031/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=6853454174647022031' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/6853454174647022031'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/6853454174647022031'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2011/10/3-nikon-d90-7-d70-nikon-d90-59800-d70-2.html' title='D90がきた'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm7.static.flickr.com/6093/6237630410_27bba62dc1_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-3134108173060627143</id><published>2011-09-08T13:30:00.000+09:00</published><updated>2011-09-08T14:40:57.008+09:00</updated><title type='text'>TeX でソート</title><content type='html'>ソートはソートでも単純なバブルソートです。バブルソートは、前から2つずつ要素を比べて大きいほうをどんどん後ろに送っていくという、かなり素朴な昇順並べ替えの方法です。&lt;a href="http://ja.wikipedia.org/wiki/%E3%83%90%E3%83%96%E3%83%AB%E3%82%BD%E3%83%BC%E3%83%88"&gt;Wikipedia&lt;/a&gt; にのっているアルゴリズムはこうです。&lt;pre&gt;procedure bubbleSort( A : list of sortable items ) defined as:&lt;br /&gt;  for each i in 1 to length(A) - 1 do:&lt;br /&gt;       for each j in 2 to length(A) - i + 1 do:&lt;br /&gt;         if A&lt;font color="red"&gt;[&lt;/font&gt; j &lt;font color="red"&gt;]&lt;/font&gt; &lt; A&lt;font color="red"&gt;[&lt;/font&gt; j - 1 &lt;font color="red"&gt;]&lt;/font&gt; then&lt;br /&gt;           swap( A&lt;font color="red"&gt;[&lt;/font&gt; j &lt;font color="red"&gt;]&lt;/font&gt;,  A&lt;font color="red"&gt;[&lt;/font&gt; j - 1 &lt;font color="red"&gt;]&lt;/font&gt; )&lt;br /&gt;         end if&lt;br /&gt;       end for&lt;br /&gt;  end for&lt;br /&gt;end procedure&lt;/pre&gt;TeX でこれを実装したいのですが、いつものように「配列がない」という大きな問題でつまずきます。配列っぽいものを TeX で実現する手法はいくつか考えられますが、ここでは「&lt;a href="http://note.golden-lucky.net/2011/01/tex-brainfuck.html"&gt;TeX で brainfuck&lt;/a&gt;」のときと同じく count レジスタを使うことにします。バブルソートのアルゴリズムは配列をなめるループが2重になっているので、配列のインデックス用のレジスタも 2つ必要です。また、配列の全長（length）を格納しておくレジスタもあるとうれしい（これも 2つ必要）。そのほか、要素の入れ替え（swap）をする際に一時的に利用するレジスタもほしい（これも 2つ）。&lt;pre&gt;&lt;font color="green"&gt;%% count1からcount99を明示的に使うので\newcountで割り当てるわけにいかない。。&lt;/font&gt;&lt;br /&gt;\countdef\p=0 \countdef\q=100&lt;br /&gt;\countdef\length=200 \countdef\l=201  &lt;font color="green"&gt;%% 配列の全長用&lt;/font&gt;&lt;br /&gt;\countdef\i=202 \countdef\j=203       &lt;font color="green"&gt;%% スワップ用&lt;/font&gt;&lt;/pre&gt;これだけ準備したら、冒頭のアルゴリズムを素直に書き下します。カウンタの値を増やしたり減らしたりするのに細心の注意が必要ですが、まあそのままです。&lt;pre&gt;\length=0&lt;br /&gt;\p=1&lt;br /&gt;&lt;br /&gt;\def&lt;b&gt;\sort&lt;/b&gt;#1&lt;font color="red"&gt;{&lt;/font&gt;&lt;font color="green"&gt;%&lt;/font&gt;&lt;br /&gt;  \initArray#1\last&lt;br /&gt;  \p=0 \q=1 \k=\length&lt;br /&gt;  &lt;font color="red"&gt;{&lt;/font&gt;\loop \advance\p by 1 \advance\k by -\p \advance\k by 1&lt;br /&gt;    &lt;font color="red"&gt;{&lt;/font&gt;\loop \advance\q by 1&lt;br /&gt;           \i=\count\q \advance\q by -1 &lt;font color="green"&gt;%% i = A[p]&lt;/font&gt;&lt;br /&gt;           \j=\count\q \advance\q by 1  &lt;font color="green"&gt;%% j = A[p-1]&lt;/font&gt;&lt;br /&gt;           &lt;font color="green"&gt;%% swap A[p] and A[p-1] when A[p] &gt; A[p-1]&lt;/font&gt;&lt;br /&gt;             \ifnum\i&lt;\j \global\count\q=\j \advance\q by -1&lt;br /&gt;                         \global\count\q=\i \advance\q by 1 \fi&lt;br /&gt;           \ifnum\q&lt;\k \repeat&lt;font color="red"&gt;}&lt;/font&gt;&lt;br /&gt;    \ifnum\p&lt;\length \repeat&lt;font color="red"&gt;}}&lt;/font&gt;&lt;/pre&gt;ここで、配列の初期化をする &lt;code&gt;\initArray&lt;/code&gt; はこんな定義になっています。&lt;pre&gt;\def&lt;b&gt;\initArray&lt;/b&gt;#1&lt;font color="red"&gt;{&lt;/font&gt;&lt;font color="green"&gt;%&lt;/font&gt;&lt;br /&gt;  \ifx#1\last&lt;br /&gt;    \let\next=\relax&lt;br /&gt;  \else&lt;br /&gt;    \global\count\p=#1&lt;br /&gt;    \global\advance\length by 1&lt;br /&gt;    \advance\p by 1&lt;br /&gt;    \let\next=\initArray&lt;br /&gt;  \fi\next&lt;font color="red"&gt;}&lt;/font&gt;&lt;/pre&gt;&lt;code&gt;\initArray&lt;/code&gt; で &lt;code&gt;\loop...\repeat&lt;/code&gt; を使っていない理由は特にありません。&lt;br/&gt;結果を出力するマクロも必要ですね。&lt;pre&gt;\def&lt;b&gt;\showArray&lt;/b&gt;&lt;font color="red"&gt;{&lt;/font&gt;&lt;font color="green"&gt;%&lt;/font&gt;&lt;br /&gt;  \p=1 \advance\length by 1&lt;br /&gt;  &lt;font color="red"&gt;{&lt;/font&gt;\loop&lt;br /&gt;     \number\count\p\ \advance\p by 1&lt;br /&gt;   \ifnum\p&lt;\length&lt;br /&gt;   \repeat&lt;font color="red"&gt;}}&lt;/font&gt;&lt;/pre&gt;実装おしまい。上記のコードと以下の実行例を pdftex のプロンプトにコピペすれば（最初の &lt;code&gt;\relax&lt;/code&gt; を忘れずに）……&lt;pre&gt;\sort&lt;font color="red"&gt;{{&lt;/font&gt;314&lt;font color="red"&gt;}&lt;/font&gt; 4 8 1 2 3 &lt;font color="red"&gt;{&lt;/font&gt;42&lt;font color="red"&gt;}}&lt;/font&gt;&lt;br /&gt;\showArray&lt;br /&gt;\vfill\eject\end&lt;/pre&gt;こんな結果のPDFが得られるはず。&lt;pre&gt;1 2 3 4 8 42 314&lt;/pre&gt;なお、ソートできるのは 1以上の自然数だけです。&lt;br/&gt;&lt;hr&gt;&lt;br/&gt;&lt;b&gt;まとめっぽいもの&lt;/b&gt;&lt;br/&gt;&lt;br/&gt;TeXのプログラミングが難しい背景には、ろくなデータ構造がないという側面も大きい気がします。配列でもリストでもいいのですが、とにかくトークンの列だけでは面倒なことは多すぎる。&lt;br/&gt;&lt;br/&gt;大事な話として、 count レジスタを配列に使ってしまうと別の目的に使えなくなり、これは実用上かなり無茶な制約なので、この記事はあくまでもネタでありトイプログラムです。ちなみに TeX で配列っぽいものを実現する別の方法としては、1以上の自然数 &lt;i&gt;n&lt;/i&gt; を配列のインデックスに見立て、&lt;code&gt;\&lt;/code&gt;&lt;i&gt;n&lt;/i&gt; で値を表現する方法（&lt;code&gt;\def\1{42} \def\2{314} ...&lt;/code&gt; といった具合）などが知られているようです。詳しく知りませんが検索したらそんな論文が出てきました（→ &lt;a href="http://www.tug.org/TUGboat/tb14-3/tb40laan-sort.pdf"&gt;"Sorting within TeX"（PDF）&lt;/a&gt;）。&lt;br/&gt;&lt;br/&gt;&lt;b&gt;ネタ元&lt;/b&gt;&lt;br/&gt;&lt;br/&gt;&lt;a href="http://d.hatena.ne.jp/zrbabbler/20110831/1314801058"&gt;マクロツイーター：TeX での末尾再帰 (5)&lt;/a&gt;の「問題 5」。バブルソートなら簡単ちゃうかなあと思ったら、案外と「実行制御」につまずきました。白状すると、&lt;code&gt;\sort&lt;/code&gt; の実装はそんなに簡単ではなかったです。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-3134108173060627143?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/3134108173060627143/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=3134108173060627143' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/3134108173060627143'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/3134108173060627143'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2011/09/tex.html' title='TeX でソート'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-7261385216586688801</id><published>2011-08-31T13:18:00.002+09:00</published><updated>2011-08-31T15:36:10.634+09:00</updated><title type='text'>Parsec3 におけるパーサーの型</title><content type='html'>&lt;h3&gt;きっかけは &lt;code&gt;try&lt;/code&gt;&lt;/h3&gt;いつものように Parsec2 で安穏とパーサーを書き始めたのですが、 &lt;code&gt;try&lt;/code&gt; が増えそうな気配だったこともあり、これを期に「Applicative！ Parsec3！」と思い立ちました。とっかかりとして、『Real World Haskell』 16章の例を Parsec3 で試してみることにします。&lt;pre&gt;import Control.Applicative hiding ((&lt;|&gt;))&lt;br/&gt;import Text.Parsec&lt;br/&gt;&lt;br/&gt;parser = (++) &lt;$&gt; string "HT" &lt;*&gt; (string "TP" &lt;|&gt; string "ML")&lt;/pre&gt;Parsec2 だと、 RWH に堂々と「Parsec プログラマは型宣言を省略するのが通常になってます」と書いてあったりして、パーサーの型シグネチャをはしょって生きてきました。その感覚でこのコードをコンパイルしたところ、こんなクレームが。&lt;pre&gt;No instance for (Stream s m Char)&lt;br/&gt;  arising from a use of `string'&lt;/pre&gt;はて、&lt;code&gt;(Stream s m Char)&lt;/code&gt;ってなんだろう。調べてみると、 &lt;code&gt;NoMonomorphismRestriction&lt;/code&gt; なる言語拡張を導入すれば解決するらしい（&lt;a href="http://www.haskell.org/pipermail/beginners/2009-April/001508.html"&gt;参照&lt;/a&gt;）。いわれるままソースの冒頭に &lt;code&gt;{-# LANGUAGE NoMonomorphismRestriction #-}&lt;/code&gt; という行を追加すると、確かにコンパイルに通ります。なにこのおまじない。。&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;単相性制限&lt;/h3&gt;憤慨していたら @bonotake さんからヒントをもらいました（ありがとうございます）。&lt;blockquote style="background-color:#E0FFFF;"&gt;型定義が与えられていない関数の型を推論する際に、多相的な型が想定できる場合でもデフォルトの型（Integerなど）に決めうちする、という規則らしいです。そのオプションを指定するか、型定義を忘れず自分で書けｗ ということらしい&lt;br&gt;&lt;a href="http://twitter.com/#!/bonotake/status/108445024378818562"&gt;http://twitter.com/#!/bonotake/status/108445024378818562&lt;/a&gt;&lt;/blockquote&gt;つまり型推論のときの付加的なルールとして&lt;a href="http://www.sampou.org/haskell/report-revised-j/decls.html#sect:monomorphism-restriction"&gt;単相性制限&lt;/a&gt;というのがあり、それを無効にするためのオプションがこのおまじないみたい。それにしても、単相性制限と &lt;code&gt;(Stream s m Char)&lt;/code&gt; のインスタンスがないというエラーの関係はさっぱりわかりません。&lt;br /&gt;&lt;br /&gt;単相性制限のことはいったん忘れて、パーサーの型を明示することに挑戦します。Parsec2 であれば &lt;code&gt;GenParser Char st [String]&lt;/code&gt; なのですが、Parsec3 のパーサーの型は RWH には説明がありません。 &lt;code&gt;NoMonomorphismRestriction&lt;/code&gt; を指定すればコンパイルに通ることはわかっているので、ずるをして GHC に型を教えてもらいます。&lt;pre&gt;&lt;font color="blue"&gt;*Main GOA&gt;&lt;/font&gt; :t parser&lt;br/&gt;parser :: (Stream s m Char) =&gt; ParsecT s u m [Char]&lt;/pre&gt;おや、こんなところに &lt;code&gt;Stream&lt;/code&gt; が。確かに、この型クラスのインスタンスが決まらないとパーサーの型が決まらなそうだけど、どうして単相性制限を使わないことにすると型推論が通ってしまうのだろう？&lt;br /&gt;&lt;br /&gt;単相性制限のことはもう一度忘れて、GHC が教えてくれた型を明示してコンパイルしなおしてみます。&lt;pre&gt;parser :: (Stream s m Char) =&gt; ParsecT s u m [Char]&lt;br/&gt;parser = (++) &lt;$&gt; string "HT" &lt;*&gt; (string "TP" &lt;|&gt; string "ML")&lt;/pre&gt;結果&lt;pre&gt;Non type-variable argument in the constraint: Stream s m Char&lt;br/&gt;    (Use -XFlexibleContexts to permit this)&lt;br/&gt;    In the type signature for `parser':&lt;br/&gt;      parser :: (Stream s m Char) =&gt; ParsecT s () m [Char]&lt;/pre&gt;制約に型変数じゃないものがあるとな。しかも、回避したければやっぱりおまじないを唱えろと。&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Parsec3 におけるパーサーの型&lt;/h3&gt;おまじないはいやなので、 &lt;code&gt;ParsecT&lt;/code&gt; が何ものかを調べてきっちりナシを通すことにします。まずは &lt;a href="http://hackage.haskell.org/packages/archive/parsec/3.1.0/doc/html/Text-Parsec-Prim.html#t:ParsecT"&gt;Hackage のドキュメント&lt;/a&gt;を眺めます。すると次のことがわかりました。&lt;ul&gt;&lt;li&gt;パーサーの型は &lt;code&gt;ParsecT&lt;/code&gt; で、これはモナド変換子である。&lt;/li&gt;&lt;li&gt;厳密な型シグネチャは &lt;code&gt;ParsecT s u m a&lt;/code&gt; &lt;ul&gt;&lt;li&gt;&lt;code&gt;s&lt;/code&gt; は抽象化された入力の型。この抽象化された入力をストリームという。&lt;/li&gt;&lt;li&gt;&lt;code&gt;u&lt;/code&gt; はパース時に好きな状態を格納しておく容器の型。&lt;/li&gt;&lt;li&gt;&lt;code&gt;m&lt;/code&gt; はモナド変換子にとって基盤となるモナド。&lt;/li&gt;&lt;li&gt;&lt;code&gt;a&lt;/code&gt; は出力の型&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;さらに、&lt;code&gt;Stream&lt;/code&gt; というストリームを用立てるための型クラスがあって、そのインスタンスを作ることでパーサーへの入力の型が決まるようです。&lt;code&gt;Stream&lt;/code&gt; のインスタンスになるには、入力の型（&lt;code&gt;String&lt;/code&gt; とか）と、それを読み込んでいくときの単位の型（&lt;code&gt;Char&lt;/code&gt; とか）、入力から 1単位だけ読み出して残りと組にして返す関数が必要です（実際には得られる組を &lt;code&gt;Maybe&lt;/code&gt; でくるんだものをさらに基盤となるモナドでくるむので、そのモナドも与えます）。&lt;br /&gt;&lt;br /&gt;ようやく見えてきました。&lt;code&gt;parser&lt;/code&gt;の型、つまり文字列から文字列を探して返すパーサーの型は、 &lt;code&gt;Monad m =&gt; ParsecT String u m String&lt;/code&gt; です。&lt;pre&gt;import Control.Applicative hiding ((&lt;|&gt;))&lt;br/&gt;import Text.Parsec&lt;br/&gt;&lt;br/&gt;&lt;b&gt;parser :: Monad m =&gt; ParsecT String u m String&lt;/b&gt;&lt;br/&gt;parser = (++) &lt;$&gt; string "HT" &lt;*&gt; (string "TP" &lt;|&gt; string "ML")&lt;/pre&gt;結果&lt;pre&gt;&lt;font color="blue"&gt;*Main GOA&gt;&lt;/font&gt; parseTest parser "HTTP"&lt;br/&gt;"HTTP"&lt;/pre&gt;もちろん必要なら &lt;code&gt;u&lt;/code&gt; や &lt;code&gt;m&lt;/code&gt; に具体的な何かを指定できます。何も例が思いつきませんが、いろいろ検索してみたら、ユーザーステートを配列代わりにして brainfuck を作り、処理結果を &lt;code&gt;IO&lt;/code&gt; に直接吐き出すという使い方が……。&lt;br /&gt;&lt;br /&gt;Haskell: ParsecのParsecによるBrainfuck（SnowClust）&lt;br /&gt;&lt;a href="http://inviernostring.blog106.fc2.com/blog-entry-32.html"&gt;http://inviernostring.blog106.fc2.com/blog-entry-32.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;ところで Parsec3 のパーサーの型は、brainfuck を作ったりするのでなければ、&lt;code&gt;Parser String&lt;/code&gt; という具合にお手軽に指定できるようです（ &lt;code&gt;Text.Parsec.String&lt;/code&gt; が必要）。&lt;pre&gt;import Control.Applicative hiding ((&lt;|&gt;))&lt;br/&gt;import Text.Parsec&lt;br/&gt;&lt;b&gt;import Text.Parsec.String&lt;/b&gt;&lt;br/&gt;&lt;br/&gt;&lt;b&gt;parser :: Parser String&lt;/b&gt;&lt;br/&gt;parser = (++) &lt;$&gt; string "HT" &lt;*&gt; (string "TP" &lt;|&gt; string "ML")&lt;/pre&gt;これは、こういう定義が Parsec に用意されているからです。&lt;pre&gt;type Parsec s u = ParsecT s u Identity&lt;/pre&gt;&lt;pre&gt;type Parser = Parsec String ()&lt;/pre&gt;つまり &lt;code&gt;Parser&lt;/code&gt; という型変数を使うということは、入力としては &lt;code&gt;String&lt;/code&gt; が、ユーザーステートとしては &lt;code&gt;()&lt;/code&gt; が、基盤となるモナドとしては &lt;code&gt;Identity&lt;/code&gt; が使われているということですね。&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;結局、単相性制限と最初のエラーの関係は？&lt;/h3&gt;&lt;br /&gt;もやもや中。&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-7261385216586688801?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/7261385216586688801/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=7261385216586688801' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/7261385216586688801'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/7261385216586688801'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2011/08/parsec3.html' title='Parsec3 におけるパーサーの型'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-4827671984221986588</id><published>2011-08-25T10:44:00.007+09:00</published><updated>2011-08-25T10:53:11.448+09:00</updated><title type='text'>技術書の索引にかける3つの覚悟</title><content type='html'>技術書の索引を作るのは、一筋縄ではいかない仕事です。&lt;blockquote style="background-color:#E0FFFF;"&gt;&lt;a href="http://d.kmuto.jp/20110824.html#p01"&gt;「IT書籍の索引について考える」（KeN's GNU/Linux Diary）&lt;/a&gt;&lt;br /&gt;&lt;a href="http://twitter.com/#!/YukiharuYABUKI/status/106164516936626176"&gt;矢吹さんのtweet&lt;/a&gt;から始まって、まとまりはないけど索引について思考実験。オチはないよ。&lt;/blockquote&gt;まず索引というのは、そもそも正しいページを参照するものでなければなりません。42ページを見よとなっているのに、そのキーワードも関連する概念の説明も42ページに出現しないのはまずい。また、キーワードAに対して「キーワードBを見よ」などとなっている場合もありますが、これが循環しているのもまずいです。Aの項にもBの項にも具体的なページ番号がないのは論外ですが、「…&lt;b&gt;も&lt;/b&gt;見よ」が循環しているのもまずいです。こうした参照先について要求されることがらを「索引の健全性」と呼びます。（いま作った用語。このほか、キーワードが正しく五十音順に並んでいることなんかも健全性に含まれますね。）&lt;br /&gt;&lt;br /&gt;一方、索引には、キーワードがあますところなく網羅されている必要もあります。こちらは、いわば「索引の完全性」です。索引の完全性は、「このキーワードの説明ページに飛びたい」に応えることだけではありません。「本に出現するキーワードはわからないけど、こんな話ってどこに書いてあるんだろう」とか「この話、あのキーワードの近くに説明があったような……」といった漠然とした要求にも応えられるよう、キーワードが選ばれている必要があります。&lt;br /&gt;&lt;br /&gt;読者にとって索引の悲劇というやつは、たいてい、完全性が満たされていない事態です。健全性がまるでないことが発覚した本は、発行後に回収される場合さえあるので、作ってるほうはあまり手を抜いてません。健全性は機械的に（必ずしも自動的にという意味ではない）チェックができる性質でもあります。時間や人手が足りないなら、項目を減らせばいい。かくして完全性からは程遠い索引（けど健全）ができあがります。@kmutoさんが指摘するように、索引はページ割りが確定しないと着手できない場合も多く、それはスケジュール上は時間や人手が最高に足りない時間です。つまり索引の完全性は、なりゆきで本を作っていると、おのずから低下します。少しでも完全性の高い索引を作るには、著者や編集者にそれなりの心構えが必要ということです。心構えというより、むしろ覚悟がいります。&lt;ol&gt;&lt;li&gt;キーワードの選択と参照先ページの決定（この両方の作業をインデキシングといいます）には時間がかかるという覚悟&lt;/li&gt;&lt;li&gt;インデキシングに著者を巻き込む覚悟&lt;/li&gt;&lt;li&gt;著者にはできないインデキシングもあるという覚悟&lt;/li&gt;&lt;/ol&gt;キーワードを選び出す仕事は索引作りの端緒にすぎません。そのキーワードを参照すべきベストなページ番号を選び出す仕事、あるいは、そのキーワードの文脈を判断して必要があれば複数の索引項目や階層的な索引項目にする仕事が不可欠です。もちろん、頭から眺めてそれっぽいキーワードをピックアップし、PDF で検索して出現ページを調べ、それを組にして五十音順でソートすれば、健全性の保たれた索引はできあがります。でも完全性を目指した索引は、全文検索とは違う、ひとつのコンテンツです。だから、索引作りには時間がかかります。少なくとも書籍全体をメタに読み直すだけの時間がかかります。（というわけで電子書籍にもいかした索引は必要なんですよ。）&lt;br /&gt;&lt;br /&gt;で、その時間を誰に割いてもらうか、というのが上記の2.と3.です。@kmuto さんがいうように、本の中身をいちばんよく知っているのは著者であり、著者が主体的にインデキシングした本はよい索引になることが多いです。が、ページ割が決まった後でないとインデキシングできないのでは、著者に作業をお願いしにくい。この点、LaTeXとかXMLからの自動組版は秀でています。なにせ、著者が自分の手で原稿に入れたメタ情報をそのまま情報を落とさずに利用できるのだから。つまり、こういう要求にも応えられる。&lt;blockquote style="background-color:#E0FFFF;"&gt;自分のDebian徹底本では索引用に5種類くらいのタグを使い分けて後処理していた。当時は紙に組んだら情報がかなり落ちてしまったのでいろいろもったいなかったんだけど、今ならもうちょっとうまい方法を思いつけそう&lt;br /&gt;&lt;a href="http://twitter.com/#!/kmuto/status/106236697867599872"&gt;http://twitter.com/#!/kmuto/status/106236697867599872&lt;/a&gt;&lt;/blockquote&gt;実際、『&lt;a href="http://ssl.ohmsha.co.jp/cgi-bin/menu.cgi?ISBN=978-4-274-06785-3"&gt;RailsによるアジャイルWebアプリケーション開発&lt;/a&gt;』という本の第2版以降は、原著のXMLデータ（著者本人が作ってるもの）からあらゆるインデキシングに関する情報を抜き出しているつもり。（第4版はもうちょっとお待ちください。）&lt;br /&gt;&lt;br /&gt;とはいえ、著者が作ればうまい索引になるというわけでもないのだよなあ。そこで、だからこそ編集者がいるんだ、というポジショントークです。最近の自分がかかわった例だと、『&lt;a href="http://ssl.ohmsha.co.jp/cgi-bin/menu.cgi?ISBN=978-4-274-06847-8"&gt;Coders at Work&lt;/a&gt;』という読み物があるのですが、これ、ちゃんと索引つけています。なんで読み物に索引ついてるんだという話ですが、この記事で最初のほうに言及した「この話、あのキーワードの近くに説明があったような……」に応えるためというのと、複数の話者のインタビュー集なので、同一の話題をパラレルに参照可能な手段があるほうがよかろうなと考えたからです。たとえば「テスト」のような項目を引いてもらうとわかりますが、別々の話者が主にテストについて語っている部分に飛べるようになっています。「テスト」というキーワードの直接出現がない場合もあるので健全性を一部犠牲にしていますが、後悔はしていない。なお、本書は原書にも索引はあるのですが、これが典型的な「それっぽいキーワードの出現箇所を適当に参照してみました」な出来だっていたので、結果的には参考にしませんでした（どうやら英語圏の大手出版社には「indexer」という専門職がいるようなので、その仕事っぷりによって索引の出来が大きく左右されてるような気もします）。&lt;br /&gt;&lt;br /&gt;とはいえ、編集者が不要なインデキシングができるすごい著者はたくさんいて、たとえば『&lt;a href="http://ssl.ohmsha.co.jp/cgi-bin/menu.cgi?ISBN=978-4-274-06775-4"&gt;プログラミングのための確率統計&lt;/a&gt;』の著者の方々とか。それでも、編集者としては、たとえば「Γ関数」を「G」からも「記号・ギリシャ語」からも「カ行」からもひけるようにしました。いや、もしかしたらこれも平岡さんがやったのだったっけ？ そこはかとなく気もしてきましたが、とにかくこれはすごい本です。&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-4827671984221986588?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/4827671984221986588/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=4827671984221986588' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/4827671984221986588'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/4827671984221986588'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2011/08/3.html' title='技術書の索引にかける3つの覚悟'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-2384134542404808094</id><published>2011-08-16T22:15:00.003+09:00</published><updated>2011-08-16T22:22:54.329+09:00</updated><title type='text'>TeXでナベアツ</title><content type='html'>&lt;blockquote style="background-color:#E0FFFF;"&gt;以下の動作を行うマクロ \NabeAzz を作れ。&lt;br /&gt;&lt;a href="http://d.hatena.ne.jp/zrbabbler/20110815/1313398638"&gt;http://d.hatena.ne.jp/zrbabbler/20110815/1313398638&lt;/a&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;一晩すぎたっぽいし、回答例アップしてもいいよね。&lt;pre&gt;\newcount\n \newcount\i&lt;br/&gt;\newcount\r \newcount\q&lt;br/&gt;\newcount\a \newcount\b&lt;br/&gt;\newcount\d&lt;br/&gt;\font\cmfi=cmfi10 at 12pt&lt;br/&gt;&lt;br/&gt;\newif\ifhasdigit&lt;br/&gt;\def\hasdigit#1#2{\d=#1 \r=10 \q=#2 \a=\q&lt;br/&gt;  \divide\q by \r&lt;br/&gt;    \b=\q \multiply\b by -\r&lt;br/&gt;    \advance\a by\b&lt;br/&gt;    \ifnum\a=\d \hasdigittrue&lt;br/&gt;      \else \ifnum\q=0 \hasdigitfalse&lt;br/&gt;        \else \hasdigit{\d}{\q}\fi\fi}&lt;br/&gt;&lt;br/&gt;\newif\ifdividep&lt;br/&gt;\def\dividep#1#2{\r=#1 \q=#2 \a=\q&lt;br/&gt;  \divide\q by \r&lt;br/&gt;    \b=\q \multiply\b by -\r&lt;br/&gt;    \advance\a by\b&lt;br/&gt;    \ifnum0=\a \divideptrue&lt;br/&gt;      \else \dividepfalse \fi}&lt;br/&gt;&lt;br/&gt;\def\NabeAzz#1{\n=#1 \i=1&lt;br/&gt;  \loop \ifnum\i&amp;lt;\n&lt;br/&gt;    \hasdigit{3}{\i}\dividep{3}{\i}&lt;br/&gt;    \ifhasdigit{\cmfi \number\i}\else&lt;br/&gt;    \ifdividep{\cmfi\number\i}\else&lt;br/&gt;    {\number\i}\fi\fi&lt;br/&gt;    \advance \i by 1&lt;br/&gt;  \repeat}&lt;br/&gt;&lt;br/&gt;\noindent\NabeAzz{400}&lt;br/&gt;&lt;br/&gt;\vfill\eject\end&lt;/pre&gt;とくに奇妙なことはしていません。10進表記でない整数（16進とか8進とか文字とか）も引数にとれるところがちょっとポイント。アプローチは &lt;a href="http://note.golden-lucky.net/2010/03/texfizzbuzz.html"&gt;FizzBuzz&lt;/a&gt; とまったく同じ。FizzBuzz もナベアツも、整数の剰余をどう扱うかに TeX ならではの難しさがあるので、TeX マクロを使えるかどうかよりも、初等代数的なことを考える力を試されている気分。&lt;br /&gt;&lt;br /&gt;参考文献はいうまでもなく "TeX Book" 一択。日本語版だと 296ページに出てくる \hex マクロを参考にしています。&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-2384134542404808094?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/2384134542404808094/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=2384134542404808094' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/2384134542404808094'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/2384134542404808094'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2011/08/tex_16.html' title='TeXでナベアツ'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-3216478275447296384</id><published>2011-08-16T09:10:00.004+09:00</published><updated>2011-11-22T16:26:08.616+09:00</updated><title type='text'>はじめてでも安心 SXML入門</title><content type='html'>&lt;p&gt;HTMLやXMLの文章を扱っていると、気楽にこんな操作をしたいケースが間々あります。&lt;ol&gt;&lt;li&gt;親に応じて処理を分けたい（例： &lt;code&gt;&amp;lt;title&gt;&lt;/code&gt; 要素に対して、その親が &lt;code&gt;&amp;lt;chapter&gt;&lt;/code&gt; なら処理 A 、 &lt;code&gt;&amp;lt;section&gt;&lt;/code&gt; なら処理 B をしたい）&lt;/li&gt;&lt;li&gt;ある属性を持つ要素だけ処理したい（例： &lt;code&gt;lang="en"&lt;/code&gt; な &lt;code&gt;&amp;lt;p&gt;&lt;/code&gt; 要素だけ抜き出したい）&lt;/li&gt;&lt;li&gt;同じレベルの次の要素に応じて処理をしたい（例：表の各行の色を縞々にするため、 &lt;code&gt;&amp;lt;table&gt;&lt;/code&gt; 直下の &lt;code&gt;&amp;lt;tr&gt;&lt;/code&gt; に交互に属性 &lt;code&gt;bgcolor="#cccccc"&lt;/code&gt; と &lt;code&gt;bgcolor="#ffffff"&lt;/code&gt; をつけたい）&lt;/li&gt;&lt;/ol&gt;（いずれもブラウザへの表示であれば CSS で実現できますが、いまは出力も XML データとして欲しい場合の話です。）&lt;/p&gt;&lt;p&gt;XML データの本質が木構造であることを思い出すと、この山括弧が S 式にさえなっていれば、 Scheme の関数でどうにでも操作できる気がしてきます。SXML は、まさにそのような夢をかなえてくれるものです。詳しくは &lt;a href="http://ja.wikipedia.org/wiki/SXML"&gt;Wikipedia&lt;/a&gt; で。ここでは、Gauche に入っている XML から SXML へのパーザーと SXML の操作関数、山括弧表記へのシリアライザを使って、SXML データを操る方法をまとめます。&lt;/p&gt;&lt;h3&gt;XML データを SXML へ&lt;/h3&gt;&lt;p&gt;何も考えずに &lt;code&gt;ssax:xml-&gt;sxml&lt;/code&gt; というユーティリティを使います。自分の目的に応じた XML パーザを作る仕組みも提供されているのですが、私は使ったことがありません。&lt;/p&gt;&lt;pre&gt;(use sxml.ssax)&lt;br /&gt;&lt;br /&gt;(call-with-input-file &lt;font color="brown"&gt;"test.xml"&lt;/font&gt;&lt;br /&gt;  (lambda (port)&lt;br /&gt;    (with-module sxml.ssax&lt;br /&gt;      (ssax:xml-&gt;sxml port '()))))&lt;/pre&gt;&lt;p&gt;ただ一点だけ、このユーティリティを黙って使う際にぶつかる壁があって、それは文字実体参照です。定義済み実体しか解釈してくれません。そのため、たとえば &lt;code&gt;&amp;amp;nbsp;&lt;/code&gt; が混ざっているとはじかれます。 &lt;code&gt;&amp;amp;nbsp;&lt;/code&gt; は HTML でよく使われるので、これはいささか不便です。&lt;/p&gt;&lt;p&gt;&lt;code&gt;ssax:xml-&gt;sxml&lt;/code&gt; には外部の文字実体参照を指定できる仕組みがないので戸惑うところですが、 &lt;code&gt;sxml.ssax&lt;/code&gt; のソースを見ると &lt;code&gt;ssax:predefined-parsed-entities&lt;/code&gt; というのがあって、これをつつけばよさそう。幸い、 Gauche には &lt;code&gt;with-module&lt;/code&gt; という仕組みがあるので、これを使って文字実体参照のデフォルトを「上書き」してしまいます。&lt;/p&gt;&lt;pre&gt;(use sxml.ssax)&lt;br /&gt;&lt;br /&gt;(call-with-input-file &lt;font color="brown"&gt;"test.xml"&lt;/font&gt;&lt;br /&gt;  (lambda (port)&lt;br /&gt;    (with-module sxml.ssax&lt;br /&gt;      (fluid-let ((ssax:predefined-parsed-entities&lt;br /&gt;                  (list '(nbsp . &lt;font color="brown"&gt;" "&lt;/font&gt;) '(amp . &lt;font color="brown"&gt;"&amp;"&lt;/font&gt;) '(lt . &lt;font color="brown"&gt;"&lt;"&lt;/font&gt;) '(gt . &lt;font color="brown"&gt;"&gt;"&lt;/font&gt;)&lt;br /&gt;                        '(quot . &lt;font color="brown"&gt;"\"&lt;/font&gt;) '(apos . &lt;font color="brown"&gt;"'"&lt;/font&gt;)))&lt;br /&gt;        (display (ssax:xml-&gt;sxml port '()))))))&lt;/pre&gt;&lt;p&gt;これで次のようなファイル &lt;code&gt;"test.xml"&lt;/code&gt; が、&lt;pre&gt;&amp;lt;body&gt;&lt;br /&gt;  &amp;lt;p&gt;ab&amp;amp;nbsp;c&amp;lt;/p&gt;&lt;br /&gt;&amp;lt;/body&gt;&lt;/pre&gt;次のような S 式になります。&lt;pre&gt;(*TOP* (body (p &lt;font color="brown"&gt;"ab c"&lt;/font&gt;)))&lt;/pre&gt;&lt;/p&gt;&lt;h3&gt;肩慣らし：要素の取得&lt;/h3&gt;&lt;p&gt;とりあえず、これから使うサンプルの XML データを用意します。&lt;/p&gt;&lt;pre&gt;(define newbooks &lt;font color="brown"&gt;"&lt;br /&gt;&amp;lt;table&gt;&lt;br /&gt;  &amp;lt;thead&gt;話題の新刊&amp;lt;/thead&gt;&lt;br /&gt;  &amp;lt;tbody&gt;&lt;br /&gt;    &amp;lt;tr&gt;&amp;lt;th&gt;書名&amp;lt;/th&gt;&amp;lt;th&gt;価格&amp;lt;/th&gt;&amp;lt;/tr&gt;&lt;br /&gt;    &amp;lt;tr&gt;&amp;lt;td&gt;抽象によるソフトウェア設計&amp;lt;/td&gt;&amp;lt;td&gt;4500円&amp;lt;/td&gt;&amp;lt;/tr&gt;&lt;br /&gt;    &amp;lt;tr&gt;&amp;lt;td&gt;インターネットのカタチ&amp;lt;/td&gt;&amp;lt;td&gt;1900円&amp;lt;/td&gt;&amp;lt;/tr&gt;&lt;br /&gt;    &amp;lt;tr&gt;&amp;lt;td&gt;Scheme修行&amp;lt;/td&gt;&amp;lt;td&gt;2800円&amp;lt;/td&gt;&amp;lt;/tr&gt;&lt;br /&gt;    &amp;lt;tr&gt;&amp;lt;td&gt;Coders at Work&amp;lt;/td&gt;&amp;lt;td&gt;2800円&amp;lt;/td&gt;&amp;lt;/tr&gt;&lt;br /&gt;  &amp;lt;/tbody&gt;&lt;br /&gt;&amp;lt;/table&gt;&lt;br /&gt;"&lt;/font&gt;)&lt;/pre&gt;&lt;p&gt;また、 XML の山括弧で表現されたテキストを SXML のデータに変換する関数をでちあげます（先に使ったコードと本質的に同じもの）。&lt;/p&gt;&lt;pre&gt;(define (string-&gt;sxml str)&lt;br /&gt;  (call-with-input-string str&lt;br /&gt;    (lambda (port)&lt;br /&gt;      (ssax:xml-&gt;sxml port '()))))&lt;/pre&gt;&lt;p&gt;これから何度か利用するので、テーブル &lt;code&gt;newbooks&lt;/code&gt; を SXML に変換したものに名前をつけておきます。これは恣意的に &lt;code&gt;root&lt;/code&gt; という名前にします。&lt;/p&gt;&lt;pre&gt;(define root (string-&gt;sxml newbooks))&lt;/pre&gt;&lt;p&gt;準備はここまで。肩慣らしにテーブルからヘッダ部分を取り出してみましょう。実は XPath のような指定が使えます。&lt;/p&gt;&lt;pre&gt;&lt;font color="blue"&gt;gosh&gt;&lt;/font&gt; ((sxpath &lt;font color="brown"&gt;"table/thead"&lt;/font&gt;) root)&lt;br /&gt;=&gt; ((thead &lt;font color="brown"&gt;"話題の新刊"&lt;/font&gt;))&lt;/pre&gt;&lt;p&gt;「&lt;code&gt;"table/thead"&lt;/code&gt;」の部分には、求めるノードへのパスを XPath に似た（ほとんどそのまんまの）構文で記述できます。その記述に関数 &lt;code&gt;sxpath&lt;/code&gt; を適用すると、ノードの集合からノード（記述したパスを満たすもの）を取り出す関数（コンバーターと呼びます）が返ってくるので、それを &lt;code&gt;root&lt;/code&gt; に適用すれば求めるノードが手に入るという仕掛けです。&lt;/p&gt;&lt;h3&gt;よりScheme風に&lt;/h3&gt;&lt;p&gt;関数 &lt;code&gt;sxpath&lt;/code&gt; は便利で多機能なのですが、クエリを組み立てるのに XPath の文法を知らないといけないので、ここではもうちょっと Scheme ふうのやり方を紹介します。&lt;/p&gt;&lt;pre&gt;&lt;font color="blue"&gt;gosh&gt;&lt;/font&gt; ((node-closure (ntype-names?? '(thead))) root)&lt;br /&gt;=&gt; ((thead &lt;font color="brown"&gt;"話題の新刊"&lt;/font&gt;))&lt;/pre&gt;&lt;p&gt;この方法も、「ノードの集合からノードを取り出すコンバーター関数を作って、それを &lt;code&gt;root&lt;/code&gt; に適用する」という方針は &lt;code&gt;sxpath&lt;/code&gt; バージョンと同じです。コンバーターの作り方がちょっと違います。 &lt;code&gt;node-closure&lt;/code&gt; という関数は、引数として述語をとり、その述語を満たすようなノードを「再帰的に」とってくるコンバーターを作ります。「再帰的に」というのは、述語を満たすノードをSXML木の根っこを起点に探すだけでなく、あらゆる子孫（大本の根っこも含みます）を起点に探すという意味です。この例では、「&lt;code&gt;thead&lt;/code&gt; という名前かどうか？」（ &lt;code&gt;(ntype-names?? '(thead))&lt;/code&gt; ）という述語を指定しているので、とにかく木全体からその名前のノードをとってきます。&lt;/p&gt;&lt;p&gt;ところで、得られるノードは1つとは限りません。&lt;/p&gt;&lt;pre&gt;&lt;font color="blue"&gt;gosh&gt;&lt;/font&gt; ((node-closure (ntype-names?? '(td))) root)&lt;br /&gt;=&gt;((td &lt;font color="brown"&gt;"抽象によるソフトウェア設計"&lt;/font&gt;) (td &lt;font color="brown"&gt;"4500円"&lt;/font&gt;) (td &lt;font color="brown"&gt;"インターネットのカタチ"&lt;/font&gt;) (td &lt;font color="brown"&gt;"1900円"&lt;/font&gt;)&lt;br /&gt;   (td &lt;font color="brown"&gt;"Scheme修行"&lt;/font&gt;) (td &lt;font color="brown"&gt;"2800円"&lt;/font&gt;) (td &lt;font color="brown"&gt;"Coders at Work"&lt;/font&gt;) (td &lt;font color="brown"&gt;"2800円"&lt;/font&gt;))&lt;/pre&gt;&lt;p&gt;ここで気にかけておくべきなのは、こうして REPL から結果がリストとして返ってくるとまるで結果のノードからなる新しいリストが得られたように錯覚するけれど、これらはちゃんと &lt;code&gt;root&lt;/code&gt; の部分木になっているということです。つまり、これらの結果から、例えば「親」を知ることができます。&lt;/p&gt;&lt;pre&gt;&lt;font color="blue"&gt;gosh&gt;&lt;/font&gt; (define tds ((node-closure (ntype-names?? '(td))) root))&lt;br /&gt;&lt;font color="blue"&gt;gosh&gt;&lt;/font&gt; (((sxml:parent (ntype?? '*any*)) root) (car tds))&lt;br /&gt;=&gt; ((tr (td &lt;font color="brown"&gt;"抽象によるソフトウェア設計"&lt;/font&gt;) (td &lt;font color="brown"&gt;"4500円"&lt;/font&gt;)))&lt;/pre&gt;&lt;p&gt;&lt;code&gt;(ntype?? '*any*)&lt;/code&gt; は「何でもいい」という述語です。この式は、親（ &lt;code&gt;sxml:parent&lt;/code&gt; ）なら何でもいいからとってこい、という意味になります。&lt;/p&gt;&lt;p&gt;くどくいようですが、上記の &lt;code&gt;(car tds)&lt;/code&gt; は表現としては &lt;code&gt;(td &lt;font color="brown"&gt;"抽象によるソフトウェア設計"&lt;/font&gt;)&lt;/code&gt; というリストだけれども、そういう表現のリストに対して上記の結果が得られるのではありません。（当たり前の話だけど、最初はやっぱり見た目に惑わされがち。）&lt;/p&gt;&lt;pre&gt;&lt;font color="blue"&gt;gosh&gt;&lt;/font&gt; (((sxml:parent (ntype?? '*any*)) root) '(td &lt;font color="brown"&gt;"抽象によるソフトウェア設計"&lt;/font&gt;))&lt;br /&gt;=&gt; ()&lt;/pre&gt;&lt;h3&gt;実践編：ノードを追加する&lt;/h3&gt;&lt;p&gt;SXML は木にすぎないので、その一部を変更するような操作も、 Scheme のような言語であればわりと直感的に書けます。ここでは、先の書籍一覧のテーブルの各行に「税」という項目を追加してみます。もちろん税額は、すでにテーブルに含まれている価格から求めます。そこでまず、価格の文字列から税額の文字列を作る関数を定義します。ここでは安直に正規表現で。&lt;/p&gt;&lt;pre&gt;&lt;font color="green"&gt;;; string -&gt; string&lt;/font&gt;&lt;br /&gt;(define (tax-price str)&lt;br /&gt;  (rxmatch-if (#/([\d]*)円/ str)&lt;br /&gt;      (m price)&lt;br /&gt;    #`&lt;font color="brown"&gt;",(* 5/100 (x-&gt;integer price))円"&lt;/font&gt;&lt;br /&gt;    #f))&lt;/pre&gt;&lt;p&gt;次に、この &lt;code&gt;tax-price&lt;/code&gt; 関数を使って「 &lt;code&gt;&amp;lt;tr&gt;&lt;/code&gt; ノードから税額を要素に持つ &lt;code&gt;&amp;lt;td&gt;&lt;/code&gt; ノードを作る関数」を定義します。なお、 SXML の一部をいじる関数を作るときは、このようにノードからノード（あるいはノードの集合）への関数として定義しておきましょう。そのほうが SXPath 用の適用関数をいろいろ利用できて便利です。&lt;/p&gt;&lt;pre&gt;&lt;font color="green"&gt;;; node -&gt; node&lt;/font&gt;&lt;br /&gt;(define (tax-node node)&lt;br /&gt;  (cond ((tax-price (sxml:string-value node)) =&gt; (pa$ list 'td))&lt;br /&gt;        (((sxpath &lt;font color="brown"&gt;"th"&lt;/font&gt;) tr) '(th &lt;font color="brown"&gt;"税"&lt;/font&gt;))&lt;br /&gt;        (else '())))&lt;/pre&gt;&lt;p&gt;あとは各行に &lt;code&gt;tax-node&lt;/code&gt; で得られるノードを要素として追加するだけですが、要素を追加する関数は Gauche にはないようなので、既存の要素 &lt;code&gt;(sxml:content-raw tr)&lt;/code&gt; と新しいノード &lt;code&gt;(tax-node tr)&lt;/code&gt; とを連結したもので既存のノードを置き換えます。木の一部を破壊的に変更する必要があるので、きちんと避難しましょう（『 Scheme 修行』ね）。&lt;/p&gt;&lt;pre&gt;(let1 root (string-&gt;sxml newbooks)&lt;br /&gt;  (for-each (lambda (tr)&lt;br /&gt;              (sxml:change-content! tr `(,@(sxml:content-raw tr) ,(tax-node tr))))&lt;br /&gt;            ((node-closure (ntype-names?? '(tr))) root))&lt;br /&gt;  root)&lt;br /&gt;&lt;br /&gt;=&gt; (*TOP* (table (thead &lt;font color="brown"&gt;"話題の新刊"&lt;/font&gt;) (tbody&lt;br /&gt;      (tr (th &lt;font color="brown"&gt;"書名"&lt;/font&gt;) (th &lt;font color="brown"&gt;"価格"&lt;/font&gt;) (th &lt;font color="brown"&gt;"税"&lt;/font&gt;))&lt;br /&gt;      (tr (td &lt;font color="brown"&gt;"抽象によるソフトウェア設計"&lt;/font&gt;) (td &lt;font color="brown"&gt;"4500円"&lt;/font&gt;) (td &lt;font color="brown"&gt;"225円"&lt;/font&gt;))&lt;br /&gt;      (tr (td &lt;font color="brown"&gt;"インターネットのカタチ"&lt;/font&gt;) (td &lt;font color="brown"&gt;"1900円"&lt;/font&gt;) (td &lt;font color="brown"&gt;"95円"&lt;/font&gt;))&lt;br /&gt;      (tr (td &lt;font color="brown"&gt;"Scheme修行"&lt;/font&gt;) (td &lt;font color="brown"&gt;"2800円"&lt;/font&gt;) (td &lt;font color="brown"&gt;"140円"&lt;/font&gt;))&lt;br /&gt;      (tr (td &lt;font color="brown"&gt;"Coders at Work"&lt;/font&gt;) (td &lt;font color="brown"&gt;"2800円"&lt;/font&gt;) (td &lt;font color="brown"&gt;"140円"&lt;/font&gt;)))))&lt;/pre&gt;&lt;h3&gt;軸とか&lt;/h3&gt;&lt;p&gt;テーブルのいちばん左の列をヘッダのように使いたいことがあります。各 &lt;code&gt;&amp;lt;tr&gt;&lt;/code&gt; ノードの最初の要素に &lt;code&gt;bgcolor=&lt;font color="brown"&gt;"#cccccc"&lt;/font&gt;&lt;/code&gt; とつけるにはどうしたらいいでしょうか。&lt;p&gt;&lt;/p&gt;ぱっと思いつくのは、先行する要素がなければ属性を追加する、という処理です。 SXML では、 XPath のように、親や子孫、先行や後続といった「軸」が利用できます。これを使って、各行の先頭の要素に背景色の属性を付けてみましょう。&lt;/p&gt;&lt;pre&gt;(let1 root (string-&gt;sxml newbooks)&lt;br /&gt;  (for-each (lambda (td)&lt;br /&gt;              (if (null? (((sxml:preceding-sibling sxml:element?) root) td))&lt;br /&gt;                  (sxml:set-attr! td '(bgcolor &lt;font color="brown"&gt;"#cccccc"&lt;/font&gt;))))&lt;br /&gt;            ((node-closure (ntype-names?? '(td th))) root))&lt;br /&gt;  root)&lt;/pre&gt;&lt;p&gt;使っている軸は、先行する兄弟の軸 &lt;code&gt;sxml:preceding-sibling&lt;/code&gt; です。 &lt;code&gt;&amp;lt;td&gt;&lt;/code&gt; 要素のそれぞれについて、先行する兄弟の要素がいるかどうかチェックし、いなかったら属性を設定しています。要素の軸は、その要素が含まれる木（もちろん部分木のことも）に対して決まるものなので、 &lt;code&gt;((sxml:preceding-sibling sxml:element?) root)&lt;/code&gt; のように木を明示する必要があります。&lt;/p&gt;&lt;pre&gt;=&gt; (*TOP* (table (thead &lt;font color="brown"&gt;"話題の新刊"&lt;/font&gt;) (tbody&lt;br /&gt;      (tr (th (|@| #0=(bgcolor &lt;font color="brown"&gt;"#cccccc"&lt;/font&gt;)) &lt;font color="brown"&gt;"書名"&lt;/font&gt;) (th &lt;font color="brown"&gt;"価格"&lt;/font&gt;))&lt;br /&gt;      (tr (td (|@| #0#) &lt;font color="brown"&gt;"抽象によるソフトウェア設計"&lt;/font&gt;) (td &lt;font color="brown"&gt;"4500円"&lt;/font&gt;))&lt;br /&gt;      (tr (td (|@| #0#) &lt;font color="brown"&gt;"インターネットのカタチ"&lt;/font&gt;) (td &lt;font color="brown"&gt;"1900円"&lt;/font&gt;))&lt;br /&gt;      (tr (td (|@| #0#) &lt;font color="brown"&gt;"Scheme修行"&lt;/font&gt;) (td &lt;font color="brown"&gt;"2800円"&lt;/font&gt;))&lt;br /&gt;      (tr (td (|@| #0#) &lt;font color="brown"&gt;"Coders at Work"&lt;/font&gt;) (td &lt;font color="brown"&gt;"2800円"&lt;/font&gt;)))))&lt;/pre&gt;&lt;p&gt;なお、ここではわざわざ軸を使っていちばん左の列を選択しましたが、 1つめの要素、のような指定の仕方で取得することももちろんできます。&lt;/p&gt;&lt;pre&gt;(let1 root (string-&gt;sxml newbooks)&lt;br /&gt;  (for-each (lambda (tr)&lt;br /&gt;              (sxml:set-attr!&lt;br /&gt;               (car ((node-pos 1) ((node-closure (ntype-names?? '(td th))) tr)))&lt;br /&gt;               '(bgcolor &lt;font color="brown"&gt;"#cccccc"&lt;/font&gt;)))&lt;br /&gt;            ((node-closure (ntype-names?? '(tr))) root))&lt;br /&gt;  root)&lt;/pre&gt;&lt;h3&gt;山括弧にするには&lt;/h3&gt;&lt;p&gt;良し悪しは別にして、やはり山括弧に戻せないといろいろ不便です。とくに html をいじっている場合には。Gauche のマニュアルを見ていると &lt;code&gt;sxml-&gt;html&lt;/code&gt; という名前が付いた関数が二種類（&lt;code&gt;sxml:sxml-&gt;html&lt;/code&gt; と &lt;code&gt;srl:sxml-&gt;html&lt;/code&gt;）ありますが、ここで使うべきは &lt;code&gt;srl:sxml-&gt;html&lt;/code&gt; のほうです。&lt;/p&gt;&lt;pre&gt;(use sxml.serializer)&lt;br /&gt;&lt;br /&gt;(srl:sxml-&gt;html&lt;br /&gt; (let1 root (string-&gt;sxml newbooks)&lt;br /&gt;   (for-each (lambda (tr)&lt;br /&gt;               (sxml:set-attr!&lt;br /&gt;                (car ((node-pos 1)&lt;br /&gt;                      ((node-closure (ntype-names?? '(td th))) tr)))&lt;br /&gt;                '(bgcolor &lt;font color="brown"&gt;"#cccccc"&lt;/font&gt;)))&lt;br /&gt;             ((node-closure (ntype-names?? '(tr))) root))&lt;br /&gt;   root))&lt;/pre&gt;&lt;p&gt;よろしくインデントされた結果が返されます。&lt;/p&gt;&lt;pre&gt;&amp;lt;table&gt;&lt;br /&gt;  &amp;lt;thead&gt;話題の新刊&amp;lt;/thead&gt;&lt;br /&gt;  &amp;lt;tbody&gt;&lt;br /&gt;    &amp;lt;tr&gt;&lt;br /&gt;      &amp;lt;th bgcolor=&lt;font color="brown"&gt;"#cccccc"&lt;/font&gt;&gt;書名&amp;lt;/th&gt;&lt;br /&gt;      &amp;lt;th&gt;価格&amp;lt;/th&gt;&lt;br /&gt;    &amp;lt;/tr&gt;&lt;br /&gt;    （略）&lt;br /&gt;  &amp;lt;/tbody&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/table&gt;&lt;/pre&gt;&lt;h3&gt;最後に宣伝&lt;/h3&gt;&lt;p&gt;&lt;a href="http://ssl.ohmsha.co.jp/cgi-bin/menu.cgi?ISBN=978-4-274-06853-9"&gt;&lt;image src="http://ssl.ohmsha.co.jp/imgm/978-4-274-06853-9.gif"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://ssl.ohmsha.co.jp/cgi-bin/menu.cgi?ISBN=978-4-274-06853-9"&gt;『Scheme修行』&lt;/a&gt;&lt;/p&gt;&lt;p&gt;ちなみに、この記事のタイトルは『&lt;a href="http://twitter.com/#!/ctakao/status/101102749550252032"&gt;はじめてでも安心コスプレ入門&lt;/a&gt;』から&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-3216478275447296384?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/3216478275447296384/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=3216478275447296384' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/3216478275447296384'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/3216478275447296384'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2011/08/sxml.html' title='はじめてでも安心 SXML入門'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-7756622368869585717</id><published>2011-08-13T18:19:00.002+09:00</published><updated>2011-08-14T15:20:37.222+09:00</updated><title type='text'>3才、補助輪なし自転車への挑戦</title><content type='html'>3才半の息子のために自転車を買いました。補助輪もついていたのですが、取り付けずにさっそく公園にいきます。&lt;br /&gt;&lt;br /&gt;&lt;iframe width="425" height="349" src="http://www.youtube.com/embed/A5K8jCpLyj4" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;気持ち下り勾配のある場所なのですが、はじめてペダルつきの自転車に挑戦して、いきなり一人で乗ることができました。我が子ながらよくやったと思います。ちなみに、この自転車の商品名は「&lt;a href="http://www.people-kk.co.jp/showroom/jit/jit_top_construction.htm"&gt;いきなり自転車&lt;/a&gt;」です。先日『&lt;a href="http://ssl.ohmsha.co.jp/cgi-bin/menu.cgi?ISBN=978-4-274-06824-9"&gt;インターネットのカタチ&lt;/a&gt;』という本にからめたイベントの懇親会でこの自転車の販売会社の方と知り合い、旧モデルをゆずっていただきました。ありがとうございます。&lt;br /&gt;&lt;br /&gt;で、まあ親バカ記事ではあるのですが、なんで3才半でいきなり自転車に乗れるのかを知りたい人はけっこういると思うので、種明かしをします。実は、彼は1才半ころからこれで遊んでました。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/k16/3873569386/" title="balance bike by Keiichirou Shikano, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2558/3873569386_715a45dfee_m.jpg" width="240" height="159" alt="balance bike"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;ペダルなしの二輪車です。一般名称としては&lt;a href="http://en.wikipedia.org/wiki/Balance_bicycle"&gt;バランスバイク&lt;/a&gt;とか呼ばれています。この「&lt;a href="http://www.strider.jp/"&gt;ストライダー&lt;/a&gt;」という商品を選んだのは、Webでいろいろ調べたところ、さまざまな配慮がなされた商品であるように見受けられたからです。当時は日本の代理店が皆無だったので個人輸入しました（自転車は車両扱いで関税がかからない！）。最近は日本でもふつうに手に入るようになり、街でも見かけるようになりました。&lt;br /&gt;&lt;br /&gt;車体がそこそこ軽いので、1才も終わりになると自分で取り回せるようになりました。足で地面を蹴って進むので1才でもよちよちながら走行を楽しめます。しかし、まがりなりにも二輪車なので、ある程度のスピードで走るには前進速度とバランスに対する感覚が必要になります。また、公道を走るからには、交差点で止まるとか、他人がいるときは飛ばさないとか、そういう交通に対する理解も培っていく必要があります。&lt;br /&gt;&lt;br /&gt;最近ではこれくらいには乗りこなせるようになっていました。&lt;br /&gt;&lt;br /&gt;&lt;iframe width="425" height="349" src="http://www.youtube.com/embed/P7nX68DCr5A" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;15秒付近から両足を離して滑走しています。（個人差はあるでしょうが、たいていの子はしばらく練習すればこれくらい走れるようです。）&lt;br /&gt;&lt;br /&gt;というわけで、3才半でいきなり補助輪なし自転車で走れたのは、このバランスバイクで養った何かのおかげではないかと推測しています。もちろんサンプル数が高々1なので推測の域は出ませんが、自分はかつて苦労して補助輪はずしの練習をした覚えもあるし、バランスバイクの影響がまったくないということはないように思います。&lt;br /&gt;&lt;br /&gt;ただ、補助輪なしで走れるには走れるのですが、3才半だと自転車の本体が重くて取り回しがうまくできないのと、ペダルをこぎ出すための筋力が足りないようで、自力でゼロからこぎ出せるわけではありません。最初の動画のように下り勾配がある場所ならいけるのですが、そうでなければ助走が必要です。「いきなり自転車」の後ろには大人が制御するための舵取り棒がついていたので、これはたいそう助かりました。&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-7756622368869585717?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/7756622368869585717/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=7756622368869585717' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/7756622368869585717'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/7756622368869585717'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2011/08/blog-post.html' title='3才、補助輪なし自転車への挑戦'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://img.youtube.com/vi/A5K8jCpLyj4/default.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-4836224532356270200</id><published>2011-08-10T12:37:00.007+09:00</published><updated>2011-08-10T14:52:54.300+09:00</updated><title type='text'>TeXで「最後のコマンド」だけ挙動を変える（ワンパス版）</title><content type='html'>&lt;a href="http://twitter.com/#!/munepixyz/status/100440925175676928"&gt;@munepixyzさんのツイート&lt;/a&gt;で、あるコマンドの挙動を最後の出現のときだけ別なものにしたい、というTeXフォーラムへの質問があったことを知りました。&lt;br /&gt;&lt;br /&gt;最後のコマンド&lt;br /&gt;&lt;a href="http://oku.edu.mie-u.ac.jp/tex/mod/forum/discuss.php?d=691&amp;parent=3733"&gt;http://oku.edu.mie-u.ac.jp/tex/mod/forum/discuss.php?d=691&amp;parent=3733&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;すでに、LaTeXで.auxファイルを使うというお手本のような回答があがっていますが、くだんのコマンドが本文のトップレベル階層にしか出現しない場合には、texコマンドを一回起動するだけで求める動作を実現できます。TeXフォーラムに登録していないため、ここでネタにします。&lt;br /&gt;&lt;br /&gt;いつもは文字列「hoge」を出力し、最後の出現だけは文字列「fuga」を出力するコマンド&lt;code&gt;\hoge&lt;/code&gt;の定義はこれだけです。&lt;pre&gt;\long\def\hoge#1\hoge#2{%&lt;br/&gt;  \ifx#2\end fuga#1#2%&lt;br/&gt;    \else hoge#1\expandafter\hoge#2&lt;br/&gt;  \fi}&lt;/pre&gt;&lt;br /&gt;こんなふうに使います。pdftexを起動してインタプリタに以下を貼り付ければ、最後の&lt;code&gt;\hoge&lt;/code&gt;だけがfugaに置き換わったPDFができあがります。&lt;pre&gt;\hoge \hoge $1+2=3$ \hoge&lt;br/&gt;&lt;br/&gt;\hoge \hoge&lt;br/&gt;&lt;br/&gt;oshimai&lt;br/&gt;% 本文はここまで&lt;br/&gt;&lt;br/&gt;\hoge\end % この行を本文の最後に追記する&lt;br/&gt;\eject&lt;/pre&gt;&lt;br /&gt;&lt;code&gt;\hoge&lt;/code&gt;の定義では、引数を指定する部分が&lt;code&gt;#1\hoge#2&lt;/code&gt;というあまり見慣れない形をしています。これは大雑把に言うと「次に&lt;code&gt;\hoge&lt;/code&gt;が出てくるまでを&lt;code&gt;#1&lt;/code&gt;に、その&lt;code&gt;\hoge&lt;/code&gt;の直後のトークンを&lt;code&gt;#2&lt;/code&gt;に束縛して、定義の本体を実行せよ」という意味です。このように、TeXのマクロでは引数のパターンマッチができる！&lt;br /&gt;&lt;br /&gt;実際には1つのパターンでしか定義できないので、これはパターンマッチでもなんでもないのですが、この「パターンでマクロの引数を取り出す」手法はTeXプログラミングの主要な武器のひとつです。少なくとも私はそうおもっているので、自分でもけっこう使う機会が多いです。これを知ってればlatex.ltxだってもりもり読めるよ。&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-4836224532356270200?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/4836224532356270200/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=4836224532356270200' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/4836224532356270200'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/4836224532356270200'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2011/08/tex.html' title='TeXで「最後のコマンド」だけ挙動を変える（ワンパス版）'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-760659262896897076</id><published>2011-06-19T00:44:00.006+09:00</published><updated>2011-06-19T02:05:43.119+09:00</updated><title type='text'>いかにして私は思い悩むのを止めてcall/ccを便利に使うようになったか</title><content type='html'>call/ccは神秘的です。&lt;code&gt;(call/cc call/cc)&lt;/code&gt; とか、いまだにくらくらします。まあ、ゆっくり考えれば難しいことではないのですが、回答に至るプロセスを即答する自信はありません。しかも、そんな込み入った話なのに、&lt;code&gt;(call/cc call/cc)&lt;/code&gt; なんていう式には実用性のかけらもない。ゼロです。採用面接の問題にはいいかも。Schemerを募集するような会社があるかどうか知りませんが。&lt;br /&gt;&lt;br /&gt;そんなcall/ccの使い道としてよく引き合いに出されるのは大域脱出です。でも、たとえばケント・ディヴィグの教科書の例を見てピンとくる人はいるのでしょうか。引数にゼロがあったら掛け算をやめてジャンプする。ありがたみがまったく感じられない話です。かと思うと、その次の例でいきなり登場するのは「プリエンプティブ・マルチタスクを実装したエンジン」なるもの。わけがわかりません。&lt;br /&gt;&lt;br /&gt;そこで、自分が「call/ccうれしい」と感じられそうな例を考えてみることにしました。大域脱出を強いられる状況を作るので、下準備が少し必要です。&lt;br /&gt;&lt;br /&gt;&lt;hr/&gt;&lt;br /&gt;いま、こんなプロシージャー「&lt;code&gt;&gt;i&gt;&lt;/code&gt;」が欲しいとしましょう。&lt;pre&gt;(&gt;i&gt; 1 10)&lt;br /&gt;=&gt; (1 2 3 4 5 6 7 8 9 10)&lt;/pre&gt;ようするに、整数を2つ与えると間を補完してくれるようなプロシージャーです。&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&gt;i&gt;&lt;/code&gt; そのものを定義するのは簡単です。でも、一歩進んで、こんな具合にメタ定義できるようにすることを考えてみましょう。&lt;pre&gt;(define-range-maker &gt;i&gt; int++)&lt;/pre&gt;ここで、&lt;pre&gt;(define (int++ n)&lt;br /&gt;  (+ n 1))&lt;/pre&gt;です。&lt;br /&gt;&lt;br /&gt;&lt;code&gt;define-range-maker&lt;/code&gt; のほうはマクロとして定義できます。&lt;pre&gt;(define-macro (define-range-maker sym next)&lt;br /&gt;  `(define (,sym from to)&lt;br /&gt;     (let R ((i from) (result '()))&lt;br /&gt;       (if (equal? i to)&lt;br /&gt;           (reverse (cons i result))&lt;br /&gt;           (R (,next i) (cons i result))))))&lt;/pre&gt;&lt;br /&gt;&lt;code&gt;define-range-maker&lt;/code&gt; を使ったので、似たような補完プロシージャーをもりもり作れるようになりました。たとえば、 &lt;code&gt;int++&lt;/code&gt; の文字バージョン &lt;code&gt;char++&lt;/code&gt; を用意すれば、2つの文字の間を補完するプロシージャー &lt;code&gt;&gt;c&gt;&lt;/code&gt; ができます。&lt;pre&gt;(define (char++ c) &lt;br /&gt;  (integer-&gt;char (+ (char-&gt;integer c) 1)))&lt;br /&gt;&lt;br /&gt;(define-range-maker &gt;c&gt; char++)&lt;br /&gt;&lt;br /&gt;(&gt;c&gt; #\a #\k)&lt;br /&gt;=&gt; (#\a #\b #\c #\d #\e #\f #\g #\h #\i #\j #\k)&lt;/pre&gt;pizzaもどうぞ。&lt;pre&gt;(define (kakko++ x)&lt;br /&gt;  (cons x '()))&lt;br /&gt;&lt;br /&gt;(define-range-maker &gt;p&gt; kakko++)&lt;br /&gt;&lt;br /&gt;(&gt;p&gt; '(pizza) '((((pizza)))))&lt;br /&gt;=&gt; ((pizza) ((pizza)) (((pizza))) ((((pizza)))))&lt;/pre&gt;&lt;br /&gt;さて、よく考えたら &lt;code&gt;&gt;i&gt;&lt;/code&gt; も &lt;code&gt;&gt;c&gt;&lt;/code&gt; も &lt;code&gt;&gt;p&gt;&lt;/code&gt; も同じ定義の繰り替えしです。やはりこんな具合にマクロ &lt;code&gt;when&lt;/code&gt; を作ってまとめられないでしょうか？&lt;pre&gt;(define-range-maker &gt;++&gt;&lt;br /&gt;  (when integer? int++&lt;br /&gt;        char?    char++&lt;br /&gt;        list?    kakko++))&lt;/pre&gt;&lt;br /&gt;ぱっと思いつくのは次のような定義でしょう。 &lt;code&gt;define-range-maker&lt;/code&gt; に渡すプロシージャー &lt;code&gt;int++&lt;/code&gt; や &lt;code&gt;char++&lt;/code&gt; がとることになる引数の種類に応じて、当のプロシージャーを返そうという戦法です。&lt;pre&gt;(define-syntax when&lt;br /&gt;  (syntax-rules ()&lt;br /&gt;    ((_ pred proc)&lt;br /&gt;     (lambda (x)&lt;br /&gt;       (if (pred x)&lt;br /&gt;           proc&lt;br /&gt;           (error "unsupported arguments"))))&lt;br /&gt;    ((_ pred1 proc1 pred2 proc2 ...)&lt;br /&gt;     (lambda (x)&lt;br /&gt;       (if (pred1 x)&lt;br /&gt;           proc1&lt;br /&gt;           (when pred2 proc2 ...))))))&lt;/pre&gt;しかし、これではうまくいきません。 &lt;code&gt;define-range-maker&lt;/code&gt; には「自分への引数を調べてプロシージャーを返そうとするプロシージャー」が渡されることになるのですが、 &lt;code&gt;define-range-maker&lt;/code&gt; はそんなものを求めていないからです。 &lt;code&gt;define-range-maker&lt;/code&gt; が求めているのは、あくまでも、そのプロシージャーが返そうとしているプロシージャーのほうです。&lt;br /&gt;&lt;br /&gt;こんなとき &lt;code&gt;call/cc&lt;/code&gt; が使えます。「自分への引数を調べてプロシージャーを返そうとするプロシージャー」のことは忘れて、当のプロシージャーを返すようにしましょう。&lt;pre&gt;(define-syntax when&lt;br /&gt;  (syntax-rules ()&lt;br /&gt;    ((_ pred proc)&lt;br /&gt;     (call/cc&lt;br /&gt;      (lambda (k)&lt;br /&gt;        (lambda (x)&lt;br /&gt;          (if (pred x)&lt;br /&gt;              (k proc)&lt;br /&gt;              (error "unsupported arguments"))))))&lt;br /&gt;    ((_ pred1 proc1 pred2 proc2 ...)&lt;br /&gt;     (call/cc&lt;br /&gt;      (lambda (k)&lt;br /&gt;        (lambda (x)&lt;br /&gt;          (if (pred1 x)&lt;br /&gt;              (k proc1)&lt;br /&gt;              (k (when pred2 proc2 ...)))))))))&lt;/pre&gt;これでうまくいきます。&lt;pre&gt;(define-range-maker &gt;++&gt;&lt;br /&gt;  (when integer? int++&lt;br /&gt;        char?    char++&lt;br /&gt;        list?    kakko++))&lt;br /&gt;&lt;br /&gt;(&gt;++&gt; '(coffee) '(((((coffee))))))&lt;br /&gt;=&gt; ((coffee) ((coffee)) (((coffee))) ((((coffee)))) (((((coffee))))))&lt;/pre&gt;&lt;br /&gt;DSLを作るようなときはマクロなどでメタな階層を積み重ねていくことが多々あると思うのですが、そんなとき、下層に潜らないと見えない条件に基づいて上層の機能をスイッチするのに &lt;code&gt;call/cc&lt;/code&gt; はなかなか便利です。 &lt;code&gt;call/cc&lt;/code&gt; なんて使わずに済ませることもできるのでしょうが、こんなふうに便利に使えることもあるので、ぜひみんな『Scheme修行』を読んで「なあんだ」と実感しておきましょう。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://ssl.ohmsha.co.jp/cgi-bin/menu.cgi?ISBN=978-4-274-06853-9"&gt;&lt;image src="http://ssl.ohmsha.co.jp/imgm/978-4-274-06853-9.gif"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://ssl.ohmsha.co.jp/cgi-bin/menu.cgi?ISBN=978-4-274-06853-9"&gt;『Scheme修行』&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;ちなみに、この『Scheme修行』の制作にも使っている&lt;a href="https://github.com/k16shikano/xml2tex/blob/master/sample/sample.xml"&gt;xml2tex.scm&lt;/a&gt;（名前とは裏腹に、変換のためのスクリプトというよりは変換を定義するためのスクリプト）でも、ここで紹介したのとまったく同じ方法でcall/ccを利用しています。というか、それを説明用の例として書き直したのがこの記事の &lt;code&gt;when&lt;/code&gt; マクロでした。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-760659262896897076?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/760659262896897076/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=760659262896897076' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/760659262896897076'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/760659262896897076'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2011/06/callcc.html' title='いかにして私は思い悩むのを止めてcall/ccを便利に使うようになったか'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-141315940152053496</id><published>2011-03-03T13:24:00.006+09:00</published><updated>2011-03-04T09:07:52.166+09:00</updated><title type='text'>drop して take すればリストに窓が開く</title><content type='html'>激しく時代遅れな話題ですが……&lt;br /&gt;&lt;blockquote&gt;[1,2,3,4,5] が与えられたとき [[1,2][2,3][3,4][4,5]] を返すような関数を定義せよ&lt;br /&gt;&lt;a href="http://valvallow.blogspot.com/2011/02/12345-12233445.html"&gt;http://valvallow.blogspot.com/2011/02/12345-12233445.html&lt;/a&gt;&lt;/blockquote&gt;&lt;br /&gt;これは、窓をガラガラっと動かしながらリストを覗く、という問題です。ようするに、こういう話（&lt;i&gt;n&lt;/i&gt; = 3 の場合）。&lt;pre&gt;&lt;font color="#cccccc"&gt;            &lt;font face="bold" color="#000000"&gt;1 2 3&lt;/font&gt; 4 5 6 7 8 9&lt;br /&gt;        1 2 &lt;font face="bold" color="#000000"&gt;3 4 5&lt;/font&gt; 6 7 8 9&lt;br /&gt;    1 2 3 4 &lt;font face="bold" color="#000000"&gt;5 6 7&lt;/font&gt; 8 9&lt;br /&gt;1 2 3 4 5 6 &lt;font face="bold" color="#000000"&gt;7 8 9&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;リストに窓を作るには、drop して take するのが簡単です。窓をガラガラっと動かすほうは、この問題の場合にはリストを作ることになっているので、unfold 系の高階関数を使えばよいでしょう。Scheme よりすっきり書けるので Haskell で書きます。&lt;pre&gt;import Data.List (unfoldr)&lt;br /&gt;&lt;br /&gt;overlaps n ls = unfoldr (window n) ls&lt;br /&gt;&lt;br /&gt;window          :: Int -&gt; [a] -&gt; Maybe ([a], [a])&lt;br /&gt;window 1 _      =  Nothing&lt;br /&gt;window _ []     =  Nothing&lt;br /&gt;window _ (x:[]) =  Nothing&lt;br /&gt;window n ls     =  Just (take n ls, drop (n-1) ls)&lt;/pre&gt;drop の引数が n-1 なのは、窓をガラガラっとする前と後で隙間が要素1つぶんだけ重なっているという問題だからです。&lt;br /&gt;&lt;br /&gt;Scheme も SRFI-1 に &lt;code&gt;unfold&lt;/code&gt; があるので、ほぼ同じように「窓をガラガラっ」（drop して take した window を unfold）という気分で書けます。Gaucheだと、リストの長さの制限がゆるいバージョンの take や drop が用意されているし（&lt;code&gt;take*&lt;/code&gt; と &lt;code&gt;drop*&lt;/code&gt;。util.list を使う）、&lt;s&gt;いつのころからか unfold も組み込まれているので（最近知った&lt;/s&gt;unfold組み込みはうそでした。すみません）、なおよい。&lt;pre&gt;(use util.list)&lt;br /&gt;(define (overlaps ls n)&lt;br /&gt;  (unfold exhaust? (take$ n) (drop$ (sub n)) ls))&lt;br /&gt;&lt;br /&gt;(define (sub n) (max 1 (- n 1))&lt;br /&gt;(define (exhaust? ls) (or (null? ls) (null? (cdr ls))))&lt;br /&gt;(define (take$ n) (cut take* &lt;&gt; n))&lt;br /&gt;(define (drop$ n) (cut drop* &lt;&gt; n))&lt;/pre&gt;結果として、&lt;a href="http://d.hatena.ne.jp/podhmo/20110228/1298900054"&gt;podhmoの日記&lt;/a&gt; と同じ答になりました。&lt;br /&gt;&lt;br /&gt;そういえば、どうして Scheme の take や drop は、リストでなく整数が最後の引数になっているんだろう…？&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-141315940152053496?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/141315940152053496/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=141315940152053496' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/141315940152053496'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/141315940152053496'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2011/03/drop-take.html' title='drop して take すればリストに窓が開く'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-1132461906010808842</id><published>2011-01-26T22:54:00.000+09:00</published><updated>2011-01-26T23:04:56.813+09:00</updated><title type='text'>TeX で Brainfuck</title><content type='html'>TeX というプログラミング言語があります。配列とループがないのが特徴です。配列とループがなくて困ることはあまりありませんが、その数少ない困る場面が、プログラミング言語 &lt;a href="http://en.wikipedia.org/wiki/Brainfuck"&gt;Brainfuck&lt;/a&gt; の実装でしょう。&lt;a href="http://ja.wikipedia.org/wiki/Brainfuck"&gt;Wikipedia の記事&lt;/a&gt;を読む限り、バイト型の配列とそれを指し示すポインタ、それに while ループさえあれば、Brainfuck は簡単に実装できそうです。&lt;br /&gt;&lt;br /&gt;しかし、ないものはないので、別の手段を考えます。ぱっと思いつく配列の実現手段は TeX のレジスタです。レジスタには、ある種のトークンやトークン列を一時的に保存できます。ちなみにトークンというのは TeX の入力の最小単位で、文字や整数のほか、グループ（&lt;code&gt;{...}&lt;/code&gt; でくくられたもの）やコントロールシーケンス（&lt;code&gt;\foo&lt;/code&gt; のようないわゆる TeX コマンド）も 1つのトークンです。&lt;br /&gt;&lt;br /&gt;レジスタにはいろいろな種類があるのですが、個々のレジスタには「種類 + 番号」のような名前が付いています。たとえば整数用のレジスタなら、&lt;code&gt;\count0&lt;/code&gt;、 &lt;code&gt;\count1&lt;/code&gt;、 &lt;code&gt;\count2&lt;/code&gt;、... といった具合です。この整数値を格納できるタイプのレジスタを使えば、番号をインデックスに見立てることで、バイト型の配列的なものが実現できますね。ただ、このインデックスの値をプログラムで足したり引いたりするには、やはりレジスタに収めるしかありません。インデックスは整数なので、整数用のレジスタが余分に 1個必要です。&lt;code&gt;\count0&lt;/code&gt; レジスタを割り当てましょう。&lt;pre&gt;%% init&lt;br /&gt;\countdef\pointer=0&lt;br /&gt;\def\init#1{%&lt;br /&gt; \count0=0&lt;br /&gt; \loop \advance\count0 by 1 \global\count\count0=0 \ifnum\count0&lt;#1 \repeat&lt;br /&gt; \global\pointer=1}&lt;/pre&gt;&lt;code&gt;\init{255}&lt;/code&gt; とすることで、長さ 255 の配列がゼロに初期化されます。&lt;br /&gt;&lt;br /&gt;あとは Brainfuck の仕様に従って処理を実装します。&lt;code&gt;\run{...}&lt;/code&gt; で Brainfuck のプログラムが実行されるようにしましょう。&lt;pre&gt;%% run bf program&lt;br /&gt;\long\def\run#1{%&lt;br /&gt; \init{255}&lt;br /&gt; \apply#1!\relax}&lt;br /&gt;&lt;br /&gt;%% applying each bf command&lt;br /&gt;\def\apply#1{%&lt;br /&gt; \let\next=\apply&lt;br /&gt; \if#1&gt;\increment\else&lt;br /&gt; \if#1&lt;\decrement\else&lt;br /&gt; \if#1+\incrementp\else&lt;br /&gt; \if#1-\decrementp\else&lt;br /&gt; \if#1.\putbyte\else&lt;br /&gt; \if#1,\getbyte\else&lt;br /&gt; \if#1!\let\next=\relax\else&lt;br /&gt;   \dowhile{#1}\let\next=\apply&lt;br /&gt; \fi\fi\fi\fi\fi\fi\fi&lt;br /&gt; \next}&lt;/pre&gt;&lt;code&gt;\apply&lt;/code&gt; は、トークンを 1つ取り込み、その種類に応じてインデックスを動かしたり整数レジスタの値を増減したりします。これをトークンがなくなるまで繰り返します。&lt;br /&gt;&lt;br /&gt;繰り返し処理がややトリッキーに見えるかもしれませんが、ループのための便利な構文もないし、末尾最適化もしてくれないので、自分で末尾再帰するように書くしかないからです。まあ、なんのことはなくて、次の処理を &lt;code&gt;\next&lt;/code&gt; に &lt;code&gt;\let&lt;/code&gt; して &lt;code&gt;\next&lt;/code&gt; を最後に置けばいいのですが、たとえば再帰するつもりで各 &lt;code&gt;\if&lt;/code&gt; 文の中に &lt;code&gt;\apply&lt;/code&gt; や &lt;code&gt;\relax&lt;/code&gt; を直接置いてしまうと、メモリがうまって止まります。TeXのコマンドは実行時に評価されるわけではなく、定義に書いてあるトークンの列に置き換えられるだけなので、 &lt;code&gt;\apply&lt;/code&gt; の素の定義がばらばらばらっと無限に繰り返し展開されてしまうからです。実は TeX の動作というのは、徹頭徹尾「トークンを置き換える」だけであり、この置き換えのルールやタイミングをうまく与えることが TeX プログラミングにほかなりません。&lt;br /&gt;&lt;br /&gt;&lt;code&gt;\dowhile&lt;/code&gt; 以外の各処理を実装しましょう。入出力がやや面倒ですが、ほかは素直に書けます。&lt;pre&gt;\def\increment{%&lt;br /&gt; \global\advance\pointer by 1}&lt;br /&gt;\def\decrement{%&lt;br /&gt; \global\advance\pointer by -1}&lt;br /&gt;\def\incrementp{%&lt;br /&gt; \global\advance\count\pointer by 1}&lt;br /&gt;\def\decrementp{%&lt;br /&gt; \global\advance\count\pointer by -1}&lt;br /&gt;\def\putbyte{%&lt;br /&gt; \ifnum\count\pointer&lt;256&lt;br /&gt;   \char\count\pointer\fi}&lt;br /&gt;\def\getbyte{%&lt;br /&gt; \read 16 to \getchar&lt;br /&gt; \ifx\end\getchar\else&lt;br /&gt;   \global\count\pointer=\getchar\fi}&lt;/pre&gt;残るは &lt;code&gt;\dowhile&lt;/code&gt; ですが、これだけは正直てこずりました。前述のように TeX はトークンを次々に置き換えていくだけなので、簡単には前に戻れない。整数レジスタを使って対応する閉じ括弧 &lt;code&gt;]&lt;/code&gt; を探すことは簡単にできますが、そこまでのトークンをどこかに保持しておいて &lt;code&gt;\apply&lt;/code&gt; の引数として渡すといった処理ができない。週末、子供と科学博物館にいったりレゴでアンモナイトを作ったりしてあげている間、ずっと考えてました。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/k16/5389198971/" title="アンモナイト LEGO by Keiichirou Shikano, on Flickr"&gt;&lt;img src="http://farm6.static.flickr.com/5259/5389198971_9efca5e918_m.jpg" width="240" height="180" alt="アンモナイト LEGO" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;で、最終的に思いついたのが、 &lt;code&gt;[&lt;/code&gt; と &lt;code&gt;]&lt;/code&gt; の &lt;code&gt;\catcode&lt;/code&gt; を変更して TeX の字句解析をだます方法。 TeX は対応する &lt;code&gt;{...}&lt;/code&gt; で囲まれた部分を 1つのトークンとして読み込むのですが、 Brainfuck の &lt;code&gt;[...]&lt;/code&gt; を TeX のグループであるかのように読み込んでしまえば、対応する括弧で囲まれた部分を取り出すという問題そのものが消滅する！&lt;pre&gt;\catcode`\[=1&lt;br /&gt;\catcode`\]=2&lt;br /&gt;&lt;br /&gt;%% [ and ] (while loop)&lt;br /&gt;\newif\ifinnerloop&lt;br /&gt;&lt;br /&gt;\def\dowhile#1{%&lt;br /&gt; \ifnum\count\pointer=0 \relax\else&lt;br /&gt;   \loop {\apply#1!}%&lt;br /&gt;     \ifnum\count\pointer=0 \innerloopfalse\else\innerlooptrue\fi&lt;br /&gt;     \ifinnerloop&lt;br /&gt;   \repeat&lt;br /&gt; \fi}&lt;/pre&gt;そんなわけで、たぶん &lt;a href="https://github.com/k16shikano/Brainfuck-TeX/blob/master/brainfuck.tex"&gt;Brainfuck っぽいもの&lt;/a&gt;ができました。とりあえず Wikipedia にあった Hello World! はうごく。&lt;pre&gt;&lt;br /&gt;\run{&lt;br /&gt;++++++++++[&gt;+++++++&gt;++++++++++&gt;+++&gt;+&lt;&lt;&lt;&lt;-]&lt;br /&gt;&gt;++.&gt;+.+++++++..+++.&gt;++.&lt;br /&gt;&lt;&lt;+++++++++++++++.&gt;.+++.------.--------.&gt;+.&gt;.&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;=&gt; Hello'World!Ω&lt;/pre&gt;入れ子の括弧も大丈夫。以下は、今回おおいに参考にさせていただいた &lt;a href="http://www.kmonos.net/alang/etc/brainfuck.php"&gt;k.inaba さんのページ&lt;/a&gt;から、掛け算の例。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;\run{&lt;br /&gt;++++&gt;++&gt;&lt;&lt;&lt;br /&gt;[-&lt;br /&gt;  &gt;[-&gt;&gt;+&lt;&lt;]&lt;br /&gt;  &gt;&gt;[-&lt;+&lt;+&gt;&gt;]&lt;br /&gt;  &lt;&lt;&lt;&lt;br /&gt;]&gt;&gt;&lt;br /&gt;++++++++++++++++++++++++++++++++++++++++++++++++.&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;=&gt; 8&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;hr&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;FAQ&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;・&lt;/b&gt;「むしろ TeX が brainfucking です。」&lt;br /&gt;&lt;br /&gt;クヌース先生に言ってください。しかし、もしかするとあなたが brainfucking だと思っているのは、 TeX ではなく LaTeX のスタイルのほうではないでしょうか。あれは実際、brainfucking です。ドキュメントの見た目を制御するときにワケワカなのと、プログラミングがワケワカなのは、違う話です。スタイルとか気にしないで素の TeX プログラミングをするだけなら楽しいですよ。&lt;br /&gt;&lt;br /&gt;&lt;b&gt;・&lt;/b&gt;「Hello World! に &lt;code&gt;'&lt;/code&gt; とか &lt;code&gt;Ω&lt;/code&gt; とかゴミが出てるけど？」&lt;br /&gt;&lt;br /&gt;TeX のデフォルトのテキストフォント cmr10 で、それぞれASCIIコードの 32 と 10 に割り当てられているグリフ（を再現したもの）です。&lt;br /&gt;&lt;br /&gt;&lt;b&gt;・&lt;/b&gt;「入力のある Brainfuck プログラムから抜けられない」&lt;br /&gt;&lt;br /&gt;&lt;code&gt;\end&lt;/code&gt; と入力して、&lt;code&gt;?&lt;/code&gt; とプロンプトが出たらリターンを押してください。運がよければエラーは出るものの dvi が生成されます。エラーは if 文が閉じてないとかそういうたぐいで、このエラーなしに再帰的なマクロを途中で抜ける方法を私は知りません。&lt;br /&gt;&lt;br /&gt;&lt;b&gt;・&lt;/b&gt;「&lt;a href="http://esoteric.sange.fi/brainfuck/"&gt;The Brainfuck Archive&lt;/a&gt; のコードに動かないのがある」&lt;br /&gt;&lt;br /&gt;そうですね。&lt;br /&gt;&lt;br /&gt;実は 1つごまかしているところがあります。この実装は、 &lt;code&gt;[...]&lt;/code&gt; の内側にコマンドが 1つしかない場合に対応していません。たとえば &lt;code&gt;[-]&lt;/code&gt; と &lt;code&gt;-&lt;/code&gt; を区別できないのです。これは &lt;code&gt;[...]&lt;/code&gt; を TeX のグループとして読み込んでいることによる制限です。とはいえ、&lt;code&gt;[-]&lt;/code&gt; としたい場面で &lt;code&gt;[&lt;&gt;-]&lt;/code&gt; などと書くことにすれば、この制限を回避して等価なコードが記述できます。動作しない Brainfuck プログラムも、そんなふうに改修すれば動くかもしれません。&lt;br /&gt;&lt;br /&gt;あと、制限としてはもうひとつ、配列の最大長が 255 です。これは TeX のレジスタが 256 個しかないからです（LuaTeX のような最近の実装を使えば 65535 とかまでいける）。上記のサイトのサンプルはかなり大がかりなものも多いので、この制限にひっかかって動かないものがけっこうありそう。&lt;br /&gt;&lt;br /&gt;さらに言い訳が続きますが、上記のサイトのコード例で計算をする系のものには、出力結果を ASCII にしてないものがあるようです。そういうのは DVI や PDF にしたときに文字化けします。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-1132461906010808842?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/1132461906010808842/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=1132461906010808842' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/1132461906010808842'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/1132461906010808842'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2011/01/tex-brainfuck.html' title='TeX で Brainfuck'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm6.static.flickr.com/5259/5389198971_9efca5e918_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-6556604050782549486</id><published>2010-12-23T22:19:00.003+09:00</published><updated>2010-12-23T22:55:20.782+09:00</updated><title type='text'>2011年賀状</title><content type='html'>年賀状書いた。&lt;pre&gt;%!&lt;br /&gt;&lt;&lt; /PageSize [285 420] &gt;&gt; setpagedevice&lt;br /&gt;&lt;br /&gt;/ellipse { % def&lt;br /&gt;   /c 2 index def&lt;br /&gt;   { % for&lt;br /&gt;       /t exch def&lt;br /&gt;       /r1 {rand 4 mod 2 div} def&lt;br /&gt;       /r2 {rand 2 mod 2 div} def&lt;br /&gt;       /r3 {rand 2 mod 2 div} def&lt;br /&gt;&lt;br /&gt;       newpath&lt;br /&gt;       gsave&lt;br /&gt;         65 190 moveto&lt;br /&gt;         /x 70 t cos mul def&lt;br /&gt;         /y 220 t sin mul def&lt;br /&gt;         x y rmoveto&lt;br /&gt;         /xscale 2.0 t cos add 20 mul def&lt;br /&gt;         /yscale 1.0 t cos add 30 mul def&lt;br /&gt;         /FireFightBB findfont [xscale 20 20 yscale 0 0] makefont setfont&lt;br /&gt;         (2011) true charpath clip&lt;br /&gt;&lt;br /&gt;         newpath&lt;br /&gt;         0 70 490 { % for&lt;br /&gt;             /i exch def&lt;br /&gt;             gsave&lt;br /&gt;               100 190 translate&lt;br /&gt;               70 setlinewidth&lt;br /&gt;               r1 r2 r3 setrgbcolor&lt;br /&gt;               .5 1 scale 0 0 i 70 add 0 360 arc stroke&lt;br /&gt;             grestore&lt;br /&gt;         } for&lt;br /&gt;       grestore&lt;br /&gt;   } for&lt;br /&gt;} def&lt;br /&gt;&lt;br /&gt;1 1 20 {&lt;br /&gt;    /n exch def&lt;br /&gt;&lt;br /&gt;    0 12 360 ellipse&lt;br /&gt;    102 6 258 ellipse % for dense farside&lt;br /&gt;&lt;br /&gt;    240 25 moveto&lt;br /&gt;    /Georgia-Bold findfont 10 scalefont setfont&lt;br /&gt;    n =string cvs show&lt;br /&gt;    (/20) show&lt;br /&gt;    showpage &lt;br /&gt;} for&lt;/pre&gt;書いたものの、肝心の年賀状がなかったので、とりあえずテスト印刷だけ。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/k16/5285644182/" title="IMAG0145.jpg by Keiichirou Shikano, on Flickr"&gt;&lt;img src="http://farm6.static.flickr.com/5085/5285644182_50fed48392.jpg" width="500" height="375" alt="IMAG0145.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;今年は&lt;a href="http://www.1001freefonts.com/FireFight.php"&gt;Fire Fight&lt;/a&gt;というフォントを使わせていただきました。文字のレイアウトはあっさり決定したけど、色づけとフォント選びが悩ましかった。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-6556604050782549486?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/6556604050782549486/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=6556604050782549486' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/6556604050782549486'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/6556604050782549486'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2010/12/2011.html' title='2011年賀状'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm6.static.flickr.com/5085/5285644182_50fed48392_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-981243833543091832</id><published>2010-12-20T16:30:00.006+09:00</published><updated>2010-12-21T09:16:16.417+09:00</updated><title type='text'>プログラミングのための確率統計 in Haskell</title><content type='html'>まっとうなサイコロをふったときに出る目の確率は、こんな表にまとめられます。&lt;br /&gt;&lt;table style="border-collapse:collapse;text-align:center;"&gt;&lt;tr&gt;&lt;td style="border:solid 1pt"&gt;目の値&lt;/td&gt;&lt;td style="border:solid 1pt"&gt;1&lt;/td&gt;&lt;td style="border:solid 1pt"&gt;2&lt;/td&gt;&lt;td style="border:solid 1pt"&gt;3&lt;/td&gt;&lt;td style="border:solid 1pt"&gt;4&lt;/td&gt;&lt;td style="border:solid 1pt"&gt;5&lt;/td&gt;&lt;td style="border:solid 1pt"&gt;6&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;td style="border:solid 1pt"&gt;確率&lt;/td&gt;&lt;td style="border:solid 1pt"&gt;1/6&lt;/td&gt;&lt;td style="border:solid 1pt"&gt;1/6&lt;/td&gt;&lt;td style="border:solid 1pt"&gt;1/6&lt;/td&gt;&lt;td style="border:solid 1pt"&gt;1/6&lt;/td&gt;&lt;td style="border:solid 1pt"&gt;1/6&lt;/td&gt;&lt;td style="border:solid 1pt"&gt;1/6&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;こんな表のことを確率分布といいます。サイコロをふったときに起こるイベントの確率、たとえば「偶数の目が出る」確率を調べることは、この確率分布からこんな別の確率分布への変換だと考えられます。&lt;br /&gt;&lt;br /&gt;&lt;table style="border-collapse:collapse;text-align:center;"&gt;&lt;tr&gt;&lt;td style="border:solid 1pt"&gt;目の値&lt;/td&gt;&lt;td style="border:solid 1pt"&gt;2,4,6（偶数）&lt;/td&gt;&lt;td style="border:solid 1pt"&gt;1,3,5（奇数）&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="border:solid 1pt"&gt;確率&lt;/td&gt;&lt;td style="border:solid 1pt"&gt;1/2&lt;/td&gt;&lt;td style="border:solid 1pt"&gt;1/2&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;この変換は、具体的にはこんな対応です。&lt;blockquote&gt;P(偶数) = P(2) + P(4) + P(6)&lt;br /&gt;P(奇数) = P(1) + P(3) + P(5)&lt;/blockquote&gt;P(X)がイベントXに対する確率を表しているわけですが、Pを「イベントの集合から[0,1]区間の実数への関数」だとみなすこともできます。確率分布から確率分布への変換は、関数に対する演算でもあるわけです。確率分布を連想リストで表せば、高階関数や代数型を使って、この変換をモデル化できそうです。&lt;br /&gt;&lt;br /&gt;以前、このアイデアを&lt;a href="http://note.golden-lucky.net/2005/12/2-905086-wikipedia-examples-of-markov.html"&gt;Scheme&lt;/a&gt;で試してみたことがありました。当時は、そもそも確率についての理解が今よりもいっそうあやしかったし、実装もちゃちでしたが、このアイデアが特別なものでなかったことを最近になって知りました。その名も&lt;a href="http://web.engr.oregonstate.edu/~erwig/pfp/"&gt;確率的関数プログラミング（Probabilistic Functional Programming）&lt;/a&gt;。PFPと呼ばれているようです。Haskellのライブラリが公開されているので、これで遊んでみます。&lt;br /&gt;&lt;br /&gt;&lt;hr&gt;&lt;br /&gt;PFPでは、確率と確率分布をだいたいこんな感じに定義しています。&lt;pre&gt;newtype Probabillity = P Float&lt;br /&gt;Dist a = D [(a, Probability)]&lt;/pre&gt;確率分布（Probabilistic Distribution）は連想リスト以外のなにものでもありません。&lt;br /&gt;&lt;br /&gt;さっそく例題をといてみましょう。次のような確率の問題を考えます。どこかで見たことがあるような問題ですね :)&lt;br /&gt;&lt;blockquote style="background-color:#E0FFFF;"&gt;とあるロールプレイングゲームではモンスターを倒すと宝箱が得られます。その宝箱には確率 2/3 で罠がかかっています。罠の気配は魔法で判定できますが、この判定は完璧ではなく、確率 1/10 で間違った判定結果がでてしまいます。&lt;ul&gt;&lt;li&gt;問題1. モンスターを倒して得た宝箱に魔法をかけたとき気配なしと判定される確率は？&lt;/li&gt;&lt;li&gt;問題2. 魔法をかけたら気配なしと判定された。このとき本当は罠がかかっている確率は？&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;なにはともあれ、宝箱をあらわす型を用意します。宝箱は、罠がかかっているか、安全か。&lt;pre&gt;data TreasureBox = Trap | Safe&lt;/pre&gt;問題文を読むと、2つの確率分布があたえられていることがわかります。罠がかかっている確率をあらわす分布と、判定魔法の結果をあらわす確率分布です。PFPには、イベントを列挙したリストと、それに対応する確率を列挙したリストとから確率分布を生成するための関数&lt;code&gt;enum&lt;/code&gt;が用意されているので、これを使います。&lt;pre&gt;treasureOfMonster   :: TreasureBox -&gt; Dist TreasureBox&lt;br /&gt;treasureOfMonster _ =  enum [2/3, 1/3] [Trap, Safe]&lt;br /&gt;&lt;br /&gt;magicSpell      :: TreasureBox -&gt; Dist TreasureBox&lt;br /&gt;magicSpell Safe =  enum [1/10, 9/10] [Trap, Safe]&lt;br /&gt;magicSpell Trap =  enum [1/10, 9/10] [Safe, Trap]&lt;/pre&gt;いずれの関数も、引数として受け取るのは目の前にある宝箱です。目の前にある宝箱は、それがモンスターから得た&lt;code&gt;treasureOfMonster&lt;/code&gt;であれば、とにかく 2/3 で罠がかかっています。その宝箱に&lt;code&gt;magicSpell&lt;/code&gt;をかけると、罠がかかっていなくても 10回に 1回は罠がかかっていると判定してしまうし、逆に 10回に 1回は罠がかかっているのに安全だと判定してしまいます。&lt;br /&gt;&lt;br /&gt;では、目の前にある&lt;code&gt;treasureOfMonster&lt;/code&gt;な宝箱に&lt;code&gt;magicSpell&lt;/code&gt;をかけてみましょう。2つの確率分布を組み合わせればいいのですが、&lt;code&gt;magicSpell&lt;/code&gt;の結果は、とうぜん、&lt;code&gt;treasureOfMonster&lt;/code&gt;な宝箱に罠がかかっているかどうかで変化します。分布Bが分布Aに依存するというなら、分布Bそのものではなく、Aから分布Bへの関数を組み合わせればいい。つまり、&lt;code&gt;Dist&lt;/code&gt;がモナドであればいいということです。実際、PFPではそのように実装されています。だから、こんなふうにすれば、モンスターの宝箱を魔法で調べた結果の確率分布が得られます。&lt;pre&gt;check     :: TreasureBox -&gt; Dist TreasureBox&lt;br /&gt;check box =  treasureOfMonster box &gt;&gt;= magicSpell&lt;/pre&gt;試してみましょう。宝箱はなんでもいいので、&lt;code&gt;undefined&lt;/code&gt;を与えておきます。&lt;pre&gt;&lt;font color="blue"&gt;*RPG&gt;&lt;/font&gt; &lt;b&gt;check undefined&lt;/b&gt;&lt;br /&gt;Trap  63.3%&lt;br /&gt;Safe  36.7%&lt;/pre&gt;問題1の答は 36.7% だとわかりました。本来の安全な確率である 1/3 より若干多い値であることから、誤判定で罠を見抜けない危険性のほうが、罠がないのに罠があると間違えてしまう可能性よりも影響が大きいようです。&lt;br /&gt;&lt;br /&gt;問題2に答えるために、罠がかかっているのに罠がないと判定してしまって死に至る確率を考えてみましょう。そのような事態はこんな演算として表せます。&lt;pre&gt;death           :: TreasureBox -&gt; TreasureBox -&gt; TreasureBox&lt;br /&gt;death Safe Trap =  Trap&lt;br /&gt;death _    _    =  Safe&lt;/pre&gt;&lt;code&gt;magicSpell&lt;/code&gt;の結果と&lt;code&gt;treasureOfMonster&lt;/code&gt;の結果のそれぞれに対して、この&lt;code&gt;death&lt;/code&gt;演算を適用すれば、その一覧から死に至る確率がわかるでしょう。PFPでは、このような操作のために、&lt;code&gt;joinWith :: (a -&gt; b -&gt; c) -&gt; Dist a -&gt; Dist b -&gt; Dist c&lt;/code&gt;という関数が用意されています。&lt;pre&gt;dead     :: TreasureBox -&gt; Dist TreasureBox&lt;br /&gt;dead box =  joinWith death (magicSpell Trap) (treasureOfMonster box)&lt;/pre&gt;&lt;code&gt;magicSpell&lt;/code&gt;に与えている引数が&lt;code&gt;Trap&lt;/code&gt;なのは、ここで気にしている状況が「目の前にある宝箱に実際には罠がかかっている」場合だからです。ただ、魔法をかけるほうからすると、目の前にある宝箱が&lt;code&gt;dead&lt;/code&gt;か否かはわかりません。&lt;code&gt;dead&lt;/code&gt;で評価する宝箱は&lt;code&gt;undefined&lt;/code&gt;です。&lt;pre&gt;&lt;font color="blue"&gt;*RPG&gt;&lt;/font&gt; &lt;b&gt;dead undefined&lt;/b&gt;&lt;br /&gt;Safe  93.3%&lt;br /&gt;Trap   6.7%&lt;/pre&gt;宝箱を前にして&lt;code&gt;magicSpell&lt;/code&gt;による判定結果を盲信するというポリシーをつらぬくと、6.7%の確率で死んでしまうようです。&lt;br /&gt;&lt;br /&gt;さて、問題2に戻りましょう。知りたいのは、&lt;code&gt;magicSpell&lt;/code&gt;の判定結果で安全と出たときに、実際には罠がかかっていて死を招いてしまう確率です。これは、いわゆる条件つき確率の問題なので、教科書的には Bayesの公式で解く場面です。しかし、すでに「判定結果で安全と出る確率」も「死に至る確率」もわかっているので、これらの比率を求めれば答が得られます。&lt;pre&gt;guessedSafeButTrap :: Probability&lt;br /&gt;guessedSafeButTrap =  (==Trap) ?? dead undefined |/ (==Safe) ?? check undefined&lt;br /&gt;&lt;br /&gt;infix 7 |/&lt;br /&gt;(|/)              :: Probability -&gt; Probability -&gt; Probability&lt;br /&gt;(|/) (P p) (P p') =  P $ p/p'&lt;/pre&gt;&lt;code&gt;(??)&lt;/code&gt;は、PFPに用意されている「確率分布からイベントの確率を求める」関数で、&lt;code&gt;Event a -&gt; Dist a -&gt; Probability&lt;/code&gt;という型を持ちます。&lt;code&gt;(|/)&lt;/code&gt;は、&lt;code&gt;Probability&lt;/code&gt;型同士の確率の値について割り算をするために定義しました。&lt;code&gt;infix&lt;/code&gt;を7にしたのは、&lt;code&gt;??&lt;/code&gt;の&lt;code&gt;infix&lt;/code&gt;が8だからです。&lt;br /&gt;&lt;br /&gt;コンパイルして評価すれば問題2の答がわかります。&lt;pre&gt;&lt;font color="blue"&gt;*RPG&gt;&lt;/font&gt; &lt;b&gt;guessedSafeButTrap&lt;/b&gt;&lt;br /&gt;18.2%&lt;/pre&gt;安全だという判定が出ても、誤判定が 1/10 もあると、まだまだ気を抜けないようです。&lt;br /&gt;&lt;br /&gt;（PFPのソースをのぞくと conditional probability というコメントのついた関数&lt;code&gt;(|||) :: Dist a -&gt; Event a -&gt; Dist a&lt;/code&gt;があって、いかにも条件つき確率の計算に使えそうだけど、確率分布からイベントの確率をfilterするようにしか見えない。そんな型で大丈夫か？）&lt;br /&gt;&lt;br /&gt;&lt;hr&gt;&lt;br /&gt;まとめ&lt;br /&gt;&lt;br /&gt;HaskellとPFPを使うことで、確率の問題をうまく抽象化してエレガントに回答を導くことができます。そしてこの抽象化は、Haskellという言語の機能によるものではなく、確率論という数学によるものです。PFPにしても、特別なHaskellの機能はほとんど使っていないように思います（PFPには確率過程をシミュレーションする機能もあって、そちらはもしかしたら高度なHaskellの機能が満載かも）。そんな数学における抽象化をダイレクトにコードで使えることがHaskellの魅力のひとつなのはいわずもがな。&lt;br /&gt;&lt;br /&gt;数学では、抽象化が漏れて台無しにならないように、厳密な論証や独特の表記を使います。そのため、数学による問題の抽象化を利用するには、少し勉強や訓練が必要です。とくに確率論は、漏れがないように抽象化された理論（公理的確率論とか呼ばれます）を勉強しようと思うと、高校までの数学経験だけではつまずいてしまう教材が多い。多少の漏れを棚に上げた感覚的な確率の話をもって「確率論」という教材もあって、それはそれでおもしろいとは思うのですが、抽象化の道具として使うにはちょっとねえ。&lt;br /&gt;&lt;br /&gt;そこでおすすめの教科書はこれ。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://ssl.ohmsha.co.jp/cgi-bin/menu.cgi?ISBN=978-4-274-06775-4"&gt;&lt;image src="http://ssl.ohmsha.co.jp/imgm/978-4-274-06775-4.gif"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://ssl.ohmsha.co.jp/cgi-bin/menu.cgi?ISBN=978-4-274-06775-4"&gt;『プログラミングのための確率統計』&lt;/a&gt;&lt;br /&gt;&lt;a href="http://estore.ohmsha.co.jp/titles/978427406775P"&gt;PDFでも買えます&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;ここまで読んだ貴徳な方なら、この記事の例題が『プログラミングのための確率統計』のものであることに気がついているかもしれません。具体的には53ページの例題2.7。この本に書いてある図を見れば、条件付き確率は一目瞭然です。確率分布や確率変数がとてもよくできた確率の問題の抽象化であることを実感できると思います。&lt;br /&gt;&lt;br /&gt;なお、この記事は &lt;a href="http://atnd.org/events/10631"&gt;Haskell Advent Calendar jp 2010&lt;/a&gt; のために書いたものです。宣伝いうな。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-981243833543091832?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/981243833543091832/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=981243833543091832' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/981243833543091832'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/981243833543091832'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2010/12/1-2-3-4-5-6-16-16-16-16-16-16-246-135.html' title='プログラミングのための確率統計 in Haskell'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-3464590060282814260</id><published>2010-12-08T18:11:00.002+09:00</published><updated>2010-12-08T18:13:20.411+09:00</updated><title type='text'>Kindleはメディアそのものだった</title><content type='html'>もう紙の本はbook、電子の本はkindleという一般名詞でいいとさえ思う。Kindle for the Webの正式リリースが数ヵ月後だと発表されて、あらためてそう感じた。Amazon.comも一企業でしかないので、あんまり妄信するつもりはない。けれども、今年の初めにKindle DXを買ってから12冊ばかし読んでみて、Kindleが自分の読書空間の一部になってしまったなと実感している。つまり、Kindleというのはデバイスとかデータ形式ではなく、紙の「本」が書店や読書の場所（自宅とか電車とかスタバとか）なんかを含めた大きなメディアであったのと同じ意味で、メディアそのものだった。&lt;br /&gt;&lt;br /&gt;たぶん、Kindleが自分にとってメディアそのものになってしまった背景には、こんな理由がある。&lt;br /&gt;&lt;ol&gt;&lt;li&gt;本当に読みたいと思える本がいつでも買える&lt;/li&gt;&lt;li&gt;リフローするページメディアである&lt;/li&gt;&lt;li&gt;さまざまな環境でシームレスに読めてしまう&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;1の要因は本当に大きい。この1年でいろんな本がEPUBやPDFで配布されるようになったけど、Kindleにはすでにほとんどそろってる。紙の本ならジュンク堂に行くように、品揃えのよい本屋はそれだけで足を運ぶ価値がある。Kindleは足を運ぶ必要もない。&lt;br /&gt;&lt;br /&gt;2は、Kindleに限らず、革命だと思う。むかしはわたしもスクロールメディア対ページメディアとか考えてました。読書におけるページというインターフェースの利点は、情報の位置が固定されることやインデックスとしてノンブルがあることじゃなかったのですね。この革命感は、実際にKindleやEPUBリーダーで本を読みまくらないと実感できないかも。3だって、クラウドとかいう前に、2があるからこそ違和感なく実現できるわけで、リフローするページメディアは偉大だと思う。スクロールして読むEPUBリーダーとか意味わからん。&lt;br /&gt;&lt;br /&gt;「こうじゃない」式の言い方をするなら、たとえば、EPUBやPDFで配布されているものをデバイスのKindleで読むことは、ここで絶賛したいKindleのうれしさではない。あるいは、EPUBで配布されている電子書籍をAndroid端末のEPUBリーダーで読むことだって、Kindleストアで購入した電子書籍をKindle for Androidで読むのと同じくらいに快適だけど、プラットフォームとしての魅力があるのはKindleのほう。もしくは、購入した書籍を自炊したPDFをiPadで読むのはすばらしいけれど、それはやっぱり「電子書籍の代替」なんだろうなと思う。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-3464590060282814260?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/3464590060282814260/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=3464590060282814260' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/3464590060282814260'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/3464590060282814260'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2010/12/1kindle.html' title='Kindleはメディアそのものだった'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-777481760155292140</id><published>2010-11-29T12:29:00.001+09:00</published><updated>2010-11-29T12:32:15.613+09:00</updated><title type='text'>多値で簡単パーサーコンビネーター（Shibuya.lisp TT#6）</title><content type='html'>Shibuya.lispのテクニカルトーク#6に参加しました。仕事半分以下、趣味半分以上です。&lt;br /&gt;&lt;br /&gt;まず仕事の部分について、直売で書籍を購入いただいた皆さん、本当にありがとうございました。Lispそのものの本よりも『鉄道ダイヤの回復技術』や『日本のコンピュータ史』のような本が想定以上に売れてしまうあたり、さすがShibuya.lispだと思った。&lt;br /&gt;&lt;br /&gt;ただ、前回も直販をしたのだけど、そのときの反省として、販売員をやるとどうも外野っぽくなってしまう。自分としては、普段からSchemeを使っているので、いちLispユーザーとしてもShibuya.lispに参加したい。それで今回はLTに応募した。LTのトピックはなんでもよかったのだけど、具体的にコードが見えるもののほうが面白かろうということで、個人プロジェクトの中で利用したアイデアを切り出して、多値を使って自分の目的にあったパーサーコンビネーターを簡単に作れるよ、という発表をさせてもらった。誤解を招くようにしたわけだけど、本の宣伝広告のほうはネタです。&lt;br /&gt;&lt;br /&gt;&lt;div style="width:425px" id="__ss_5955469"&gt;&lt;strong style="display:block;margin:12px 0 4px"&gt;&lt;a href="http://www.slideshare.net/k16shikano/shibuyalisp-tt6lt" title="多値で簡単パーサーコンビネーター"&gt;多値で簡単パーサーコンビネーター&lt;/a&gt;&lt;/strong&gt;&lt;object id="__sse5955469" width="425" height="355"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=shibuyalisp-tt6-lt-101128192644-phpapp02&amp;stripped_title=shibuyalisp-tt6lt&amp;userName=k16shikano" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed name="__sse5955469" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=shibuyalisp-tt6-lt-101128192644-phpapp02&amp;stripped_title=shibuyalisp-tt6lt&amp;userName=k16shikano" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div style="padding:5px 0 12px"&gt;View more &lt;a href="http://www.slideshare.net/"&gt;presentations&lt;/a&gt; from &lt;a href="http://www.slideshare.net/k16shikano"&gt;k16shikano&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Gaucheで実行できるコードもgithubにあげておきます。実質的には100行くらいの短いコードです。&lt;br /&gt;&lt;br /&gt;&lt;a href="https://github.com/k16shikano/tinypeg"&gt;k16shikano/tinypeg&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;肝心の発表では、思わずTeXについて語ってしまったおかげで時間がなくなってしまったけど、本当はスライド26枚目でParsecが出てくるあたりから面白くなるはずだった！ でも&lt;a href="http://twitter.com/#!/khibino"&gt;@khibino&lt;/a&gt;さんに喜んでもらえたので本望です。なおかつフィードバックもたくさんもらえた。ありがとうございます。これについてはそのうちまとめてもうちょっと役に立ちそうな記事を書くつもり。&lt;br /&gt;&lt;br /&gt;ちなみに、実際にこのアイデアを実装していたのは去年のいまごろの話。この原理を利用したパーサーコンビネーターを作ったおかげで、本来の開発対象であるTeX modokiがずいぶん前進した。&lt;br /&gt;&lt;br /&gt;&lt;a href="https://github.com/k16shikano/tex-modoki"&gt;k16shikano/tex-modoki&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;TeX modokiはGaucheによるTeXの簡易実装です。TeXのソースをHTML/CSS2.1で出力します。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-777481760155292140?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/777481760155292140/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=777481760155292140' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/777481760155292140'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/777481760155292140'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2010/11/shibuyalisp-tt6.html' title='多値で簡単パーサーコンビネーター（Shibuya.lisp TT#6）'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-2253838307489411291</id><published>2010-11-15T20:06:00.008+09:00</published><updated>2010-11-16T12:30:20.155+09:00</updated><title type='text'>Lisperのためのゲーデルの不完全性定理の反証不可能性について考えてみた</title><content type='html'>&lt;a href="http://d.hatena.ne.jp/kazu-yamamoto/20101112/1289531777"&gt;Lisperのためのゲーデルの不完全性定理&lt;/a&gt;では、(g g)が証明も反証もできないことが示されていない。証明できないほうはいいとして、反証できないことがすぐに理解できなかった。unprovable-pとvalid-proof-pだけで反証不能なことが証明できるの？&lt;br /&gt;&lt;br /&gt;ちょっと考えてみた。&lt;br /&gt;(g g)の否定が証明可能だとすると、&lt;pre&gt;(unprovable-p&lt;br /&gt; (eval&lt;br /&gt;  ((lambda&lt;br /&gt;     (x)&lt;br /&gt;     `(unprovable-p&lt;br /&gt;       (eval&lt;br /&gt;        (,x ',x))))&lt;br /&gt;   '(lambda&lt;br /&gt;      (x)&lt;br /&gt;      `(unprovable-p&lt;br /&gt;        (eval&lt;br /&gt;         (,x ',x)))))))&lt;/pre&gt;の否定が証明可能ということなので、&lt;pre&gt;(valid-proof-p&lt;br /&gt; (eval&lt;br /&gt;  ((lambda&lt;br /&gt;     (x)&lt;br /&gt;     `(unprovable-p&lt;br /&gt;       (eval&lt;br /&gt;        (,x ',x))))&lt;br /&gt;   '(lambda&lt;br /&gt;      (x)&lt;br /&gt;      `(unprovable-p&lt;br /&gt;        (eval&lt;br /&gt;         (,x ',x)))))))&lt;/pre&gt;ところがこれは、gの主張である&lt;pre&gt;(unprovable-p (eval (,x ',x))))&lt;/pre&gt;と矛盾する。したがって(g g)は反証不可能。&lt;br /&gt;&lt;br /&gt;こんな感じだろうか？&lt;br /&gt;&lt;br /&gt;で、(g g)の形式的な決定不能性はいいとして、これをもってゲーデルの不完全性定理が証明できた、とは依然としていえないんじゃないだろうか。なぜなら、S式からなる形式的な系について、unprovable-pとvalid-proof-pがあるということ以上に何も情報がないから。それだけの情報では、この系が不完全性定理の前提条件を満たすかどうか確かめようがない。と思う。S式で自然数が作れるのは確かだけど、すべてのS式からなる系では当然無矛盾性を満たさないし。1階の述語論理に対応するS式のセットを再帰的に用意して、そこでunprovable-pとvalid-proof-pを（Lispの意味論を使わず形式的に）定義すればいいのだけど、簡単ではなさそう。（追記：Lispの実装にこだわらなければ、比較的わかりやすく形式化できるようです→&lt;a href="http://howm.sourceforge.jp/cgi-bin/hiki/hiki.cgi?IncompletenessTheorem.rev"&gt;howm wiki - 不完全性定理.改&lt;/a&gt;。Lispでゲーデルの不完全性定理が証明できる！のようなインパクトはないですが、「Lispを含む再帰的可算な公理系は不完全」の証明になってそう）&lt;br /&gt;&lt;br /&gt;だからたぶんチャイティンの元記事は、不完全性定理のフレーバーをLispならS式で表せるぜ、という話であって、それは、不完全性定理のフレーバーを自然言語ならうそつきのパラドクスで表せるぜ、という話と大きく違わないのではないかと思った。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-2253838307489411291?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/2253838307489411291/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=2253838307489411291' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/2253838307489411291'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/2253838307489411291'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2010/11/lisper.html' title='Lisperのためのゲーデルの不完全性定理の反証不可能性について考えてみた'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-8269032385358303776</id><published>2010-10-25T19:36:00.004+09:00</published><updated>2010-10-25T19:36:00.135+09:00</updated><title type='text'>原稿の形式って最適解があるの？</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://farm2.static.flickr.com/1375/5113306551_e083462a25_m.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 240px; height: 180px;" src="http://farm2.static.flickr.com/1375/5113306551_e083462a25_m.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://oku.edu.mie-u.ac.jp/texconf10/"&gt;TeXユーザの集い2010&lt;/a&gt;でパネル発表をしました。この1～2年のあいだに手がけたLaTeXによる組版の本もいくつか展示しました。もし「TeXで新規に組んでる本の数」部門があったら、それなりに上位に食い込めたはず。（そういうイベントではありません）&lt;br /&gt;&lt;br /&gt;いまうちらは本の制作にTeXを使っている。しかしそれは、「きれいに組めるから」でも「著者の原稿がTeXだから」でもない。もちろん、きれいに間違いのない組版（とくに数式）ができることはTeXの大きなメリットだけれども、うちらはそんなに数式の多い本ばかり作っているわけでもないので、それがTeXを使う必然性にはなっていない。ただ、数式を含む組版のためのツールとしてTeXに欠陥がないことは、いまの制作フローを実現するための必要条件ではある。&lt;br /&gt;&lt;br /&gt;そのうえで、うちらの制作フローにとってTeXが満たしている十分条件は、レイアウトや、がんばれば図版までも、すべてテキストで管理できることにある。ここで「管理できる」といっているのは、印刷所にわたす直前まで、汎用のバージョン管理ツールを使って継続的にインテグレーションが可能であるということ。TeXがテキストであることは、多くのTeXユーザーもメリットとして挙げる点だと思うけれど、それが執筆からリリースの全期間にわたる継続的インテグレーションにとってうれしいという主張は、自分たち自身もあまり陽に喧伝してこなかったことなので、TeXユーザーの集い2010ではあらためてパネル発表の1枚目として大書した。&lt;br /&gt;&lt;br /&gt;&lt;div style="width:477px" id="__ss_5548610"&gt;&lt;strong style="display:block;margin:12px 0 4px"&gt;&lt;a href="http://www.slideshare.net/k16shikano/texconf10-ohmshakaihatsubupanel" title="オーム社開発部がTeXを使う3つのおもな理由"&gt;オーム社開発部がTeXを使う3つのおもな理由&lt;/a&gt;&lt;/strong&gt;&lt;object id="__sse5548610" width="477" height="510"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/doc_player.swf?doc=texconf10-ohmsha-kaihatsubu-panel-101024215840-phpapp02&amp;stripped_title=texconf10-ohmshakaihatsubupanel&amp;userName=k16shikano" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed name="__sse5548610" src="http://static.slidesharecdn.com/swf/doc_player.swf?doc=texconf10-ohmsha-kaihatsubu-panel-101024215840-phpapp02&amp;stripped_title=texconf10-ohmshakaihatsubupanel&amp;userName=k16shikano" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="477" height="510"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div style="padding:5px 0 12px"&gt;View more &lt;a href="http://www.slideshare.net/"&gt;documents&lt;/a&gt; from &lt;a href="http://www.slideshare.net/k16shikano"&gt;k16shikano&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;もうひとつ、このパネル発表の1枚目で強調したかったことは、「入力形式は強制しません」ということ。なんというか、原稿からHTMLなりPDFなりを生成するシステムにとって、原稿執筆のための決まり（TeXのスタイル、XMLのスキーマ、既存のWiki記法、独自のWiki記法、などなど）を画一的に定めてしまうのってどうなんでしょう？ 出力するものがマニュアルや学会誌論文のような定形のドキュメントなら、標準のスキーマが有意義というか必然の要件になると思う。でも、とくに本のような「一点もの」にとっては、原稿そのものの表現方法、つまり構造の入れ方にも、選択肢というか自由度があったほうがいいんじゃないだろうか。結果として、うちら編集者は、書籍ごとに構造の入れ方が多種多様な原稿を受け入れることになるわけだけれども、そういうのを吸収するのもまた編集者の仕事だと思うわけです。そんなわけで、最近の自分の仕事は、プロジェクトごとにカスタムパーサーを書いて出版用スタイルに合わせたLaTeXファイルを出力し、PDFを自動的に生成できるようにすることから始まる。半分冗談だけど半分本当の話。&lt;br /&gt;&lt;br /&gt;そんなわけで、オーム社開発部から「こういう形式にのっとって書くべし」などと強制することはあまりない（例外は、翻訳ものでベースになるデータがある場合）。こちらから原稿の形式を提案する場合は、たいていTeXでさえなく、各プロジェクトに適したXML風の書式を提案している。ここで「XML」という時点で、TeXの人たちからはうげーと言われてしまうのだけど、多くの場合はスキーマも何もない野良XMLとでもいうべきもので、開きタグと閉じタグで文章に構造を与えただけのもの。タグの種類は、プロジェクトにとって適切なものを自由に使ってOK（see. &lt;a href="http://www.geekpage.jp/blog/?id=2010/10/20/1"&gt;Geekなぺーじ : Scheme手習い - The Little Schemer -&lt;/a&gt;）。もちろんTeXでもOK。他の形式でもOK。構造が一意に表現できるテキストであることが最低要件。パーサーもあるとうれしいので、&lt;a href="http://i.loveruby.net/svn/public/review/"&gt;ReVIEW&lt;/a&gt;も歓迎です。&lt;br /&gt;&lt;br /&gt;もちろん、形式が定まっているほうが執筆しやすいという人も多いはずだし、そのような場合には汎用のスタイルを提案します。たとえばXHTMLとかが候補になると思います。（see. &lt;a href="http://ideotype.sourceforge.net/"&gt;IdeoType&lt;/a&gt;）&lt;br /&gt;&lt;br /&gt;最後に、とってつけたようでなんだけれども、受け入れる形式を問わずに最終的にPDFとして組んで出力できるのはTeXの自由度の高さがあればこそだなあと思った。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-8269032385358303776?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/8269032385358303776/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=8269032385358303776' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/8269032385358303776'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/8269032385358303776'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2010/10/blog-post.html' title='原稿の形式って最適解があるの？'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm2.static.flickr.com/1375/5113306551_e083462a25_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-873447869211250758</id><published>2010-09-11T18:22:00.008+09:00</published><updated>2010-09-15T10:01:13.475+09:00</updated><title type='text'>TeXのトイ実装で数式をHTML表示する話</title><content type='html'>&lt;style&gt;&lt;br /&gt;span.noad {display:inline-block;text-align:left;vertical-align:middle;font-size:60%}&lt;br /&gt;span.noad div.sub {position:relative;bottom:0.4em;}&lt;br /&gt;span.noad div.sup {position:relative;top:0.4em;}&lt;br /&gt;span.italic {font-style:italic}&lt;br /&gt;span.normal {font-style:normal}&lt;br /&gt;span.op {display:inline-block; text-align:center; vertical-align:middle;font-size:200%}&lt;br /&gt;span.op span.noad {font-size:60%}&lt;br /&gt;span.op span.noad div.sub {position:relative;bottom:1em}&lt;br /&gt;span.op span.noad div.sup {position:relative;top:1em}&lt;br /&gt;span.op div.sup {font-size:30%;vertical-align:bottom}&lt;br /&gt;span.op div.sub {font-size:30%;vertical-align:bottom}&lt;br /&gt;span.op div.nuc {font-size:100%;line-height:80%}&lt;br /&gt;span.null {display:inline-block;width:0px;line-height:0px}&lt;br /&gt;span.binrel {display:inline-block;text-align:center;vertical-align:middle;font-size:110%;}&lt;br /&gt;span.box {font-style:normal; vertical-align:middle}&lt;br /&gt;span.delim {font-size:130%;vertical-align:middle}&lt;br /&gt;span.rad {display:inline-block;border-top:1pt solid;vertical-align:middle}&lt;br /&gt;span.fraction {display:inline-block;text-align:center;vertical-align:middle;font-size:80%;}&lt;br /&gt;span.fracdelim {font-size:150%; vertical-align:middle}&lt;br /&gt;&lt;/style&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;What &lt;a href="http://github.com/k16shikano/tex-modoki"&gt;TeX-modoki is&lt;/a&gt;&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;TeX-modoki is aiming to become a subset of plain TeX implementation. Instead of DVI or PDF, it is intended to generate a plain-old HTML file. Being fully compliant with TeX's macro language, it could support LaTeX or other packages. I wish all the legacy TeX manuscripts around the world someday became readable on any web browser.&lt;br /&gt;&lt;br /&gt;TeX-modoki は plain TeX の簡易実装です。出力はDVIやPDFではなくHTMLです。TeXのマクロ言語を実装しているので、LaTeXのような一般的なパッケージを使って書かれた原稿にも原理的には対応できるはず。地球上のあらゆる既存のTeX原稿がブラウザで文字データとして閲覧できるようになればいいな。&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Sample Output&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;For now, you get some mathematical formula in HTML/CSS2.1 from a plain TeX source, though the output needs further refinement.&lt;br /&gt;&lt;br /&gt;現状の出力機能はやっつけだけれども、HTML/CSSなので、たいていのブラウザでそれっぽく数式を表示できるようにはなっている。&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;1. Simple example&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;Displaying fraction or choice is trivial for TeX but for HTML.&lt;br /&gt;&lt;br /&gt;分数など。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;(tokenlist-&gt;html&lt;br /&gt;  (output&lt;br /&gt;   (string-&gt;tokenlist&lt;br /&gt;      "$_nC_{k/2} = {n\\atopwithdelims() {k\\over 2}}$")))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The result is &lt;br /&gt;&lt;div style="font-family:serif; font-size:150%"&gt;&lt;span class=""&gt;&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="italic"&gt;n&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="italic"&gt;C&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="inner"&gt;&lt;span class="italic"&gt;k&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="normal"&gt;/&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="normal"&gt;2&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:{100}%"&gt; &lt;/span&gt;&lt;span class="binrel"&gt;=&lt;/span&gt;&lt;span style="font-size:{100}%"&gt; &lt;/span&gt;&lt;span class="inner"&gt;&lt;span class="fracdelim"&gt;(&lt;/span&gt;&lt;span style="font-size:{10}%"&gt; &lt;/span&gt;&lt;span class="fraction"&gt;&lt;div style="border-bottom:()px solid;"&gt;&lt;span class="italic"&gt;n&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="inner"&gt;&lt;span class="fracdelim"&gt;&lt;/span&gt;&lt;span style="font-size:{10}%"&gt; &lt;/span&gt;&lt;span class="fraction"&gt;&lt;div style="border-bottom:1px solid;"&gt;&lt;span class="italic"&gt;k&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="normal"&gt;2&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;span style="font-size:{10}%"&gt; &lt;/span&gt;&lt;span class="fracdelim"&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;span style="font-size:{10}%"&gt; &lt;/span&gt;&lt;span class="fracdelim"&gt;)&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;2. Example with mathematical symbols&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;Mathematical symbols can be defined in the same way as plain TeX, except you must specify them with Unicode but TeX's character encoding. You can also compose any original symbol in the TeX manner. In this example, \cdots is defined exactly the same way as the Appendix B of "The TeXbook."&lt;br /&gt;&lt;br /&gt;数式で使う記号類は、TeXとまったく同じ方法で、TeXの文字コードの代わりにUnicodeの値を指定しておきます。独自に合成した記号も、やはりTeXと同じようにして定義できます。（実際、以下の例の \cdots は「TeXブック」付録Bの定義そのままです。）&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;(tokenlist-&gt;html&lt;br /&gt;  (output&lt;br /&gt;   (string-&gt;tokenlist&lt;br /&gt;    "\\mathchardef\\infty = \"0221e \\mathchardef\\sum = \"103a3 \\mathchardef\\cdotp = \"000b7\&lt;br /&gt;     \\def\\cdots{\\mathinner{\\cdotp\\cdotp\\cdotp}}\&lt;br /&gt;     The exponential function&lt;br /&gt;      $e^x = \\sum_{n=0}^{\\infty} {x^n \\over n!}&lt;br /&gt;           = {x^1\\over 1!} + {x^2\\over 2!}+ \\cdots$ . ")))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The result is&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family:serif; font-size:150%"&gt;The exponential function &lt;span class="italic"&gt;e&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="italic"&gt;x&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:{100}%"&gt; &lt;/span&gt;&lt;span class="binrel"&gt;=&lt;/span&gt;&lt;span style="font-size:{100}%"&gt; &lt;/span&gt;&lt;span class="op"&gt;&lt;div class="sup"&gt;&lt;span class="inner"&gt;&lt;span class="italic"&gt;∞&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="nuc"&gt;Σ&lt;/div&gt;&lt;div class="sub"&gt;&lt;span class="inner"&gt;&lt;span class="italic"&gt;n&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:{100}%"&gt; &lt;/span&gt;&lt;span class="binrel"&gt;=&lt;/span&gt;&lt;span style="font-size:{100}%"&gt; &lt;/span&gt;&lt;span class="normal"&gt;0&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;span style="font-size:{20}%"&gt; &lt;/span&gt;&lt;span class="inner"&gt;&lt;span class="fracdelim"&gt;&lt;/span&gt;&lt;span style="font-size:{10}%"&gt; &lt;/span&gt;&lt;span class="fraction"&gt;&lt;div style="border-bottom:1px solid;"&gt;&lt;span class="italic"&gt;x&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="italic"&gt;n&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="italic"&gt;n&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="normal"&gt;!&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;span style="font-size:{10}%"&gt; &lt;/span&gt;&lt;span class="fracdelim"&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:{100}%"&gt; &lt;/span&gt;&lt;span class="binrel"&gt;=&lt;/span&gt;&lt;span style="font-size:{100}%"&gt; &lt;/span&gt;&lt;span class="inner"&gt;&lt;span class="fracdelim"&gt;&lt;/span&gt;&lt;span style="font-size:{10}%"&gt; &lt;/span&gt;&lt;span class="fraction"&gt;&lt;div style="border-bottom:1px solid;"&gt;&lt;span class="italic"&gt;x&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="normal"&gt;1&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="normal"&gt;1&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="normal"&gt;!&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;span style="font-size:{10}%"&gt; &lt;/span&gt;&lt;span class="fracdelim"&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:{100}%"&gt; &lt;/span&gt;&lt;span class="binrel"&gt;+&lt;/span&gt;&lt;span style="font-size:{100}%"&gt; &lt;/span&gt;&lt;span class="inner"&gt;&lt;span class="fracdelim"&gt;&lt;/span&gt;&lt;span style="font-size:{10}%"&gt; &lt;/span&gt;&lt;span class="fraction"&gt;&lt;div style="border-bottom:1px solid;"&gt;&lt;span class="italic"&gt;x&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="normal"&gt;2&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="normal"&gt;2&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="normal"&gt;!&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;span style="font-size:{10}%"&gt; &lt;/span&gt;&lt;span class="fracdelim"&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:{100}%"&gt; &lt;/span&gt;&lt;span class="binrel"&gt;+&lt;/span&gt;&lt;span style="font-size:{100}%"&gt; &lt;/span&gt;&lt;span class="inner"&gt;&lt;span class="italic"&gt;·&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="italic"&gt;·&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="italic"&gt;·&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt; .&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;3. Square-root&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;Square root is hard to display neatly in HTML/CSS without font-stretch. It’s decent if the inner elements fit in a line.&lt;br /&gt;&lt;br /&gt;根号は、CSS2.1ではフォントを上下に伸ばせないので、なかなかきれいには表示できません。中身が一行なら、そこそこの見た目にはなります。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;(tokenlist-&gt;html&lt;br /&gt;  (output&lt;br /&gt;   (string-&gt;tokenlist&lt;br /&gt;       "\\def\\sqrt{\\radical\"2221a}&lt;br /&gt;        \\mathchardef\\plusminus=\"300b1&lt;br /&gt;        Roots of a quadratic equation $ax^2+bx+c=0$ are&lt;br /&gt;        $x={-b\\plusminus\\sqrt{b^2 - 4ac} \\over 2a}$.")))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The result is &lt;br /&gt;&lt;br /&gt;&lt;div style="font-family:serif; font-size:150%"&gt;Roots of a quadratic equation &lt;span class="italic"&gt;a&lt;/span&gt;&lt;span class="italic"&gt;x&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="normal"&gt;2&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:{100}%"&gt; &lt;/span&gt;&lt;span class="binrel"&gt;+&lt;/span&gt;&lt;span style="font-size:{100}%"&gt; &lt;/span&gt;&lt;span class="italic"&gt;b&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="italic"&gt;x&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:{100}%"&gt; &lt;/span&gt;&lt;span class="binrel"&gt;+&lt;/span&gt;&lt;span style="font-size:{100}%"&gt; &lt;/span&gt;&lt;span class="italic"&gt;c&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:{100}%"&gt; &lt;/span&gt;&lt;span class="binrel"&gt;=&lt;/span&gt;&lt;span style="font-size:{100}%"&gt; &lt;/span&gt;&lt;span class="normal"&gt;0&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt; are &lt;span class="italic"&gt;x&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:{100}%"&gt; &lt;/span&gt;&lt;span class="binrel"&gt;=&lt;/span&gt;&lt;span style="font-size:{100}%"&gt; &lt;/span&gt;&lt;span class="inner"&gt;&lt;span class="fracdelim"&gt;&lt;/span&gt;&lt;span style="font-size:{10}%"&gt; &lt;/span&gt;&lt;span class="fraction"&gt;&lt;div style="border-bottom:1px solid;"&gt;&lt;span class="italic"&gt;−&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="italic"&gt;b&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:{100}%"&gt; &lt;/span&gt;&lt;span class="binrel"&gt;±&lt;/span&gt;&lt;span style="font-size:{100}%"&gt; &lt;/span&gt;&lt;span style="font-size:{20}%"&gt; &lt;/span&gt;&lt;span class="delim"&gt;√&lt;/span&gt;&lt;span class="rad"&gt;&lt;span class="italic"&gt;b&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="normal"&gt;2&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:{100}%"&gt; &lt;/span&gt;&lt;span class="binrel"&gt;−&lt;/span&gt;&lt;span style="font-size:{100}%"&gt; &lt;/span&gt;&lt;span class="normal"&gt;4&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="italic"&gt;a&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="italic"&gt;c&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:{20}%"&gt; &lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="normal"&gt;2&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="italic"&gt;a&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;span style="font-size:{10}%"&gt; &lt;/span&gt;&lt;span class="fracdelim"&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;4. More complicated formula&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;Integral symbol should be nolimit style. &lt;br /&gt;&lt;br /&gt;積分記号の添字は上下ではなく横に付くべきですが、これもTeXの定義のままHTMLで表示できます。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;(tokenlist-&gt;html&lt;br /&gt;  (output&lt;br /&gt;   (string-&gt;tokenlist&lt;br /&gt;       "\\mathchardef\\intop=\"1222b\&lt;br /&gt;         \\mathchardef\\infty=\"1221e\&lt;br /&gt;         \\mathchardef\\pi=\"003c0\&lt;br /&gt;         \\mathchardef\\sigma=\"003c3\&lt;br /&gt;         \\mathchardef\\mu=\"003bc\&lt;br /&gt;         \\def\\sqrt{\\radical\"2221a}\&lt;br /&gt;         \\def\\int{\\intop\\nolimits}\&lt;br /&gt;         $\\int_{-\\infty}^\\infty \&lt;br /&gt;             {1 \\over \\sqrt{2\\pi\\sigma^2}}\&lt;br /&gt;             \\hbox{exp}(- {{(x-\\mu)}^2\\over 2\\sigma^2}) dx$")))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The result is &lt;br /&gt;&lt;br /&gt;&lt;div style="font-family:serif; font-size:150%"&gt;&lt;span class="op"&gt;∫&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="op"&gt;∞&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:{20}%"&gt; &lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="inner"&gt;&lt;span class="italic"&gt;−&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="op"&gt;∞&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:{20}%"&gt; &lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:{20}%"&gt; &lt;/span&gt;&lt;span class="inner"&gt;&lt;span class="fracdelim"&gt;&lt;/span&gt;&lt;span style="font-size:{10}%"&gt; &lt;/span&gt;&lt;span class="fraction"&gt;&lt;div style="border-bottom:1px solid;"&gt;&lt;span class="normal"&gt;1&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size:{20}%"&gt; &lt;/span&gt;&lt;span class="delim"&gt;√&lt;/span&gt;&lt;span class="rad"&gt;&lt;span class="normal"&gt;2&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="italic"&gt;π&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="italic"&gt;σ&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="normal"&gt;2&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:{20}%"&gt; &lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;span style="font-size:{10}%"&gt; &lt;/span&gt;&lt;span class="fracdelim"&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="box"&gt;exp&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="binrel"&gt;(&lt;/span&gt;&lt;span class="italic"&gt;−&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="inner"&gt;&lt;span class="fracdelim"&gt;&lt;/span&gt;&lt;span style="font-size:{10}%"&gt; &lt;/span&gt;&lt;span class="fraction"&gt;&lt;div style="border-bottom:1px solid;"&gt;&lt;span class="inner"&gt;&lt;span class="binrel"&gt;(&lt;/span&gt;&lt;span class="italic"&gt;x&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:{100}%"&gt; &lt;/span&gt;&lt;span class="binrel"&gt;−&lt;/span&gt;&lt;span style="font-size:{100}%"&gt; &lt;/span&gt;&lt;span class="italic"&gt;μ&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="binrel"&gt;)&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="normal"&gt;2&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="normal"&gt;2&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="italic"&gt;σ&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="normal"&gt;2&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;span style="font-size:{10}%"&gt; &lt;/span&gt;&lt;span class="fracdelim"&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="binrel"&gt;)&lt;/span&gt;&lt;span class="italic"&gt;d&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="italic"&gt;x&lt;span class="noad"&gt;&lt;div class="sub"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="sup"&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="null"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-873447869211250758?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/873447869211250758/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=873447869211250758' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/873447869211250758'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/873447869211250758'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2010/09/what-tex-modoki-is-tex-modoki-is-aiming.html' title='TeXのトイ実装で数式をHTML表示する話'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-732823942142212121</id><published>2010-07-02T18:33:00.000+09:00</published><updated>2010-07-02T18:33:45.597+09:00</updated><title type='text'>SLaTeXを使う。Gaucheで。</title><content type='html'>&lt;a href="http://evalwhen.com/slatex/slatxdoc.html"&gt;SLaTeX&lt;/a&gt;をGaucheで使いたい。&lt;br /&gt;&lt;br /&gt;SLaTeXは、Schemeのコードを装飾するためのtex-&gt;texコンバータ。&lt;code&gt;\scheme|...|&lt;/code&gt;とか&lt;code&gt;\begin{schemedisplay}...\end{schemedisplay}&lt;/code&gt;といった感じでSchemeのコードを(La)TeXの原稿中に書いておくと、その各部分に装飾を施した一時的なtexファイルをSchemeスクリプトで大量に生成してくれる。それをTeXの処理系に渡すところまでやってくれるslatexというシェルスクリプトがついているので、&lt;code&gt;latex foo.tex&lt;/code&gt;のかわりに&lt;code&gt;slatex foo.tex&lt;/code&gt;とすればよい。&lt;br /&gt;&lt;br /&gt;よいのだけど、実際に使うとなんとなく微妙。一時ファイルが大量にできるのは気持ちが悪いし、添付のスタイルが（少なくとも日本語環境では）あんまりうまくない。プリティプリンタというわけでもなさそうで、インデントの面倒も見てくれない。&lt;br /&gt;&lt;br /&gt;あと、現時点ではそのままGaucheで使えない。とりあえず使えるように、次のようなパッチをあてた。これで&lt;code&gt;gosh /(path to scmxlate)/scmxlate.scm&lt;/code&gt;のようにすると、Gauche用のslatex.scmと、platexを使うシェルスクリプトができる。&lt;pre&gt;diff -rupN slatex/dialects/dialects-supported.scm myslatex/dialects/dialects-supported.scm&lt;br /&gt;--- slatex/dialects/dialects-supported.scm      2002-11-24 05:06:34.000000000 +0900&lt;br /&gt;+++ myslatex/dialects/dialects-supported.scm    2010-07-02 16:31:41.000000000 +0900&lt;br /&gt;@@ -1,6 +1,7 @@&lt;br /&gt; bigloo&lt;br /&gt; chez&lt;br /&gt; gambit&lt;br /&gt;+gauche&lt;br /&gt; guile&lt;br /&gt; mitscheme&lt;br /&gt; mzscheme&lt;br /&gt;diff -rupN slatex/dialects/gauche-slatex-src.scm myslatex/dialects/gauche-slatex-src.scm&lt;br /&gt;--- slatex/dialects/gauche-slatex-src.scm       1970-01-01 09:00:00.000000000 +0900&lt;br /&gt;+++ myslatex/dialects/gauche-slatex-src.scm     2010-07-02 18:08:41.000000000 +0900&lt;br /&gt;@@ -0,0 +1,12 @@&lt;br /&gt;+(define getenv sys-getenv)&lt;br /&gt;+&lt;br /&gt;+(define *scheme-version*&lt;br /&gt;+  (string-append "Gauche " (gauche-version)))&lt;br /&gt;+&lt;br /&gt;+(define void&lt;br /&gt;+  (lambda ()&lt;br /&gt;+    (if #f #f)))&lt;br /&gt;+&lt;br /&gt;+(scmxlate-postprocess&lt;br /&gt;+  (define *scheme-command-name* "gosh")&lt;br /&gt;+  (load "./dialects/make-echo-script.scm"))&lt;br /&gt;diff -rupN slatex/dialects/make-echo-script.scm myslatex/dialects/make-echo-script.scm&lt;br /&gt;--- slatex/dialects/make-echo-script.scm        2002-03-25 01:26:22.000000000 +0900&lt;br /&gt;+++ myslatex/dialects/make-echo-script.scm      2010-07-02 17:13:53.000000000 +0900&lt;br /&gt;@@ -3,12 +3,16 @@&lt;br /&gt;    (rename-file "my-slatex-src.scm" "slatex.scm")&lt;br /&gt;    (delete-file "slatex")&lt;br /&gt;    (delete-file "callsla.scm"))&lt;br /&gt;+  ((gauche)&lt;br /&gt;+   (sys-rename "my-slatex-src.scm" "slatex.scm")&lt;br /&gt;+   (if (file-exists? "slatex") (sys-remove "slatex"))&lt;br /&gt;+   (if (file-exists? "callsla.scm") (sys-remove "callsla.scm")))&lt;br /&gt;   (else&lt;br /&gt;    (system "mv my-slatex-src.scm slatex.scm")&lt;br /&gt;    (system "rm -f slatex callsla.scm")))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-(load "dialects/make-callsla.scm")&lt;br /&gt;+(load "./dialects/make-callsla.scm")&lt;br /&gt;&lt;br /&gt; (call-with-output-file "slatex"&lt;br /&gt;   (lambda (o)&lt;br /&gt;@@ -18,11 +22,7 @@&lt;br /&gt;     (display ")" o) (newline o)&lt;br /&gt;     (display ";check pathname above is correct for you" o)&lt;br /&gt;     (newline o)&lt;br /&gt;-    (display "(slatex" o)&lt;br /&gt;-    (display (if (eqv? *dialect* 'bigloo)&lt;br /&gt;-                 "$$"&lt;br /&gt;-                 "::") o)&lt;br /&gt;-    (display "process-main-tex-file \"'$1'\")" o)&lt;br /&gt;+    (display "(process-main-tex-file \"'$1'\")" o)&lt;br /&gt;     (if (eqv? *dialect* 'scsh)&lt;br /&gt;         (begin&lt;br /&gt;          (newline o)&lt;br /&gt;@@ -32,10 +32,11 @@&lt;br /&gt;     (newline o)&lt;br /&gt;     (display "if test -f pltexchk.jnk" o) (newline o)&lt;br /&gt;     (display "then tex $1; rm pltexchk.jnk" o) (newline o)&lt;br /&gt;-    (display "else latex $1" o) (newline o)&lt;br /&gt;+    (display "else platex $1" o) (newline o)&lt;br /&gt;     (display "fi" o) (newline o)))&lt;br /&gt;&lt;br /&gt; (case *dialect*&lt;br /&gt;   ((scsh) (run (chmod "+x" slatex)))&lt;br /&gt;+  ((gauche) (sys-chmod "slatex" 484))&lt;br /&gt;   (else (system "chmod +x slatex")))&lt;br /&gt;&lt;br /&gt;diff -rupN slatex/scmxlate-slatex-src.scm myslatex/scmxlate-slatex-src.scm&lt;br /&gt;--- slatex/scmxlate-slatex-src.scm      2009-09-29 08:28:56.000000000 +0900&lt;br /&gt;+++ myslatex/scmxlate-slatex-src.scm    2010-07-02 17:07:17.000000000 +0900&lt;br /&gt;@@ -16,10 +16,10 @@&lt;br /&gt;&lt;br /&gt; (scmxlate-eval&lt;br /&gt;  ;on denali&lt;br /&gt;- ;(define *target-file* "/home/dorai/.www/slatex/slatex.scm")&lt;br /&gt;+ (define *target-file* "/home/kshikano/src/slatex/slatex.scm")&lt;br /&gt;&lt;br /&gt;  ;on mac&lt;br /&gt;- (define *target-file* "/Users/doraisitaram/public_html/slatex/slatex.scm")&lt;br /&gt;+ ;(define *target-file* "/Users/doraisitaram/public_html/slatex/slatex.scm")&lt;br /&gt;  )&lt;br /&gt;&lt;br /&gt; ;You may define slatex::*texinputs* here.  Eg,&lt;br /&gt;@@ -30,7 +30,7 @@&lt;br /&gt; ;(define slatex::*texinputs*&lt;br /&gt; ;"/home/dorai/tex:/usr/local/lib/tex/macros") ;in Unix&lt;br /&gt;&lt;br /&gt;-;(define slatex::*texinputs* (getenv "TEXINPUTS"))&lt;br /&gt;+(define slatex::*texinputs* (sys-getenv "TEXINPUTS"))&lt;br /&gt;&lt;br /&gt; ;Unfortunately, that last one is not really as convenient as&lt;br /&gt; ;it seems, even if your Scheme has a getenv procedure.&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-732823942142212121?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://docs.hp.com/ja/B2355-60104-01/diff.1.html' title='SLaTeXを使う。Gaucheで。'/><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/732823942142212121/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=732823942142212121' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/732823942142212121'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/732823942142212121'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2010/07/slatexgauche.html' title='SLaTeXを使う。Gaucheで。'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-3323583357385593884</id><published>2010-06-24T17:30:00.001+09:00</published><updated>2010-06-24T17:35:18.958+09:00</updated><title type='text'>The WYSIWYG Conundrum: The Solid Cloud � An American Editor</title><content type='html'>&lt;a href="http://americaneditor.wordpress.com/2010/06/08/the-wysiwyg-conundrum-the-solid-cloud/"&gt;The WYSIWYG Conundrum: The Solid Cloud � An American Editor&lt;/a&gt;: &lt;div class="quote"&gt;"Success is much more than the number of downloads of free or 99� ebooks, especially when there is no way to know how many of those downloads actually were read or well thought of. Instead, success is having readers clamor for your books, talk about your books, express a willingness to pay a higher price for your books — all things that a professional editorial eye can help an author achieve by preventing the kinds of mistakes that turn readers away."&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;「（本の）成功とは、タダだったり100円だったりするebookがたくさんダウンロードされることじゃない。そのうち何冊が読まれたか確かめようがないなら、なおさらだ。成功というのは、そんなことではなく、読者がその本を話題にしてくれて、もっとお金を払いたいと思ってくれることにある。その本を読んだ人をがっかりさせるようなミスを防ぐことにこそ、プロの編集者の役割がある。」&lt;br /&gt;&lt;br /&gt;これ以上なにも付け足すことがない。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-3323583357385593884?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/3323583357385593884/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=3323583357385593884' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/3323583357385593884'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/3323583357385593884'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2010/06/wysiwyg-conundrum-solid-cloud-american.html' title='The WYSIWYG Conundrum: The Solid Cloud � An American Editor'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-6614665005333859237</id><published>2010-06-03T16:00:00.003+09:00</published><updated>2010-06-03T17:06:42.477+09:00</updated><title type='text'>Emacs上での正規表現による検索で結果をハイライトしっぱなしにする</title><content type='html'>たまーに、「emacs」「検索」「ハイライト」で&lt;a href="http://note.golden-lucky.net/2007/08/emacs-ja-ja-en-en-let-designated.html"&gt;過去のエントリ&lt;/a&gt;を見てもらっているようなのですが、あれはバグっているのです。バグっているというか、フォントロックの仕組みをちゃんと理解していなかったので、実行するとメジャーモードの色づけを葬ってしまう。&lt;br /&gt;&lt;br /&gt;いまは改良してこうなっています。（Emacs 22.2.1）&lt;pre&gt;(defun keep-highlight-regexp (re)&lt;br /&gt;  (interactive "sRegexp: \n")&lt;br /&gt;  (make-face 'my-highlight-face)&lt;br /&gt;  (set-face-foreground 'my-highlight-face "black")&lt;br /&gt;  (set-face-background 'my-highlight-face "yellow")&lt;br /&gt;  (defvar my-highlight-face 'my-highlight-face)&lt;br /&gt;  (setq font-lock-set-defaults nil)&lt;br /&gt;  (font-lock-set-defaults)&lt;br /&gt;  (font-lock-add-keywords 'nil (list (list re 0 my-highlight-face t)))&lt;br /&gt;  (font-lock-fontify-buffer))&lt;br /&gt;&lt;br /&gt;(defun cancel-highlight-regexp ()&lt;br /&gt;  (interactive)&lt;br /&gt;  (setq font-lock-set-defaults nil)&lt;br /&gt;  (font-lock-set-defaults)&lt;br /&gt;  (font-lock-fontify-buffer))&lt;br /&gt;&lt;br /&gt;(global-set-key "\C-f" 'keep-highlight-regexp)&lt;br /&gt;(global-set-key "\C-d" 'cancel-highlight-regexp)&lt;/pre&gt;[Ctrl]-[f]で検索開始、[Ctrl]-[d]でハイライト解除。それぞれ、自分では通常のキーバインドとして使ってないので、グローバルに設定しています。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-6614665005333859237?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/6614665005333859237/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=6614665005333859237' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/6614665005333859237'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/6614665005333859237'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2010/06/emacs-emacs-22.html' title='Emacs上での正規表現による検索で結果をハイライトしっぱなしにする'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-4303464210885508057</id><published>2010-03-26T19:57:00.008+09:00</published><updated>2010-03-26T21:36:42.457+09:00</updated><title type='text'>稼働中のマシンのHDDから、VMware Player用の仮想マシンを作る</title><content type='html'>稼働中の物理マシンの HDD を、そっくり仮想イメージに変換して、 VMware Player で再生できるようにしたい。手順としてはこれだけなんだけど……&lt;ol&gt;&lt;li&gt;対象の HDD をダンプする（partimage を使う）&lt;/li&gt;&lt;li&gt;VMware 用の仮想ディスクを空っぽの状態で作る（QEMU を使う）&lt;/li&gt;&lt;li&gt;2.の空っぽ仮想ディスクに領域を作る（fdisk を使う）&lt;/li&gt;&lt;li&gt;1.のダンプを、3.の領域へとリストアする（partimage を使う）&lt;/li&gt;&lt;/ol&gt;それなりに広大な作業スペースが必要だし、個々の作業に時間がかかるので（待ち時間にこんな記事がかけるくらい）、次回以降はできるだけ要領よく済ませたい。だから自分用にメモ。もちろん無保証です。&lt;br /&gt;&lt;br /&gt;用意するもの。&lt;ul&gt;&lt;li&gt;&lt;b&gt;作業場&lt;/b&gt;：&lt;br /&gt;ここでは Windows マシンを使う。対象の HDD 上で動いてなくて、VMware と QEMU が使えて、でかいディスク容量があるマシンなら、何でもいいと思う。&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;起動環境&lt;/b&gt;：&lt;br /&gt;ここでは Knoppix の iso イメージを使う。VMware 用の仮想イメージ以外で、fdisk と partimage が使える環境を VMware Player から起動できるものなら、何でもいいと思う。&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;QEMU&lt;/b&gt;：&lt;br /&gt;空っぽの仮想ディスクを作るのに使う。ここでは QEMU on Windows の qemu-img コマンドを使う。&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;実際の作業の流れ。&lt;ol&gt;&lt;li&gt;partimage で対象の HDD をダンプして、作業場からファイルとして見える場所にイメージファイル（群）として保管する。&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Windows のコマンドプロンプトで、qemu-img コマンドを使って空っぽの VMware 用仮想ディスクを作る。対象の HDD と同じサイズで vmdk 形式にする。対象が 120Gバイトならこんな具合。&lt;pre&gt;&amp;gt; qemu-img create -f vmdk hokansaki.vmdk 120G&lt;/pre&gt;これで&lt;code&gt;hokansaki.vmdk&lt;/code&gt;という仮想ディスクができる。&lt;/li&gt;&lt;br /&gt;&lt;li&gt;空っぽの仮想ディスクをフォーマットしたいのだけど、空っぽなので、当然のことながら VMware Player で仮想マシンを起動することができない。そこで、何かしら起動環境が必要になる。空っぽの物理ディスクに OS をインストールするときと同じ理屈ですね。つまり、BIOSチップ を CD/DVDブートにするのと同じ要領で、VMware Player の BIOS を CD/DVD ブートに設定し、ROM ドライブに Knoppix のディスクを入れて Player を再起動すればいい。VMware Player の起動時に F2 を押せば BIOS 画面に入れる。&lt;br /&gt;ただ、せっかく仮想マシンなんだから、わざわざ物理的な起動ディスクを使う必要もない。作業場の HDD 上に Knoppix の iso を置いておいて、それを Player の起動時に読むようにしたほうが手っ取り早いというもの。つまり、こんな vmx ファイルで仮想マシンを読み込めばいい。（この例では Windows の Fドライブ以下に Knoppix 5.1.1 の iso が置いてある。guestOS の一覧は&lt;a href="http://phasorburn.com/index.php/archive/vmware-guestos-id-list/"&gt;このへん&lt;/a&gt;を参考に。ide1 の deviceType を cdrom-image としているため、この場合も BIOS で CD/DVD ブートに設定する必要あり）&lt;pre&gt;.encoding                = "Shift_JIS"&lt;br /&gt;config.version           = "8"&lt;br /&gt;virtualHW.version        = "4"&lt;br /&gt;memsize                  = "512"&lt;br /&gt;&lt;br /&gt;ide0:0.present           = "TRUE"&lt;br /&gt;ide0:0.fileName          = "hokansaki.vmdk"&lt;br /&gt;ide0:0.mode              = "persistent"&lt;br /&gt;ide0:0.deviceType        = "disk"&lt;br /&gt;&lt;br /&gt;ide1:0.present           = "TRUE"&lt;br /&gt;ide1:0.fileName          = "F:\knoppix-iso\KNX5.1.1J_AC.200.iso"&lt;br /&gt;ide1:0.deviceType        = "cdrom-image"&lt;br /&gt;&lt;br /&gt;ethernet0.present        = "TRUE"&lt;br /&gt;ethernet0.connectionType = "nat"&lt;br /&gt;&lt;br /&gt;usb.present              = "TRUE"&lt;br /&gt;&lt;br /&gt;displayName              = "hokan saki"&lt;br /&gt;guestOS                  = "other26xlinux"&lt;br /&gt;nvram                    = "hokansaki.nvram"&lt;/pre&gt;この構成で仮想マシンを起動する前に、仮想マシンから作業場（具体的には、ダンプしたイメージファイルの置き場所）が見えるようにする設定を忘れずに。VMware Player のバージョン3 には、「仮想マシン設定の編集」という GUI が用意されているので、そこから作業場のハードディスクを追加するだけだった。&lt;/li&gt;&lt;br /&gt;&lt;li&gt;空っぽの仮想ディスクを fdisk でフォーマット。上記の構成なら、くだんの空っぽの仮想ディスクは &lt;code&gt;/dev/hda&lt;/code&gt; として認識されているはずなので、&lt;pre&gt;$ sudo fdisk /dev/hda&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;partimage で、ダンプした対象 HDD のイメージファイルを &lt;code&gt;/dev/hda1&lt;/code&gt; にリストア。partimage を実行する前に、対象 HDD のイメージファイルの置き場所をマウントしておくこと。イーサネットだと、たぶんすごい時間がかかる。ついててよかった eSATA。&lt;/li&gt;&lt;br /&gt;&lt;li&gt;ブートローダの修復。GRUB ならこんな感じ。&lt;pre&gt;$ sudo mount /dev/hda1 /media/hda1&lt;br /&gt;$ sudo chroot /media/hda1&lt;br /&gt;$ grub-install /dev/hda&lt;/pre&gt;（マウントのときは Knoppix の UI を使わず、コンソールから mount コマンドで実行すること（Knoppix についてくる &lt;code&gt;/etc/fstab&lt;/code&gt; の設定のせいで読み取り専用になってしまうため）&lt;br /&gt;あと、fdiskで領域（この場合は&lt;code&gt;/dev/hda&lt;/code&gt;）をブート可能に設定しておくこと。&lt;/li&gt;&lt;br /&gt;&lt;li&gt;BIOS の CD/DVD ブートを解除すれば、物理マシンで稼動していたシステムがそっくり VMware Player 上で起動するようになるはず。&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-4303464210885508057?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/4303464210885508057/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=4303464210885508057' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/4303464210885508057'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/4303464210885508057'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2010/03/hddvmware-player.html' title='稼働中のマシンのHDDから、VMware Player用の仮想マシンを作る'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-6251445520828692264</id><published>2010-03-22T12:10:00.010+09:00</published><updated>2010-03-23T22:35:05.508+09:00</updated><title type='text'>TeXでFizzBuzz</title><content type='html'>shibuya.lisp の テクニカルトーク#5 で、はやみずさんが「LaTeXでFizzBuzzを書く気になるか？」的な話を一瞬されたので反応しておく。そう言われて始めて書いてみようかと思うくらいだから、「書く気になるか？」という問いに対する答えは否定的なものであっていると思う。&lt;pre&gt;\newcount\a \newcount\b \newcount\c&lt;br /&gt;\newcount\n \newcount\i&lt;br /&gt;\newif\ifdivisable&lt;br /&gt;&lt;br /&gt;\def\fizzbuzz#1{%&lt;br /&gt;  \n=#1 \i=1&lt;br /&gt;  \loop \ifnum\i&lt;\n &lt;br /&gt;    \printffizzbuzz&lt;br /&gt;    \advance \i by 1&lt;br /&gt;  \repeat}&lt;br /&gt;&lt;br /&gt;&lt;s&gt;\def\printffizzbuzz{%&lt;/s&gt;&lt;br /&gt;&lt;s&gt;  \testdivisable{\i}{15} \ifdivisable fizzbuzz\par \fi&lt;/s&gt;&lt;br /&gt;&lt;s&gt;  \testdivisable{\i}{3}  \ifdivisable fizz\par \fi&lt;/s&gt;&lt;br /&gt;&lt;s&gt;  \testdivisable{\i}{5}  \ifdivisable buzz\par \fi&lt;/s&gt;&lt;br /&gt;&lt;s&gt;  \ifdivisable\else \number \i\par \fi}&lt;/s&gt;&lt;br /&gt;&lt;br /&gt;\def\printffizzbuzz{%&lt;br /&gt;  \testdivisable{\i}{15} \ifdivisable fizzbuzz \else&lt;br /&gt;  \testdivisable{\i}{3}  \ifdivisable fizz \else&lt;br /&gt;  \testdivisable{\i}{5}  \ifdivisable buzz \else&lt;br /&gt;  \number \i \fi\fi\fi \par}&lt;br /&gt;&lt;br /&gt;\def\testdivisable#1#2{%&lt;br /&gt;  \a=#1 \b=#2 \c=#1&lt;br /&gt;  \divide \a by \b&lt;br /&gt;  \multiply \a by \b&lt;br /&gt;  \advance \c by -\a&lt;br /&gt;  \ifnum\c=0 \divisabletrue \else \divisablefalse \fi}&lt;br /&gt;&lt;br /&gt;\fizzbuzz{30}&lt;br /&gt;&lt;br /&gt;\vfill&lt;br /&gt;\eject&lt;br /&gt;\end&lt;/pre&gt;（2010.3.23 rudolphさんの指摘を受けて\printffizzbuzzを修正）&lt;br /&gt;&lt;br /&gt;LaTeXじゃなくて素のTeX。これを fizzbuzz.tex のような名前で保存して &lt;code&gt;tex fizzbuzz&lt;/code&gt; と実行すれば dvi ができる。&lt;br /&gt;&lt;br /&gt;整数の計算には、&lt;code&gt;\newcount&lt;/code&gt;コマンドでグローバルなレジスタをいくつか用意して、これを使う。これは文字通りのレジスタ計算で、レジスタに入っている値を&lt;code&gt;advance&lt;/code&gt;や&lt;code&gt;divide&lt;/code&gt;といったコマンドを使って書き換えながら計算を進めていく。&lt;br /&gt;&lt;br /&gt;リストやシーケンスのような気が利いたデータ構造は当然存在しないので、ループを使ってFizzBuzzするしかない。素のTeXでは、&lt;code&gt;\loop... \repeat&lt;/code&gt;という構文が用意されていて、これでループが書ける。&lt;br /&gt;&lt;br /&gt;あとトリッキーなのは、&lt;code&gt;\newif&lt;/code&gt;というマクロを使って&lt;code&gt;\ifdivisable&lt;/code&gt;という特定用途のための条件文を用意するところだろう。まあ、なんていうか、このへんはイディオムなので深く考えない。最初に見るとぎょっとするし、もっとうまい記述方法がないか考えても見るけど、結局こういうイディオムを使って書くのがいちばんしっくりくることに気がつくものだ。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-6251445520828692264?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/6251445520828692264/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=6251445520828692264' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/6251445520828692264'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/6251445520828692264'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2010/03/texfizzbuzz.html' title='TeXでFizzBuzz'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-1733999610011753942</id><published>2010-03-04T16:53:00.004+09:00</published><updated>2010-03-04T17:27:36.972+09:00</updated><title type='text'>pLaTeX+dvipdfmxで基本じゃないOTFフォントを使う</title><content type='html'>ヨドバシカメラのソフト売り場で大枚はたいてOTFフォントを買ったならば、とりあえずpLaTeXでも気軽に使いたい、それもWordくらい気軽に、という話。&lt;br /&gt;&lt;br /&gt;具体的には、「本文のゴシックはヒラギノ基本書体の角ゴW3でいいんだけど、強調したいところで角ゴW4を使いたい。ヒラギノ角ゴW4は買ってきた。原稿で&lt;code&gt;\hirakakufour{モナド}&lt;/code&gt;って使いたい！」という状況がままあって、場当たり的な試行錯誤で「とりあえず」期待どおりの結果は得られているが、なにぶん試行錯誤でたどりついた方法なので正解かどうかはわかりません、つっこみ求む、という話。&lt;br /&gt;&lt;br /&gt;TeXにおけるフォントとは何か、を整理する必要があるので、肝心の手順にいたるまでの説明が長くなります。まずは基礎知識。&lt;dl&gt;&lt;dt&gt;&lt;b&gt;買ってきたフォントの実体は .otf ファイルだけど、TeXが必要としているのは .tfm というファイルである。&lt;/b&gt;（.vf ファイルもあるけど、ややこしいので省略）&lt;/dt&gt;&lt;dd&gt;TeXのソースで指定するのは、あくまでも .tfm ファイルの名前である。.tfm ファイルには、TeXがそのフォントの文字を配置するときの幅とか前後の文字とのアキといった数値情報（メトリック）&lt;b&gt;だけ&lt;/b&gt;が入っている。これはバイナリファイルで、極端にいうとフォントの実体とぜんぜん関係ない値であっても、とにかく数値情報が&lt;a href="http://ascii.asciimw.jp/pb/ptex/tfm/index.html"&gt;決まったフォーマット&lt;/a&gt;でエンコードされていればいい。TeX のコマンド（&lt;code&gt;platex&lt;/code&gt; とか）にとっては、フォントの実体なんて知ったことじゃないのである。TeX の仕事は、各ページへの要素の配置を決めるアルゴリズムを駆使して、その結果を dvi ファイルとして埋め込むだけ。それにはフォントのグリフを並べるのに必要な数値情報だけ知っていればいい。（この「なんでも数値にしてアルゴリズムさえ考え抜けばいいじゃん」という方針をクヌーシズムと称したい。）&lt;/dd&gt;&lt;dt&gt;&lt;b&gt;TeX は、「この要素には○○というフォントを使って！」という情報だけをdviファイルに書き出す。&lt;/b&gt;&lt;/dt&gt;&lt;dd&gt;○○は、この場合は .tmf ファイルの名前。&lt;/dd&gt;&lt;dt&gt;&lt;b&gt;フォントの実体は、dviファイルを解釈するDVIウェアと呼ばれるソフトウェアが扱う。&lt;/b&gt;&lt;/dt&gt;&lt;dd&gt;dvipdfmx や dviout といったDVIウェアが、フォントの実体である .otf ファイルを扱うので、彼らに .tfm ファイルと .otf ファイルとの対応付けを教えなければならない。&lt;/dd&gt;&lt;/dl&gt;&lt;br /&gt;次に、ここでまとめる手順の前提条件。&lt;ul&gt;&lt;li&gt;&lt;a href="http://psitau.at.infoseek.co.jp/otf.html"&gt;OTFパッケージ&lt;/a&gt;を導入ずみ&lt;/li&gt;&lt;li&gt;OpenTypeの&lt;a href="http://www.screen.co.jp/ga_product/sento/sample/hirg4.html"&gt;ヒラギノ角ゴシック体 W4&lt;/a&gt;の実体を HiraKaku-W4.otf という名前で持っている&lt;/li&gt;&lt;li&gt;DVIウェアは dvipdfmx&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;ようやく手順。&lt;ol&gt;&lt;li&gt;何はともあれヒラギノ角ゴW4用の .tfm ファイルが必要。ここが肝要なんだろうけど、&lt;b&gt;まあ角ゴW4のメトリックは角ゴW3とそんなにかわらないはずだよね&lt;/b&gt;、と仮定して、齋藤さんのOTFパッケージの nmlgothb-h.tfm および nmlgothb-h.tfm をそっくりコピーして使わせていただく。このへんが「とりあえず」なゆえん。（もしかするとヒラギノ角ゴW8用の tfm のほうが適切かも。）&lt;pre&gt;$ cd (TEXMF)/fonts/tfm/ptex/otf/otf  # パスとコピー先は各自でてきとうに&lt;br /&gt;$ cp nmlgothb-h.tfm nmlgothlb-h.tfm&lt;br /&gt;$ cp nmlgothb-v.tfm nmlgothlb-v.tfm&lt;/pre&gt;（本来は、メトリックをS式っぽいもので記述したPLファイルというのを作って、それをpltotfというツールで変換してtfmファイルを作るらしいが、自分でやったことはない。OTFパッケージのうれしさは、ヒラギノ基本6書体に対してこれらをすべてお膳立てしてくれることにある。）&lt;/li&gt;&lt;li&gt;dvipdfmxに、.tfm ファイルと .otf ファイルの対応付けを教える。これは、次のような map ファイルを書いて、dvipdfmx の実行時に &lt;code&gt;-f&lt;/code&gt; オプションで指定すればよい。&lt;pre&gt;$ cat hirakakufour.map&lt;br /&gt;nmlgothlb-h    H    HiraKaku-W4.otf&lt;br /&gt;nmlgothlb-v    V    HiraKaku-W4.otf&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;フォントの実体 HiraKaku-W4.otf を、dvipdfmx から見える場所（&lt;code&gt;/usr/share/texmf/dvipdfmx/fonts/&lt;/code&gt; とか）におく。&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;これで、たとえばこんな風にすれば、ヒラギノ角ゴW4を &lt;code&gt;\hirakakufour&lt;/code&gt; コマンドで使えるようになる。&lt;pre&gt;\DeclareFontShape{JY1}{gt}{lb}{n}{&lt;-&gt; nmlgothlb-h}{}&lt;br /&gt;\DeclareFontShape{JT1}{gt}{lb}{n}{&lt;-&gt; nmlgothlb-v}{}&lt;br /&gt;\def\hirakakufour#1{%&lt;br /&gt;  {\usefont{JY1}{gt}{lb}{n}#1}}&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-1733999610011753942?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/1733999610011753942/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=1733999610011753942' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/1733999610011753942'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/1733999610011753942'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2010/03/platexdvipdfmxotf.html' title='pLaTeX+dvipdfmxで基本じゃないOTFフォントを使う'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-3366358091613815326</id><published>2009-12-30T21:28:00.003+09:00</published><updated>2009-12-30T22:05:04.168+09:00</updated><title type='text'></title><content type='html'>年賀状かいた。&lt;br /&gt;&lt;pre&gt;%!&lt;br /&gt;&lt;&lt; /PageSize [285 420] &gt;&gt; setpagedevice&lt;br /&gt;&lt;br /&gt;1 1 25 {&lt;br /&gt;    /n exch def&lt;br /&gt;    0 12 360 { % for&lt;br /&gt;        /i exch def&lt;br /&gt;&lt;br /&gt;        newpath&lt;br /&gt;        gsave&lt;br /&gt;            /r1 {rand 5 mod 2 div} def&lt;br /&gt;            /r2 {rand 2 mod 2 div} def&lt;br /&gt;            /r3 {rand 2 mod 2 div} def&lt;br /&gt;            r1 r2 r3 setrgbcolor&lt;br /&gt;            140 220 moveto&lt;br /&gt;            i rotate&lt;br /&gt;            /Times-Bold findfont 10 scalefont setfont&lt;br /&gt;            (                          ) show&lt;br /&gt;            0 10 20 { % for&lt;br /&gt;                /j exch def&lt;br /&gt;                /AgentOrange findfont j 12 add scalefont setfont&lt;br /&gt;                (2) show&lt;br /&gt;                /AgentOrange findfont j 14 add scalefont setfont&lt;br /&gt;                (0) show&lt;br /&gt;                /AgentOrange findfont j 16 add scalefont setfont&lt;br /&gt;                (1) show&lt;br /&gt;                /AgentOrange findfont j 18 add scalefont setfont&lt;br /&gt;                (0) show&lt;br /&gt;            } for&lt;br /&gt;        grestore&lt;br /&gt;    } for&lt;br /&gt;    220 45 moveto&lt;br /&gt;    /Georgia-BoldItalic findfont 10 scalefont setfont&lt;br /&gt;    n =string cvs show&lt;br /&gt;    (/25) show&lt;br /&gt;    showpage &lt;br /&gt;} for&lt;/pre&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/k16/4227589719/" title="DSC_0178 by Keiichirou Shikano, on Flickr"&gt;&lt;img src="http://farm5.static.flickr.com/4015/4227589719_9af34c98ac_m.jpg" width="240" height="160" alt="DSC_0178" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;こちらのAgentOrangeというフリーフォントを使わせていただきました。ありがとうございます。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.1001freefonts.com/AgentOrange.php"&gt;http://www.1001freefonts.com/AgentOrange.php&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-3366358091613815326?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/3366358091613815326/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=3366358091613815326' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/3366358091613815326'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/3366358091613815326'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2009/12/setpagedevice-1-1-25-n-exch-def-0-12.html' title=''/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm5.static.flickr.com/4015/4227589719_9af34c98ac_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-2380399481864750734</id><published>2009-12-28T16:58:00.005+09:00</published><updated>2009-12-28T17:08:40.825+09:00</updated><title type='text'>Gauche の CGI スクリプトを lighttpd + FastCGI で動かす手順</title><content type='html'>Gauche の CGI スクリプトを lighttpd + FastCGI で動かす手順。自分用の備忘録。&lt;br /&gt;&lt;br /&gt;FastCGI は、Web サーバと外部プログラム間のやり取りを規定した一種のプロトコル。外部プログラムは起動しっぱなしになっていて、Web サーバは、その起動しっぱなしのプロセスと必要に応じてやり取りする。したがって、外部プログラムには、起動しっぱなしで Web サーバとおしゃべりできる仕組みが必要で、Web サーバのほうも、そんな外部プログラムとおしゃべりできないといけない。&lt;br /&gt;&lt;br /&gt;外部プログラム側で必要となる仕掛けは、Gauche の場合、&lt;a href="http://practical-scheme.net/wiliki/wiliki.cgi?Gauche:Packages#H-y4wpo8"&gt;Gauche-fastcgi&lt;/a&gt; が提供する &lt;tt&gt;with-fastcgi&lt;/tt&gt; という関数で &lt;tt&gt;cgi-main&lt;/tt&gt; をくるむだけでいい。Gauche-fastcgi のインストールには FastCGI の開発ツールキットが必要。&lt;br /&gt;&lt;br /&gt;Web サーバのほうは、lighttpd を使う場合、&lt;tt&gt;mod_fastcgi&lt;/tt&gt; を有効にして、しかるべき設定をする。lighttpd の設定ファイルは &lt;tt&gt;/etc/lighttpd/lighttpd.conf&lt;/tt&gt; なので、まあこれを編集してもいいのだけれど、Debian では &lt;tt&gt;lighty-enable-mod&lt;/tt&gt; というユーティリティがあるのでこれを使う。具体的には、&lt;tt&gt;/etc/lighttpd/conf-available/&lt;/tt&gt; 以下に &lt;tt&gt;nn-name.conf&lt;/tt&gt; という形式の名前を付けたファイルで設定の断片を用意し（&lt;tt&gt;nn&lt;/tt&gt; は優先順、&lt;tt&gt;name&lt;/tt&gt; は名前）、&lt;tt&gt;lighty-enable-mod name&lt;/tt&gt; を実行する。最初から用意されている &lt;tt&gt;nn-name.conf&lt;/tt&gt; ファイルもいくつかあって、&lt;tt&gt;10-fastcgi.conf&lt;/tt&gt; という FastCGI 用のものもあるけれど、きっと Gauche で書いた FastCGI スクリプトには対応していない。だから、代わりに次のような内容の &lt;tt&gt;10-fastcgi.conf&lt;/tt&gt; を用意する。&lt;br /&gt;&lt;pre&gt;server.modules   += ( "mod_fastcgi" )&lt;br /&gt;&lt;br /&gt;fastcgi.server    = (&lt;br /&gt;        "sample.fcgi" =&gt; ((&lt;br /&gt;                "host" =&gt; "127.0.0.1",&lt;br /&gt;                "port" =&gt; 1026&lt;br /&gt;        )),&lt;br /&gt;        "index.fcgi" =&gt; ((&lt;br /&gt;                "host" =&gt; "127.0.0.1",&lt;br /&gt;                "port" =&gt; 1027&lt;br /&gt;        ))&lt;br /&gt;)&lt;br /&gt;&lt;/pre&gt;&lt;tt&gt;sample.fcgi&lt;/tt&gt; や &lt;tt&gt;index.fcgi&lt;/tt&gt; が、 Gauche で書いた実行可能なスクリプトのファイル名。この設定は、「クライアントから &lt;tt&gt;sample.fcgi&lt;/tt&gt; を要求されたら、localhost 上のポート 1026 で動きっぱなしの &lt;tt&gt;sample.fcgi&lt;/tt&gt; に処理させますよ」などと読む。というわけで、事前に localhost 上のポート 1026 で &lt;tt&gt;sample.fcgi&lt;/tt&gt; を動きっぱなしにしておく必要がある。そのために使うのは &lt;a href="http://redmine.lighttpd.net/projects/spawn-fcgi/wiki"&gt;&lt;tt&gt;spawn-fcgi&lt;/tt&gt;&lt;/a&gt; という lighttpd に付属するコマンド。&lt;pre&gt;$ sudo spawn-fcgi -f /var/www/sample.fcgi -p 1026 -u www-data -g www-data&lt;br /&gt;$ sudo spawn-fcgi -f /var/www/index.fcgi -p 1027 -u www-data -g www-data&lt;/pre&gt;これで、FastCGI でのおしゃべりをポート 1026 （あるいは 1027）で待ち受けるプロセスが立ち上がる。なお、&lt;tt&gt;sample.fcgi&lt;/tt&gt; や &lt;tt&gt;index.fcgi&lt;/tt&gt; に実行権限が付与されてないと（&lt;tt&gt;chmod 755&lt;/tt&gt; されてないと）、&lt;tt&gt;spawn-fcgi&lt;/tt&gt; がエラーになる。また、Gauche のエラーでプロセスが死んでも &lt;tt&gt;spawn-fcgi&lt;/tt&gt; そのものは成功してしまうので、&lt;tt&gt;spawn-fcgi&lt;/tt&gt; の実行後に &lt;tt&gt;ps awx | grep gosh&lt;/tt&gt; して起動しっぱなしのプロセスがあることを確認したほうがいい。&lt;br /&gt;&lt;br /&gt;この後、lighttpd を起動する。すでに起動していて再起動する場合は、設定ファイルの再読み込みもしておく。&lt;br /&gt;&lt;pre&gt;$ sudo /etc/init.d/lighttpd force-reload&lt;br /&gt;$ sudo /etc/init.d/lighttpd restart&lt;br /&gt;&lt;/pre&gt;これで準備はおしまい。リロードしまくっても新しい gosh プロセスが毎回起動しなければOK。&lt;br /&gt;&lt;br /&gt;なお、この手順は、事前に動きっぱなしにしておいた外部プログラムをIPアドレスとポートで識別する方法。識別に UNIX ドメインソケットを使うこともできる。また、外部プログラムを事前に起動しておかず、初回は lighttpd から起動させることもできる。細かい話は lighttpd の &lt;a href="http://redmine.lighttpd.net/wiki/1/Docs:ModFastCGI"&gt;&lt;tt&gt;mod_fastcgi&lt;/tt&gt; のドキュメント&lt;/a&gt;にいろいろと書いてあった。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-2380399481864750734?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/2380399481864750734/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=2380399481864750734' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/2380399481864750734'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/2380399481864750734'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2009/12/gauche-cgi-lighttpd-fastcgi.html' title='Gauche の CGI スクリプトを lighttpd + FastCGI で動かす手順'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-4424233627822750305</id><published>2009-07-29T12:12:00.005+09:00</published><updated>2011-02-10T15:13:10.382+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PHS Willcom Debian'/><title type='text'>DebianでWillcom端末からPPP接続</title><content type='html'>Debian/GNU Linux（squeeze）に Willcom の PHS 電話端末 AH-J3003S（ウィルコム定額プランで契約）を USB でつなぎ、契約なしで利用できるプロバイダ PRIN にダイアルアップして PPP でインターネットに接続するときのメモ。&lt;br /&gt;&lt;br /&gt;まず、避けて通れないプロバイダについて。Willcom 端末からのダイヤルアップ接続には、事前契約が不要な PRIN というプロバイダが使える。使えるんだけど、ずっと料金体系や支払い方法がよくわからず、こわくて使ってなかった。最近になって Windows XP から勇気を出して使ってみたところ、ちょっと外出先で接続するくらいなら気にならない程度の金額だとわかったので、Debianマシンでも使ってみることにした。気になるお値段は&lt;a href="http://www.prin.ne.jp/service/service.html"&gt;PRIN／サービス案内&lt;/a&gt;に一覧表がある。Willcom の電話端末を「ウィルコム定額プラン」で契約していれば、「リアルインターネットプラス」を契約していなくても 10円/分 くらい。料金の支払いは、電話料金と一緒に引かれているっぽい（金額が微妙でよくわからないけど、ほかから請求がこないので）。&lt;br /&gt;&lt;br /&gt;AH-J3001S という端末は、Linux Kernel からは ACM デバイスとして認識される。cdc-acm モジュールが有効になっていれば、USB ケーブルでつなぐだけで、こんな感じに認識されるはず。&lt;pre&gt;$ tail /var/log/messages&lt;br /&gt;...&lt;br /&gt;... cdc_acm 4-2:1.0: ttyACM0: USB ACM device&lt;br /&gt;... usb 4-2: New USB device found, idVendor=1145, idProduct=0001&lt;br /&gt;... usb 4-2: New USB device strings: Mfr=0, Product=0, SerialNumber=0&lt;br /&gt;...&lt;/pre&gt;というわけで、必要な作業は、PPP の設定のみ。&lt;br /&gt;&lt;br /&gt;Debian での PPP 接続には ppp パッケージが必要。それと、設定ファイルを編集する pppconfig というユーティリティーを使いたいので、 pppconfig パッケージもインストールする。&lt;pre&gt;$ sudo apt-get install ppp pppconfig&lt;/pre&gt;インストールできたら、pppconfig を使って、モデムのデバイスファイルやプロバイダの情報（ダイアルアップ先やユーザ名やパスワードなんか）を設定する。モデムのデバイスは /dev/ACM0 にする。プロバイダがらみの設定値は、&lt;a href="http://www.prin.ne.jp/service/service.html"&gt;PRIN／サービス案内&lt;/a&gt;（アクセスポイント一覧がある）や&lt;a href="http://www.prin.ne.jp/setup/dial/d_w_xp.html"&gt;PRIN／各種設定・利用案内&lt;/a&gt;（Windows XP のウィザード設定画面の説明がある）とかから探せば見つかる。&lt;br /&gt;&lt;br /&gt;pppconfig による設定は /etc/ppp/peers/ および /etc/chatscripts/ 以下にテキストファイルとして保存される。手元の設定結果はこんな感じ。&lt;pre&gt;$ cat /etc/ppp/peers/willcom&lt;br /&gt;# This optionfile was generated by pppconfig 2.3.18.&lt;br /&gt;#&lt;br /&gt;#&lt;br /&gt;hide-password&lt;br /&gt;noauth&lt;br /&gt;connect "/usr/sbin/chat -v -f /etc/chatscripts/willcom"&lt;br /&gt;debug&lt;br /&gt;/dev/ttyACM0&lt;br /&gt;115200&lt;br /&gt;defaultroute&lt;br /&gt;noipdefault&lt;br /&gt;user "prin"&lt;br /&gt;&lt;br /&gt;ipparam willcom&lt;br /&gt;&lt;br /&gt;usepeerdns&lt;/pre&gt;&lt;pre&gt;$ cat /etc/chatscripts/willcom&lt;br /&gt;# This chatfile was generated by pppconfig 2.3.18.&lt;br /&gt;# Please do not delete any of the comments.  Pppconfig needs them.&lt;br /&gt;#&lt;br /&gt;# ispauth CHAP&lt;br /&gt;# abortstring&lt;br /&gt;ABORT BUSY ABORT 'NO CARRIER' ABORT VOICE ABORT 'NO DIALTONE' ABORT 'NO DIAL TONE' ABORT 'NO ANSWER' ABORT DELAYED&lt;br /&gt;# modeminit&lt;br /&gt;'' ATZ&lt;br /&gt;# ispnumber&lt;br /&gt;OK-AT-OK "ATDT0570570611##61"&lt;br /&gt;# ispconnect&lt;br /&gt;CONNECT \d\c&lt;br /&gt;# prelogin&lt;br /&gt;&lt;br /&gt;# ispname&lt;br /&gt;# isppassword&lt;br /&gt;# postlogin&lt;br /&gt;&lt;br /&gt;# end of pppconfig stuff&lt;/pre&gt;なお、このファイルには書き出されてないけど、プロバイダのパスワードにはユーザ名と同じ prin を設定する（公開情報）。&lt;br /&gt;&lt;br /&gt;で、いよいよ接続するには pon コマンドを使う（利用するユーザは dip グループに入っていないといけない）。&lt;pre&gt;$ pon willcom&lt;/pre&gt;willcom の部分は、pppconfig による設定の際に指定する設定名。これは /etc/ppp/peers/ なんかの下にあるファイル名でもある。ifconfig してみると ppp0 みたいな名前のインタフェースが新たに現れているはず。切断は poff で。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-4424233627822750305?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/4424233627822750305/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=4424233627822750305' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/4424233627822750305'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/4424233627822750305'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2009/07/debiangnu-linuxsqueeze-willcom-phs-ah.html' title='DebianでWillcom端末からPPP接続'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-7050010655517020029</id><published>2009-07-10T18:18:00.002+09:00</published><updated>2009-07-10T18:21:44.451+09:00</updated><title type='text'>LaTeX におけるページをまたいだ囲み記事スタイルのまとめ</title><content type='html'>LaTeX でページをまたいだ囲み記事を実現するスタイルはいくつかあって、今のところ回避困難な制限がある。そのまとめ。&lt;br /&gt;&lt;br /&gt;基本は &lt;a href="http://tug.ctan.org/tex-archive/macros/latex/contrib/misc/"&gt;framed.sty&lt;/a&gt; だろう。角が四角くてもいいなら、これがいちばん素性がいい感じ。ただし、ページをまたぐときに、前のページの末尾と次のページの先頭に罫線が入る。標準的なパッケージなので、いろんな環境で利用できる可能性が高い。たぶん中身をボックスにいれて \vsplit で一行ずつページを構成する垂直ボックスに渡していく方式。&lt;br /&gt;&lt;br /&gt;もうひとつ、 &lt;a href="http://y-nam.hp.infoseek.co.jp/sub4.html#style"&gt;eclbkbox.sty&lt;/a&gt; というのもある。これはページをまたぐ箇所に罫線が入らない。これもやはり角は四角い。これも \vsplit を使う方式。&lt;br /&gt;&lt;br /&gt;同じく \vsplit を使ったページ分割手法で、しかも角丸に対応したスタイルとして、&lt;a href="http://emath.s40.xrea.com/ydir/Wiki/index.php?breakitembox%B4%C4%B6%AD"&gt;emath の itembkbx.sty&lt;/a&gt; と &lt;a href="http://ideotype.svn.sourceforge.net/viewvc/ideotype/trunk/lib/multipagebox.sty"&gt;multipagebox.sty&lt;/a&gt; がある。&lt;br /&gt;&lt;br /&gt;さて、以上の4つのパッケージには共通する悩ましい制約条件がある。&lt;b&gt;\footnote がまったく使えない。&lt;/b&gt;翻訳なんかだと囲み記事に脚注入れたい場合もあるというのに、いれられない。いろいろ回避策を考えてみたけど、\vsplit を使うにはいったん囲み記事にしたい中身をボックスに入れるしかなく、その時点で \footnote を見るしかなくて、\vsplit するときには手の出しようがない。そもそも \vsplit はインサートの分割アルゴリズムを利用するためのプリミティブだから、やはりインサートである \footnote に対応できなくてもしょうがないか（実際には直接の関係はないけど）。&lt;br /&gt;&lt;br /&gt;以下のようにして簡単に \footnote を有効にできる場合がある（全部試してない。使えない環境も多々あるはず）。&lt;pre&gt;\newtoks\mftn&lt;br /&gt;\def\mfootnote#1{%&lt;br /&gt;  \footnotemark&lt;br /&gt;  \edef\@tempa{\the\mftn\noexpand\footnotetext[\the\c@footnote]}%&lt;br /&gt;  \global\mftn\expandafter{\@tempa{#1}}}%&lt;br /&gt;\def\mfootnoteout{%&lt;br /&gt;  \the\mftn&lt;br /&gt;  \global\mftn{}}&lt;br /&gt;&lt;br /&gt;\begin{...}&lt;br /&gt;  \let\footnote\mfootnote&lt;br /&gt;  ...&lt;br /&gt;\end{...}&lt;br /&gt;\mfootnoteout&lt;/pre&gt;ただしこの回避策だと、\footnote の項目がページごとではなく最後のページにまとめて出てしまう。まあ、最後の手段ということで。&lt;br /&gt;&lt;br /&gt;ページをまたぐ囲み記事で、しかも \footnote に完全対応する方法として、longtable.sty を使って独自の環境をでっちあげるという手がある。（&lt;a href="http://note.golden-lucky.net/2006/01/latex-screenminipagefootnoteknooth-web.html"&gt;例&lt;/a&gt;。汎用性がないのでそのままの状態ではたぶん利用不可能。囲み記事の段落を longtable の行に対応させるという荒業のため、段落ごとにしか改ページできない。これが最大の難点。でもまあ、この \longtable を使う方法の難点こそが、\footnote をページごとに出力するための直接の代償でもあるわけだ。）&lt;br /&gt;&lt;br /&gt;というわけで、だれか footnote を華麗に再定義して footnoteanyware.sty みたいなのを作ってください。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-7050010655517020029?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/7050010655517020029/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=7050010655517020029' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/7050010655517020029'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/7050010655517020029'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2009/07/latex.html' title='LaTeX におけるページをまたいだ囲み記事スタイルのまとめ'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-4953222988176366331</id><published>2009-06-22T13:24:00.001+09:00</published><updated>2009-06-22T13:30:50.415+09:00</updated><title type='text'>Lisp!</title><content type='html'>Golden Lucky - Lisp (via Keiichirou Shikano) &lt;br /&gt;&lt;a href="http://www.flickr.com/photos/k16/3649649944/" title="Lisp by Keiichirou Shikano, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2449/3649649944_757720c58b_m.jpg" width="186" height="240" alt="Lisp" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;発作的に作ってしまった。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-4953222988176366331?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/4953222988176366331/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=4953222988176366331' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/4953222988176366331'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/4953222988176366331'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2009/06/lisp.html' title='Lisp!'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm3.static.flickr.com/2449/3649649944_757720c58b_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-1802053638691272295</id><published>2009-05-24T15:46:00.002+09:00</published><updated>2009-05-24T15:48:49.439+09:00</updated><title type='text'>Goodby Bafana</title><content type='html'>『マンデラの名もなき看守』を見た。見ることができた。赤ちゃんがいると映画館にいく機会は限られるのだけど、今日はたまたまそういうチャンスだった。そして、たまたま今週の早稲田松竹のラインナップが『マンデラの名もなき看守』だった。ついてた。&lt;br /&gt;&lt;br /&gt;映画では、旧体制の南アにおける黒人差別政策についてどうこう言うこともなく、看守としてマンデラとかかわるたびに気がついたら人生の窮地に立っている男とその家族の話をテンポよくつないで、1990年2月11日の釈放シーンで締めくくっている。じわじわくる。ラストまでのエピソードのおかげで、最後の"goodbye bafana"というセリフの手前くらいで涙が出そうになる。そして釈放シーンの看守の奥様がとてもきれい。この2つのシーンは、もっと感動的に演出してもよさそうなものだけど、これでちょうどよかったのだろうな。&lt;br /&gt;&lt;br /&gt;現代史に散らばっている社会問題って、「かわいそう」駆動型の活動や「正義感」駆動型の行為、あるいは思考停止になりがちだ。自分は正直なところ思考停止していると思う。それを「娯楽」の形で消化する贅沢に折り合いを付けるのは難しいし、たぶん付かない。『ホテルルワンダ』もそうだった。でも、たとえばダライ・ラマ14世の亡命後の半生を描いた映画ができれば、きっと見に行く。贅沢はくせになる。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-1802053638691272295?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/1802053638691272295/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=1802053638691272295' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/1802053638691272295'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/1802053638691272295'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2009/05/goodby-bafana.html' title='Goodby Bafana'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-981863434945004544</id><published>2009-05-23T10:09:00.002+09:00</published><updated>2009-05-23T10:12:48.700+09:00</updated><title type='text'>A rant about happiness</title><content type='html'>タイ料理屋でしこたまのみながら、「幸福」を定義した。&lt;br /&gt;手元にメモが残っているので、思い出しつつ書き起こしておく。&lt;br /&gt;&lt;br /&gt;「幸福」とは何かよくわからないので、まずは「幸福でない」について考えよう。&lt;br /&gt;&lt;br /&gt;レベル1の「幸福でない」とは、幸福の軸が定まっていて、幸福の側にいない状態。&lt;br /&gt;レベル2の「幸福でない」とは、レベル1の「幸福でない」を定めるすべがない状態。つまり、この場合は、レベル1における幸福の軸を見出せていない状態。&lt;br /&gt;&lt;br /&gt;この定義から、レベルnの「幸福でない」を自然に拡張できる。&lt;br /&gt;レベルnの「幸福でない」とは、レベルn-1の「幸福でない」を定めるすべがない状態だ。&lt;br /&gt;&lt;br /&gt;で、レベルωの「幸福でない」とは何かを考えてみる。ωは最初の可算無限基数。たぶん、任意の可算基数レベルの「幸福でない」を定めるすべがない状態、なんだろうな。&lt;br /&gt;&lt;br /&gt;ということは、ある可算基数があって、そのレベルで「幸福でない」を定めるすべがあれば、レベルωで「幸福でない」ではないといえる。「幸福でない」の逆が「幸福」とは限らないけど、まあ、「幸福になりうる」っていうくらいならいいだろう。とくに、レベル1で「幸福でない」を定めるすべがあれば、レベルωで幸福になりうる。&lt;br /&gt;&lt;br /&gt;ここまで書いて気づいたけど、べつに無限基数まで拡張する必要なかったか。&lt;br /&gt;レベル1で「幸福でない」を定めるすべがあれば、どんなレベルでも幸福になりうる。&lt;br /&gt;&lt;br /&gt;ところで、いまうちらはレベル1の「幸福でない」を定めるすべを持っている。実際、定めることができている。したがって、うちらはどんなレベルでも幸福になりうる。&lt;br /&gt;&lt;br /&gt;おや、なんだかあたりまえの結論じゃないか。&lt;br /&gt;そんな話だったっけかなあ。これだから酔っ払いは。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-981863434945004544?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/981863434945004544/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=981863434945004544' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/981863434945004544'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/981863434945004544'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2009/05/1-211-n-nn-1-1-1-1.html' title='A rant about happiness'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-862945610587031403</id><published>2009-04-23T17:20:00.005+09:00</published><updated>2011-02-10T14:46:32.771+09:00</updated><title type='text'>LaTeXでSubversionのキーワード展開を使うパッケージ</title><content type='html'>LaTeX で Subversion のメタ情報（つまり、$Id$ とかのキーワード展開）を使いたい。&lt;br /&gt;&lt;br /&gt;Subversion におけるキーワード展開について基本をまとめると、たぶんこんな感じ。&lt;ul&gt;&lt;li&gt;各ファイルの&lt;a href="http://svnbook.red-bean.com/en/1.0/svn-book.html#svn-ch-7-sect-2.3.4"&gt;svn:keywords属性&lt;/a&gt;を展開したいキーワードに設定する。&lt;/li&gt;&lt;li&gt;原稿ファイル中にある $Id: ... $ などが展開されるのは、svn checkout や svn update でリポジトリの変更を取ってきた時点。&lt;/li&gt;&lt;/ul&gt;困っちゃうのは、ファイルごとにしかメタ情報を使えないところ。LaTeX で原稿を複数のファイルに分けて執筆している場合に、1ページめに原稿全体としての最新リビジョンを出力するようなことができない。1ページめをコンパイルする時点では、そのページの元になっている *.tex ファイルの $Id: ... $ しか展開されなからだ。後ろのほうのファイルだけが更新されたら、その新しいリビジョン番号には追随できなくなってしまう。&lt;br /&gt;この悩みを解決する LaTeX のパッケージがいくつかある。&lt;a href="http://www.ctan.org/tex-archive/macros/latex/contrib/svn-multi/"&gt;svn-multi&lt;/a&gt; が新しいめで高機能そうなんだけど、今回は &lt;a href="http://www.ctan.org/tex-archive/macros/latex/contrib/svninfo/"&gt;svninfo&lt;/a&gt; を使うことにした。&lt;b&gt;以下は備忘録。&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;book.tex から zenhan.tex と kouhan.tex を include していて、Id キーワードの情報が使いたいとする。&lt;pre&gt;% プリアンブルいろいろ&lt;br /&gt;\begin{document}&lt;br /&gt;\include{zenhan}&lt;br /&gt;\include{kouhan}&lt;br /&gt;\end{document}&lt;/pre&gt;まずは svninfo パッケージを利用できるようにする。\usepackage{svninfo} は \begin{document} の&lt;b&gt;直前&lt;/b&gt;に置かないといけないようだ。&lt;pre&gt;% プリアンブルいろいろ&lt;br /&gt;\usepackage{svninfo}&lt;br /&gt;\begin{document}&lt;br /&gt;\include{zenhan}&lt;br /&gt;\include{kouhan}&lt;br /&gt;\end{document}&lt;/pre&gt;つぎに以下のような行を zenhan.tex と kouhan.tex に追記する。&lt;b&gt;最後の $ のあとにスペース必須。&lt;/b&gt; "file rev YYYY-MM-DD hh:mm:ss owner" の部分は、現在のファイルの情報（svn log -rHEAD zenhan.tex とかで得られる情報）か何かを手書きしておく。&lt;pre&gt;\svnInfo $Id: file rev YYYY-MM-DD hh:mm:ss owner $ ← スペースあり&lt;/pre&gt;忘れずに svn:keywords を設定してコミット。&lt;pre&gt;&gt; svn propset svn:keywords "Id" *.tex&lt;br /&gt;&gt; svn commit -m"added svnInfo Id"&lt;/pre&gt;準備はこれでOK。この情報を LaTeX で出力するには、\svnId とか \svnInfoRevision といった svninfo のコマンドを使う。&lt;br /&gt;複数のファイルにある $Id: ... $ を全部チェックして最新のリビジョン番号をとってきてくれる \svnInfoMaxRevision というコマンドもある。この \svnInfoMaxRevision をzenhan.tex に書いておけば、最新のリビジョンで更新されたのが kouhan.tex だけでも、その最新のリビジョン番号に展開される。たとえば、zenhan.tex に対する最後の変更がリビジョン 1000 で、kouhan.tex だけが 1001 で変更されたとすると、どんなに svn up しても zenhan.tex にある $Id: ... $ の部分はリビジョン 1000 に相当する情報にしか展開されない。ところが \svnMaxRevision のほうは 1001 に展開されてくれる。&lt;br /&gt;svninfo に用意されているほかのコマンドは、マニュアルのPDFを参照。&lt;br /&gt;&lt;br /&gt;The svninfo package（PDMマニュアル）&lt;br /&gt;&lt;a href="http://ftp.yz.yamagata-u.ac.jp/pub/CTAN/macros/latex/contrib/svninfo/svninfo.pdf"&gt;http://ftp.yz.yamagata-u.ac.jp/pub/CTAN/macros/latex/contrib/svninfo/svninfo.pdf&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-862945610587031403?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/862945610587031403/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=862945610587031403' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/862945610587031403'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/862945610587031403'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2009/04/latex-subversion-id-subversion.html' title='LaTeXでSubversionのキーワード展開を使うパッケージ'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-8584296130462225134</id><published>2009-04-21T17:19:00.001+09:00</published><updated>2009-04-21T17:19:57.042+09:00</updated><title type='text'></title><content type='html'>Gauche の string-split が便利だ。便利なんだけど、セパレータとしてプロシージャを渡したとき、文字列にある各文字に対してプロシージャが順番に呼ばれないっぽいのが困る。&lt;br /&gt;まずはふつうの例。こんな文字列があったとき、&lt;pre&gt;(define text-with-block&lt;br /&gt;  "words, |entering a block|, got out of the block.")&lt;/pre&gt;スペースかどうか判断するプロシージャを is-space? 渡して、この文字列をぶったぎりたい。&lt;pre&gt;(define is-space? (pa$ char=? #\space))&lt;br /&gt;(string-split text-with-block is-space?)&lt;br /&gt;=&gt; ("words," "|entering" "a" "block|," "got" "out" "of" "the" "block.")&lt;/pre&gt;これは問題ない。&lt;br /&gt;今度は、文字列のうちで縦棒 "|" でくくられている部分を塊とみなし、その内部にあるスペースは無視したいとする。つまりこんな結果がほしい。&lt;Pre&gt;(string-split text-with-block is-isolated-space?)&lt;br /&gt;=&gt; ("words," "|entering a block|," "got" "out" "of" "the" "block.")&lt;/pre&gt;クロージャーの出番です。is-isolated-space? はこんな定義でいいだろう。&lt;pre&gt;(define is-isolated-space?&lt;br /&gt;  (let ((inblock? #f))&lt;br /&gt;    (lambda (c)&lt;br /&gt;      (cond ((char=? c #\|)&lt;br /&gt;             (set! inblock? (if inblock? #f #t))&lt;br /&gt;             #f)&lt;br /&gt;            (inblock?&lt;br /&gt;             #f)&lt;br /&gt;            ((char=? #\space c)&lt;br /&gt;             #t)&lt;br /&gt;            (else&lt;br /&gt;             #f)))))&lt;/pre&gt;実際、 text-with-block に対して is-isolated-space? を繰り返し呼べば、縦棒 "|" でくくられた内部がセパレータとみなされないことが確かめられる。&lt;pre&gt;(let R ((ls (string-&gt;list text-with-block)))&lt;br /&gt;  (cond ((null? ls)&lt;br /&gt;         '())&lt;br /&gt;        ((is-isolated-space? (car ls))&lt;br /&gt;         (cons 1 (R (cdr ls))))&lt;br /&gt;        (else&lt;br /&gt;         (cons 0 (R (cdr ls))))))&lt;br /&gt;=&gt; (0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 1 0 0 0 1 0 0 0 0 0 0)&lt;/pre&gt;見づらいけど、 "|entering a block|," の位置に相当する部分がぜんぶゼロになっているのがポイント。&lt;br /&gt;だから、string-split に渡したプロシージャが文字列にある各文字に対して順番に呼ばれるなら、目的の結果が得られるはず。でも得られない。&lt;pre&gt;(string-split text-with-block is-isolated-space?)&lt;br /&gt;=&gt; ("words," "|entering" "a" "block|, got out of the block.")&lt;/pre&gt;しかも、もういっかい呼び出すと結果が変わる。&lt;pre&gt;=&gt; ("words, |entering" "a" "block|, got out of the block.")&lt;/pre&gt;ということは、各文字ごとに is-isolated-space? の抱えているクロージャがクリアされているわけではないんだよな。2回目の呼び出しでは、inblock? の初期値が #t になっているようだ。&lt;br /&gt;ちなみに、&lt;a href="http://gauche.sourceforge.jp/doc/gauche-refj_71.html#IDX367"&gt;マニュアル&lt;/a&gt;にはこうある。&lt;pre&gt;&lt;br /&gt;splitter に手続きが与えられた場合、string にある各文字に対してその手続きが呼ばれ、&lt;br /&gt;splitter が真の値を返すような連続した文字群がデリミタとして使われます。 &lt;/pre&gt;また、ソースの stringutil.scm にある string-split の定義を見ると、ふつうに文字列の先頭から各文字をプロシージャーで処理してるっぽい。なにがおかしいのかなあー。&lt;br /&gt;仕方がないので代わりの関数をでっちあげる。&lt;pre&gt;(define (string-split-by str proc)&lt;br /&gt;  (let ((n (string-index str proc)))&lt;br /&gt;    (if n&lt;br /&gt;        (receive (h r)&lt;br /&gt;          (values&lt;br /&gt;           (string-take str n)&lt;br /&gt;           (string-drop str n))&lt;br /&gt;          (if (= (string-length r) 0)&lt;br /&gt;              '()&lt;br /&gt;              (if (&gt; n 0)&lt;br /&gt;                  (cons h (string-split-by (string-drop r 1) proc))&lt;br /&gt;                  (string-split-by (string-drop r 1) proc))))&lt;br /&gt;        `(,str))))&lt;br /&gt;&lt;br /&gt;(string-split-by text-with-block is-isolated-space?)&lt;br /&gt;=&gt; ("words," "|entering a block|," "got" "out" "of" "the" "block.")&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-8584296130462225134?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/8584296130462225134/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=8584296130462225134' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/8584296130462225134'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/8584296130462225134'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2009/04/gauche-string-split-define-text-with.html' title=''/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-2520652099312525047</id><published>2008-12-30T14:53:00.002+09:00</published><updated>2008-12-30T15:00:35.723+09:00</updated><title type='text'></title><content type='html'>ようやく年賀状を作る。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/k16/3149151075/" title="DSC_0201 by Keiichirou Shikano, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3124/3149151075_f1674894d7_m.jpg" width="240" height="160" alt="DSC_0201" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;どうみても&lt;a href="http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-15.html#%_sec_2.2.4"&gt;図形言語&lt;/a&gt;です。&lt;br /&gt;&lt;br /&gt;にしても今年は一年中なんだか余裕がなかった。来年はなんとかする。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-2520652099312525047?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/2520652099312525047/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=2520652099312525047' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/2520652099312525047'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/2520652099312525047'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2008/12/blog-post.html' title=''/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm4.static.flickr.com/3124/3149151075_f1674894d7_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-3644576704776755831</id><published>2008-09-26T18:48:00.002+09:00</published><updated>2008-09-26T18:54:27.310+09:00</updated><title type='text'></title><content type='html'>Scheme どう書く？的 - ひげぽん OSとか作っちゃうかMona-&lt;br /&gt;&lt;a href="http://d.hatena.ne.jp/higepon/20080925/1222326246"&gt;http://d.hatena.ne.jp/higepon/20080925/1222326246&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;こんなことをしていられる状況ではないんだけど、mapAccumLを使いたい衝動を抑えられなかった。&lt;pre&gt;compactNumberList :: [Int] -&gt; [[Int]]&lt;br /&gt;compactNumberList = snd . partition ([]==) . tail . snd . mapAccumL collect [-1] . (++[-1])&lt;br /&gt;    where collect xx@(x:xs) y | y - x == 1 = (y:xx, [])&lt;br /&gt;                              | xs ==[]    = ([y], [x])&lt;br /&gt;                              | otherwise  = ([y], [last xx, head xx])&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-3644576704776755831?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/3644576704776755831/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=3644576704776755831' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/3644576704776755831'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/3644576704776755831'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2008/09/scheme-osmona-httpd.html' title=''/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-4052033138804687858</id><published>2008-09-12T01:17:00.002+09:00</published><updated>2008-09-12T01:21:37.093+09:00</updated><title type='text'></title><content type='html'>IO型は、使うだけなら簡単に思える。たとえば String -&gt; IO () という型の putStr に文字列を渡せば、それが画面に印字される。&lt;pre&gt;&lt;font color="blue"&gt;Main &gt;&lt;/font&gt;&lt;b&gt;putStr "abcdef\n"&lt;/b&gt;&lt;br /&gt;abcdef&lt;/pre&gt;putStr の出力は IO () 型なので、結果として印字された「abcdef」は文字列ではない。じゃあ、IO () 型の出力はどこにいったんだろう？ Show クラスのインスタンスがないということ？ でも、だとしたらGHCがエラーを出力するんじゃなかったっけ？ &lt;br /&gt;&lt;br /&gt;とにかく絶対に IO () な何かが関数の結果として返ってきているはずなので、IO () -&gt; String な関数を定義してそれに putStr をつないでみた。&lt;pre&gt;vacant :: IO () -&gt; String&lt;br /&gt;vacant o = "munashii"&lt;/pre&gt;&lt;pre&gt;&lt;font color="blue"&gt;Main &gt;&lt;/font&gt;&lt;b&gt;vacant $ putStr "subarashii\n"&lt;/b&gt;&lt;br /&gt;"munashii"&lt;/pre&gt;どうして「subarashii」が印字されないん？&lt;br /&gt;&lt;br /&gt;結局、これはやっぱり副作用&lt;b&gt;じゃない&lt;/b&gt;ってことなんだろうな。Scheme でも同じことをすると、&lt;pre&gt;&lt;font color="blue"&gt;gosh&gt; &lt;/font&gt;&lt;b&gt;(define (vacant o) "munashii")&lt;/b&gt;&lt;br /&gt;vacant&lt;br /&gt;&lt;font color="blue"&gt;gosh&gt; &lt;/font&gt;&lt;b&gt;(vacant (print "subarashii"))&lt;/b&gt;&lt;br /&gt;subarashii&lt;br /&gt;"munashii"&lt;br /&gt;&lt;/pre&gt;これが本物の副作用ということなのか！&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-4052033138804687858?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/4052033138804687858/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=4052033138804687858' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/4052033138804687858'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/4052033138804687858'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2008/09/io-string-io-putstr-putstr-abcdefn.html' title=''/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-1587549740601462123</id><published>2008-09-11T01:17:00.003+09:00</published><updated>2011-02-10T14:45:38.649+09:00</updated><title type='text'>Haskellでプログラムを書くときは、まず関数の型を妄想してHoogleしろ</title><content type='html'>Haskellでは、型を「利用して」プログラミングができるという。つまり、「あーなんかこんな型の関数ねえかな」というところからプログラムを書き始めるものらしい。だから haskell.org では型からAPIを検索することができる。その名も &lt;a href="http://haskell.org/hoogle/"&gt;Hoogle&lt;/a&gt;。Gauche のリファレンスマニュアルさえあれば誰にでも Scheme のプログラムが書けてしまうように、Hoogle があれば誰にでも Haskell のプログラムが書ける。気がする。ところで、Yahooみたいな名前の APIサーチエンジンもあるそうなのですが、見つかりません。&lt;br /&gt;（追記）&lt;a href="http://holumbus.fh-wedel.de/hayoo/hayoo.html"&gt;Hayoo&lt;/a&gt;でした。ありがとうございます &gt; nobsun（ここまで追記）&lt;br /&gt;&lt;br /&gt;たとえば、10進の整数を各桁からなるリストだと思って map したい。&lt;pre&gt;&lt;font color="blue"&gt;*Main&gt;&lt;/font&gt;&lt;b&gt; intMap (*2) 12345&lt;/b&gt;&lt;br /&gt;[2,4,6,8,10]&lt;br /&gt;&lt;font color="blue"&gt;*Main&gt;&lt;/font&gt; &lt;b&gt;foldr (+) 0 $ intMap id 123456789&lt;/b&gt;&lt;br /&gt;45&lt;/pre&gt;こういうintMapをどうやって作っていくか。（以下、とりあえず正の整数の場合だけを考える。）&lt;br /&gt;&lt;br /&gt;Scheme脳の正攻法は、各桁の再帰だろう。1の位を head、それより大きな位を tail にして再帰的にリストを作り、reverse すればよさそうだ。10進数の 1の位の数は (mod 10) だし、10で割って floor を取れば 1の位より前にある数字を並べた数になるので、型を考えずにこんなナイーブな定義が書ける。&lt;pre&gt;intMap p n | n &amp;lt; 10 = [p n]&lt;br /&gt;           | otherwise = reverse (p last : reverse front)&lt;br /&gt;           where&lt;br /&gt;             last = mod n 10&lt;br /&gt;             front = intMap p (floor (n/10))&lt;/pre&gt;ちなみにこれはコンパイルに通らない。floor とか (/) とかは、そのままでは Int型に対して使えないので。コンパイルするには最後の front を次のようにする必要がある。&lt;pre&gt;front = intMap p $ fromEnum $ floor $ toEnum n/10&lt;/pre&gt;（追記）整数の割り算がありました。front = intMap p (div n 10) でOK。（ここまで追記）&lt;br /&gt;&lt;br /&gt;本来なら順番が逆だけど、ここで初めて intMap の型について考える。intMap は、ふつうの map のように、1引数関数とリスト代わりの整数をとってリストを返すようにしたい。つまり、こういう型だ。&lt;pre&gt;intMap :: (Int -&gt; a) -&gt; Int -&gt; [a]&lt;/pre&gt;自分が求めている型が分かったので、これをキーワードにして Hoogle で検索してみる。結果はいっぱい出るけど、その先頭には iterate という関数がひっかかるはずだ。リンクをクリックすると、GHCのドキュメントの iterate の項目にジャンプする。その説明によれば、iterate はこんな関数らしい。&lt;pre&gt;iterate :: (a -&gt; a) -&gt; a -&gt; [a]&lt;br /&gt;&lt;br /&gt;iterate f x returns an infinite list of repeated applications of f to x:&lt;br /&gt;&lt;br /&gt; iterate f x == [x, f x, f (f x), ...]&lt;/pre&gt;見るからに intMap の定義に使えそうだ。f として先ほどの定義の front に相当するものを与えてやれば、iterate f 1234 -&gt; [1234, 123, 12, 1, 0, ...] といった具合にリストが得られるので、あとは各要素から mod 10 で 1の位を抜き出せばいい。&lt;br /&gt;（追記）f の定義を fromEnum $ floor $ toEnum m/10 から div m 10 に修正（ここまで追記）&lt;pre&gt;intMap :: (Int -&gt; a) -&gt; Int -&gt; [a]&lt;br /&gt;intMap p n = map (p . lastDigit) $ reverse $ takeWhile (&gt; 0) $ iterate f n&lt;br /&gt;              where&lt;br /&gt;                f m = div m 10&lt;br /&gt;                lastDigit m = mod m 10&lt;/pre&gt;再帰がなくなり、標準関数をごにょごにょするだけで求める関数を作ることができた。&lt;br /&gt;&lt;br /&gt;&lt;b&gt;まとめ&lt;/b&gt;&lt;br /&gt;「Haskellでプログラムを書くときは、まず関数の型を妄想して Hoogle しろ」&lt;br /&gt;&lt;br /&gt;&lt;b&gt;おまけ&lt;/b&gt;&lt;br /&gt;ナベアツ問題とか。&lt;pre&gt;nabeatsu = [p i | i &amp;lt;- [1..]]&lt;br /&gt;           where has3 n = or $ intMap (== 3) n&lt;br /&gt;                 p i | has3 i || mod i 3 == 0 = "aho"&lt;br /&gt;                     | otherwise = intMap intToDigit i&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-1587549740601462123?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/1587549740601462123/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=1587549740601462123' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/1587549740601462123'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/1587549740601462123'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2008/09/haskell-haskell.html' title='Haskellでプログラムを書くときは、まず関数の型を妄想してHoogleしろ'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-2713411281078532977</id><published>2008-08-03T23:14:00.008+09:00</published><updated>2011-02-10T14:47:58.552+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Panasonic Let&apos;s Note CF-R4J Debian GNU/Linux インストールまとめ'/><title type='text'>Panasonic CF-R4JにDebianを入れるまとめ</title><content type='html'>正月に液晶を割ってしまった Panasonic CF-R4J のパーツを入手できたので、修理ついでに Debian GNU/Linux を入れることにした。いままでは購入時にプリインストールされていた Windows XP 上で VMware を使って Ubuntu を利用していたが、やっぱりたまにいらりってくる。&lt;br /&gt;最近は Debian も簡単にインストールできるけど、CF-R4J には光学ドライブがないし、内蔵の無線LANのように使えないと困る機能もある。あと、いままで使っていた Windows XP の環境をそのまま使い続けられるようにしたい。そこで備忘録として作業のまとめ。&lt;br /&gt;&lt;h2&gt;目標&lt;/h2&gt;プリインストールされている Windows XP はそのままにして、Debian を追加でインストールしたい。&lt;br /&gt;&lt;h2&gt;戦略&lt;/h2&gt;&lt;ol&gt;&lt;li&gt;USBメモリから KNOPPIX を起動し、ntfsresize と cfdisk を使って、Windows XP がプリインストールされた HDD の後半に Debian 用の新しいパーティションを作る。&lt;/li&gt;&lt;li&gt;別のUSBメモリから Debian のインストーラを起動し、新しいパーティションにインストールする。&lt;/li&gt;&lt;li&gt;内蔵されている無線LAN を有効にする。&lt;/li&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;h2&gt;用意するもの&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;1GバイトのUSBメモリ&lt;/li&gt;&lt;li&gt;128MバイトのUSBメモリ&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.kernel.org/pub/linux/utils/boot/syslinux/"&gt;syslinux（Windows用）&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.dnsbalance.ring.gr.jp/archives/linux/knoppix/iso/"&gt;KNOPPIXのisoイメージ&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.t.ring.gr.jp/pub/linux/debian/debian/dists/etch/main/installer-i386/current/images/hd-media/"&gt;boot.img.gz&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Debianのネットインストーラ（名刺サイズCD用。&lt;a href="http://cdimage.debian.org/debian-cd/4.0_r4/i386/iso-cd/"&gt;ここ&lt;/a&gt;の debian-40r4etchnhalf-i386-netinst.iso ）&lt;/li&gt;&lt;li&gt;&lt;a href="http://ipw2200.sourceforge.net/firmware.php"&gt;Intel PRO/Wireless 2200BG ドライバのファームウェア（v3.0）&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h2&gt;USBメモリから起動するKNOPPIXのイメージを作る&lt;/h2&gt;この作業は、プリインストールされた Windows XP 上で行う。以下のサイトの手順に従っただけ。&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;[USBメモリでKNOPPIXを起動する]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href="http://ryusai.hp.infoseek.co.jp/KNOPPIX_on_USB-01.htm"&gt;http://ryusai.hp.infoseek.co.jp/KNOPPIX_on_USB-01.htm&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;まとめると以下の通り。&lt;ol&gt;&lt;li&gt;KNOPPIX の iso イメージを入手して DAEMON tools でマウント&lt;/li&gt;&lt;li&gt;1Gバイトの USBメモリを FAT32 でフォーマット&lt;/li&gt;&lt;li&gt;DAEMON tools でマウントした KNOPPIX をエクスプローラで開き、KNOPPIX フォルダ全体と /boot/isolinux 以下のファイルを、フォーマットした USB メモリの直下にコピー&lt;/li&gt;&lt;li&gt;/isolinux.cfg を /syslinux.cfg にリネーム&lt;/li&gt;&lt;li&gt;syslinux -a :f&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;h2&gt;USBメモリから起動する Debian のインストーラを作る&lt;/h2&gt;この作業は、上で作った KNOPPIX で行う。これも以下のページの手順に従っただけ。&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;[USB メモリでの起動用ファイルの準備]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href="http://www.jp.debian.org/releases/stable/i386/ch04s04"&gt;http://www.jp.debian.org/releases/stable/i386/ch04s04&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;まとめると以下の通り。デバイス名とかは適宜。&lt;ol&gt;&lt;li&gt;（ここだけ Windows XP でやっておく）128Mバイトの USBメモリを FAT32 でフォーマット&lt;/li&gt;&lt;li&gt;boot.img.gz を入手し、zcat boot.img.gz &gt; /dev/sdb&lt;/li&gt;&lt;li&gt;sudo mount /dev/sdb /mnt/sdb&lt;/li&gt;&lt;li&gt;cp debian-40r4etchnhalf-i386-netinst.iso /mnt/sdb/&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;h2&gt;HDD のパーティションを切り直す&lt;/h2&gt;この作業は、KNOPPIX 上で行う。&lt;ol&gt;&lt;li&gt;（ここだけ Windows XP でやっておく）Cドライブのデフラグ&lt;/li&gt;&lt;li&gt;ntfsresize -i /dev/hda1 で、リサイズできる HDD 領域の大きさを調べる&lt;/li&gt;&lt;li&gt;ntfsresize -s 30000M /dev/hda1 （30000M のところは、上で調べた大きさを参考に適宜）&lt;/li&gt;&lt;/ol&gt;この時点で Windows XP からは、C ドライブの大きさが指定した大きさに縮小されて見える（この場合だと30Gバイトしか見えなくなる）。ただしパーティションが変わったわけではないので、管理ツールからローカルディスクを見れば、やはり元の大きさのHDDがCというドライブ名の1つのパーティションに占有されているように見える。ちょっとへんな状態。&lt;br /&gt;実際にパーティションを切るには fdisk をするしかない。そこで cfdisk /dev/hda1 を実行する。&lt;h4&gt;ntfsresize 後の cfdisk でやること&lt;/h4&gt;ここからが危険なところ。&lt;ol&gt;&lt;li&gt;もともと Windows XP がプリインストールされていたパーティションを削除する。最初に cfdisk を実行すると、HDD の末尾に 3G くらいの空き領域があるように見える。これは CF-R4 のリカバリ領域。Windows XP が入っているパーティションを削除することで全体が1つの空き領域になるため、空き領域として見えていたリカバリ領域が cfdisk からは識別できなくなってしまう。この領域は BIOS レベルで fdisk などでは削除できないようになっているらしいが、それを確かめる勇気はないので、本当のことは知らない。個人的には用心しておいたほうがいいと思う。実際、あとでパーティションの設定を誤って Windows XP が起動しなくなったとき、KNOPPIX からは /dev/hda4 としておもいっきり見える状態になっていた。たぶんこの領域を隠蔽するのに、プリンストールされた Windows XP の機能を使っているんだろう。&lt;/li&gt;&lt;li&gt;全体が1つの空き領域になっているところに、まずはプリインストールされている Windows 用のパーティションを作る。先に ntfsresize で縮小したサイズ以上の大きさのパーティションにすること。ぴったり同じバイト数で指定すると、ntfsresize で縮小したサイズよりもfdiskで作ったパーティションのほうが小さくなってしまうようだ。そうすると Windows XP が起動しなくなる。もし後続の空き領域に Debian 用のパーティションを作ってフォーマットしようものなら、あふれた部分が失われてしまって Windows XP の環境が復旧できなくなってしまうはず。大きい分には問題ないので、1Gバイトくらい多めの大きさのパーティションにしたほうがいいと思う。&lt;/li&gt;&lt;li&gt;この時点でパーティションテーブルを書き込み、Debian のインストールに使う領域の設定はインストーラにまかせてしまってもいいが、リカバリ領域を失うのは怖いので、この時点で最後に 5G くらい残るようにして、スワップ用とルート用のパーティションを切ってしまう。&lt;/li&gt;&lt;li&gt;書き込む。もう戻れない。&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;h2&gt;Debian のインストール&lt;/h2&gt;いつもどおりなので省略。ネットインストールに無線LAN が使えないので、有線をつないで実行する必要がある。&lt;br /&gt;&lt;h2&gt;無線LANを有効にする&lt;/h2&gt;ラップトップ向けのインストールをすれば wlan-tools はインストールされる。CF-R4J の内蔵無線LAN は Intel PRO/Wireless 2200BG で、そのドライバは ipw2200-source というパッケージでインストールすることができる。lenny ならパッケージのインストールは不要。ただし lenny であってもファームウェアは入らないので、別途 ipw2200-fw-3.0.tgz をダウンロードして /lib/firmware に手動で置いておく必要がある。&lt;br /&gt;あとは /etc/network/interfaces をこんな感じに設定しておけば、有線LAN との使い分けも適当にできると思う。&lt;pre&gt;# The loopback network interface&lt;br /&gt;auto lo&lt;br /&gt;iface lo inet loopback&lt;br /&gt;&lt;br /&gt;# The primary network interface&lt;br /&gt;allow-hotplug eth0&lt;br /&gt;iface eth0 inet dhcp&lt;br /&gt;&lt;br /&gt;# Wireless LAN&lt;br /&gt;auto eth1&lt;br /&gt;iface eth1 inet dhcp&lt;br /&gt;wireless-essid ******&lt;br /&gt;wireless-key **************************&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-2713411281078532977?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/2713411281078532977/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=2713411281078532977' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/2713411281078532977'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/2713411281078532977'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2008/08/panasonic-cf-r4j-debian-gnulinux.html' title='Panasonic CF-R4JにDebianを入れるまとめ'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-8543154121869327427</id><published>2008-07-27T22:54:00.003+09:00</published><updated>2008-07-29T09:19:56.331+09:00</updated><title type='text'></title><content type='html'>金曜日、帰り際にうっかりメールを見ると、確率クイズが出題されていた。&lt;pre&gt;x&lt;sub&gt;i&lt;/sub&gt; ≧ 0 かつ Σ x&lt;sub&gt;i&lt;/sub&gt; = 1 となるような乱数 &lt;br /&gt;x&lt;sub&gt;1&lt;/sub&gt;, ..., x&lt;sub&gt;10&lt;/sub&gt; がほしい。&lt;br /&gt;&lt;br /&gt;そこで、区間 [0,1] 上の独立な一様乱数を 9 個作ってソートし、&lt;br /&gt;得られた r&lt;sub&gt;1&lt;/sub&gt; ≦ … ≦ r&lt;sub&gt;9&lt;/sub&gt; を使って、&lt;br /&gt;x&lt;sub&gt;i&lt;/sub&gt; = r&lt;sub&gt;i&lt;/sub&gt; - r&lt;sub&gt;i-1&lt;/sub&gt; としてみた。&lt;br /&gt;（ただし r&lt;sub&gt;0&lt;/sub&gt; = 0, r&lt;sub&gt;10&lt;/sub&gt; = 1）&lt;br /&gt;&lt;br /&gt;これは平等か？&lt;br /&gt;たとえば x&lt;sub&gt;1&lt;/sub&gt; の分布と x&lt;sub&gt;5&lt;/sub&gt; の分布は等しいか？&lt;br /&gt;（数式に頼らずうまく説明せよ）&lt;/pre&gt;ようするに、数直線の0～1の間に均等な確率で弾を9発撃ち込むという行為を繰り返したとき、毎回の隣り合う各弾の間隔は同じような幅になると期待していいか、ということでしょう？&lt;pre&gt; 0            r&lt;sub&gt;i-1&lt;/sub&gt;   r&lt;sub&gt;i&lt;/sub&gt;            1&lt;br /&gt;-+--- …… ---+------+--- …… ---+-&lt;br /&gt;              `--x&lt;sub&gt;i&lt;/sub&gt;--'&lt;/pre&gt;たとえば撃ち込む弾の数が毎回1発だったら、&lt;pre&gt; 0       r&lt;sub&gt;1&lt;/sub&gt;        1&lt;br /&gt;-+-------+---------+-&lt;br /&gt;  `--x&lt;sub&gt;1&lt;/sub&gt;--'`---x&lt;sub&gt;2&lt;/sub&gt;---'&lt;/pre&gt;いかにも x&lt;sub&gt;1&lt;/sub&gt; と x&lt;sub&gt;2&lt;/sub&gt; が同じ分布になりそうだ。撃ち込むのが9発でも同じことだよね。というわけで、この方法で平等な乱数を10個作ることができる。&lt;br /&gt;&lt;br /&gt;こう返信しようとしたけど、思いとどまって（というか時間がなかったので）その日は帰宅した。&lt;br /&gt;&lt;br /&gt;でも今日、紙と鉛筆を使ってもうちょと考えてみることにした。&lt;br /&gt;&lt;br /&gt;&lt;b&gt;追記&lt;/b&gt;：以下にはしょうもない間違いがあるので、あとで訂正します。&lt;br /&gt;&lt;br /&gt;&lt;font color="#cccccc"&gt;&lt;br /&gt;任意のλ∈[0,1] について、x&lt;sub&gt;i&lt;/sub&gt; がλになる確率 P(x&lt;sub&gt;i&lt;/sub&gt; = λ) を考えよう。 r&lt;sub&gt;i&lt;/sub&gt; より左側に i-1 個の乱数があって、r&lt;sub&gt;i&lt;/sub&gt;＋λ より右側に 9-i 個の乱数があるということなので、以下のように書ける。&lt;pre&gt;P(x&lt;sub&gt;i&lt;/sub&gt; = λ) = r&lt;sub&gt;i&lt;/sub&gt;&lt;sup&gt;i-1&lt;/sup&gt; × (1 - r&lt;sub&gt;i&lt;/sub&gt; - λ)&lt;sup&gt;9-i&lt;/sup&gt;&lt;/pre&gt;いくつか具体的に計算してみると、x&lt;sub&gt;1&lt;/sub&gt; がλになる確率は以下のとおり。&lt;pre&gt;P(x&lt;sub&gt;1&lt;/sub&gt; = λ) = r&lt;sub&gt;1&lt;/sub&gt;&lt;sup&gt;0&lt;/sup&gt; × (1 - r&lt;sub&gt;1&lt;/sub&gt; - λ)&lt;sup&gt;8&lt;/sup&gt;&lt;br /&gt;           = (1 - r&lt;sub&gt;1&lt;/sub&gt; - λ)&lt;sup&gt;8&lt;/sup&gt;&lt;/pre&gt;同様に x&lt;sub&gt;2&lt;/sub&gt; がλになる確率は、&lt;pre&gt;P(x&lt;sub&gt;2&lt;/sub&gt; = λ) = r&lt;sub&gt;2&lt;/sub&gt;&lt;sup&gt;1&lt;/sup&gt; × (1 - r&lt;sub&gt;2&lt;/sub&gt; - λ)&lt;sup&gt;7&lt;/sup&gt;&lt;br /&gt;           = r&lt;sub&gt;2&lt;/sub&gt; (1 - r&lt;sub&gt;2&lt;/sub&gt; - λ)&lt;sup&gt;7&lt;/sup&gt;&lt;/pre&gt;おや、なんだか P(x&lt;sub&gt;1&lt;/sub&gt; = λ) = P(x&lt;sub&gt;2&lt;/sub&gt; = λ) とも言えなそうだ。そこでおおざっぱに評価してみる。&lt;pre&gt;   P(x&lt;sub&gt;2&lt;/sub&gt; = λ) / P(x&lt;sub&gt;1&lt;/sub&gt; = λ)&lt;br /&gt; = r&lt;sub&gt;2&lt;/sub&gt; (1 - r&lt;sub&gt;2&lt;/sub&gt; - λ)&lt;sup&gt;7&lt;/sup&gt; / (1 - r&lt;sub&gt;1&lt;/sub&gt; - λ)&lt;sup&gt;8&lt;/sup&gt;&lt;br /&gt; = (r&lt;sub&gt;2&lt;/sub&gt; / (1 - r&lt;sub&gt;1&lt;/sub&gt; - λ)) × ((1 - r&lt;sub&gt;2&lt;/sub&gt; - λ)&lt;sup&gt;7&lt;/sup&gt; / (1 - r&lt;sub&gt;1&lt;/sub&gt; - λ)&lt;sup&gt;7&lt;/sup&gt;)&lt;br /&gt;≦ (r&lt;sub&gt;2&lt;/sub&gt; / (1 - r&lt;sub&gt;1&lt;/sub&gt; - λ))     ← r&lt;sub&gt;1&lt;/sub&gt; ≦ r&lt;sub&gt;2&lt;/sub&gt; なので&lt;br /&gt; = r&lt;sub&gt;2&lt;/sub&gt; / (1 - r&lt;sub&gt;2&lt;/sub&gt;)            ← λ = r&lt;sub&gt;2&lt;/sub&gt; - r&lt;sub&gt;1&lt;/sub&gt;&lt;/pre&gt;最後の式は、r&lt;sub&gt;2&lt;/sub&gt; = 1/2 なら 1 になる。しかも、もし r&lt;sub&gt;1&lt;/sub&gt; = r&lt;sub&gt;2&lt;/sub&gt; だったら、途中の不等号が統合になるので、P(x&lt;sub&gt;1&lt;/sub&gt; = λ) = P(x&lt;sub&gt;2&lt;/sub&gt; = λ) になる。撃ち込む弾の数が毎回1発のケースは、この場合に相当していたのか。&lt;br /&gt;&lt;br /&gt;というわけで、実は平等じゃない、というのがクイズの答えっぽい。数式を使わない説明としては、1に近づくほど確保しうる x&lt;sub&gt;i&lt;/sub&gt; の大きさが小さくなってしまう確率が高まるから、というのでどうでしょう。&lt;br /&gt;&lt;/font&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-8543154121869327427?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/8543154121869327427/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=8543154121869327427' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/8543154121869327427'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/8543154121869327427'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2008/07/x-i-0-x-i-1-x-1.html' title=''/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-6947356346669223548</id><published>2008-06-14T21:53:00.000+09:00</published><updated>2008-06-14T21:55:05.537+09:00</updated><title type='text'></title><content type='html'>今日は7ヶ月の妊婦さんが遊びに来て、彼女たちが帰ったら2ヶ月の妊婦さんの夫から電話がきた。うちは去年のあいだ妊娠生活だったわけだけど、けっこう楽しく乗り切れたと思う。&lt;br /&gt;&lt;br /&gt;妊娠生活に限らず、日常と違う生活を楽しむにはまともな情報が必要だ。いろいろあさったけど、雑誌の情報（この場合はベネッセの何か）は2ちゃんねるのようなもので、その他大勢の声を確認するには悪くない。しかしそれはまた、意義のある情報を得るには取捨選択が必要なことも意味している。ところが取捨選択するには、そのドメインに対する基本的で正しい認識が欠かせない。そういうときに役立つのが本物の実用書というものだ。文句なしにお勧めするのはこれ。&lt;br /&gt;&lt;br /&gt;Arlene Eisenberg, Heidi Eisenberg Murkoff, Sandee E. Hathaway "What to Expect When You're Expecting"(Workman Pub Co, 2002)&lt;br /&gt;&lt;a href="http://www.amazon.co.jp/dp/0761121323/"&gt;http://www.amazon.co.jp/dp/0761121323/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;翻訳も出ている。自分は翻訳版を読んだことはないけど、上記をすすめて翻訳を買った妊婦さん（鬼編集者で出版物の出来には人一倍うるさい）によればいい本とのこと。&lt;br /&gt;&lt;br /&gt;森田由美、竹内正人訳『すべてがわかる妊娠と出産の本』（アスペクト、2004年）&lt;br /&gt;&lt;a href="http://www.amazon.co.jp/dp/4757210795"&gt;http://www.amazon.co.jp/dp/4757210795&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;この本のすごいところは、妊娠にかかわるいろんなトピックを、できるだけ全部できるだけ詳細に説明しようとしていることだ。それも平易な言葉と妊婦の視線で。実際、オリジナルの作者はそのへんの元妊婦さんで、自分が妊娠中に不安だったのに本に書いてなかったことを全部まとめて本にしてやると思い立ち、産婦人科医や研究者なんかに徹底的にリサーチして出版したらしい。&lt;br /&gt;&lt;br /&gt;自分はこの本がなかったら、予定日2週間前の午前2時に実家に戻っていた奥様から「破水した」という電話をもらったとき、これから何が起きて、自分が何をすればいいのか、さっぱりわからなかったはずだ。陣痛室から分娩台の脇で臍の緒を切るまで、すべては本に書いてあるとおりのあらすじで進み、要所で迫られる選択にも十分な理解をした上でのぞむことができた。アメリカ人の実用書の作り込みっぷりに改めて脅威を感じた。&lt;br /&gt;&lt;br /&gt;もちろん日本にもすごい本はある。&lt;br /&gt;&lt;br /&gt;定本育児の百科 上 5ヵ月まで&lt;br /&gt;&lt;a href="http://www.amazon.co.jp/dp/4003811119/"&gt;http://www.amazon.co.jp/dp/4003811119/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;この本は「育児」を扱った古典だが、冒頭でかなりのページを割いて出産前の心得や注意事項に触れられている。書かれたのは古いが、インターネットやベネッセから出産育児に関する情報を取捨選択するためのリテラシーを培うにはとてもお勧めだし、内容も今でも役に立つ話ばかりだ（文庫化にあたって、そういうふうに編集されている）。何よりも普通におもしろい。当たり前だが出産後も役に立つので、買っておいて損はないと思う。&lt;br /&gt;&lt;br /&gt;ベネッセやインターネットの情報を利用するのは、少なくともこの2冊の後でいいはずだ。もちろん、すべてを鵜呑みにしたりしなければ、いつどんなリソースに触れてもいいんだけど。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-6947356346669223548?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/6947356346669223548/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=6947356346669223548' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/6947356346669223548'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/6947356346669223548'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2008/06/72-2-arlene-eisenberg-heidi-eisenberg.html' title=''/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-1225816283802685838</id><published>2008-06-04T10:14:00.000+09:00</published><updated>2008-06-04T11:19:54.186+09:00</updated><title type='text'></title><content type='html'>朝一で&lt;a href="http://www.kt.rim.or.jp/~kbk/zakkicho/08/zakkicho0806a.html#D20080602-4"&gt;ときどきの雑記帖&lt;/a&gt;を見ていてクイズの存在に気が付いた。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://practical-scheme.net/wiliki/wiliki.cgi?Scheme%3a%e3%83%aa%e3%82%b9%e3%83%88%e5%87%a6%e7%90%86#H-ne4pu7"&gt;与えられた木から、子→親への対応を作る&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;脊髄反射で回答を思いついたので仕事を始める前に書いてみた。都合15分弱。&lt;pre&gt;(use srfi-1)&lt;br /&gt;&lt;br /&gt;&lt;font color="#AAAAAA"&gt;;; [name [tree ...]] -&gt; [(tree-head . name)]&lt;/font&gt;&lt;br /&gt;(define (child-parent ls)&lt;br /&gt;  (if (null? (cdr ls))&lt;br /&gt;      '()&lt;br /&gt;      (append-map&lt;br /&gt;       (lambda (l)&lt;br /&gt;         (cons (cons (car l) (car ls))&lt;br /&gt;               (child-parent l)))&lt;br /&gt;       (cdr ls))))&lt;/pre&gt;にしても、「10分で中級、30分で初級」というshiroさんによるレベル設定が絶妙すぎると思う。&lt;br /&gt;&lt;br /&gt;ところでむしろ気になるのは、他人が回答に至るプロセスだ。自分はこんな感じの思考過程で上記の定義に至った。&lt;pre&gt;リストのcarと、リストのcdrたちのcarとを、逆順にconsして集めるのね&lt;br /&gt;↓&lt;br /&gt;とりあえずcdrたちに対してmap-appendか&lt;br /&gt;↓&lt;br /&gt;そしてconsで再帰すればいいから、必然的に終了判定はnull?&lt;br /&gt;↓&lt;br /&gt;"(if (null? (cdr ls))"あたりから書き始める&lt;/pre&gt;この場合は再帰も単純なので一発で書いちゃうけど、もうちょっと複雑な場合はテスト用のトリビアルな入力データをREPLで評価しながら関数に仕上げていく。あるいは、一発で関数を書いちゃってからテスト用のトリビアルな入力データを使ってREPLで評価し、意図していない結果であれば修正して（再帰の終了条件を修正する場合が多い）、これを繰り返して関数に仕上げていく。だいたいいつもこんな感じ。必要なら最後にCtrl-c tしてテストを作りますよ。gca.el最高！&lt;br /&gt;&lt;br /&gt;ところがこのごろ、テストファーストという呪縛に悩んでいる。最初にテストを書け。問題にある「結果の例」とequal?になるテストケースを書けばいいのかな？でも結果のリストの順番はどうでもいいから、equal?になるテストケースをパスするコードを書くのは一苦労だぞ。そういえばGaucheにはリストを集合として同じだと見なす関数があったよな。しかし元の木に循環があったら集合としても同じにならないし……ってなことを考えているうちに、平気で30分は経過してしまう。&lt;br /&gt;&lt;br /&gt;この問題はただのクイズだから気にしなくていい、というわけにもいかない。shiroさん自身も「仕事で扱った小ネタ」と書いているように、Schemeでプログラムを書いているときには、こういう小さな関数を大量にスクラッチしている。そのほとんどを書くときは、まず上記のような思考をまとめて、REPLで即興データの評価を繰り返しながら、徐々に関数としてまとめていく。その過程で関数のキワがはっきりしてくるから、そのきわどい条件を含むように即興データをどんどん変更していく。（場合によっては最後にCtrl-c t。）&lt;br /&gt;&lt;br /&gt;テストファーストじゃなくてもメンテナンスのためにテストを残してけ、という意見もあるが、これもいまいち納得しきれていない（もちろん理解はできる）。gca.elを使って開発していれば、コードを書いちゃった後でテストを「残す」のは簡単だ。それでも、例えばプログラムの一部としてこの関数を使っていて、後で効率のいいコードにリファクタリングする場合、作り直したコードによって生成されるリストは現在の結果と同順になるとは限らない（その必要もない）。そうなったらユニットテストとして残しておいたテストケースの意味って、ゼロとは言わないけどあまりなくない？リファクタリングのときもテストデータをREPLで評価しながら作業するわけだけど、そのときにユニットテストとして残っているコードがテスト用として適切とは限らないんだよな。&lt;br /&gt;&lt;br /&gt;自分は最近、入力と結果の型（っぽいもの）を関数にコメントしておくようにしている。リファクタリングするときは、この型（っぽいもの）の入力にそったデータをでっちあげて、それをREPLで評価するためのテストデータとして使う。そのでっちあげたテストデータは、やはり新しい関数のキワを突くようにどんどん変更していくだろう。人のコードを見るときも、まずはその情報を探す（コメントとしてであれ、コードとしてであれ）。&lt;br /&gt;&lt;br /&gt;関数的なプログラミングにおけるテストの意味合いが、純粋によくわからない。なんども言うけど、テストそのものはCtrl-c tすれば作れるので、テストを残しておくことは面倒でもなんでもない。心にひっかかるのは、それって正しいの？という純粋な疑問だ。神様を毎朝拝むのは、一瞬なら面倒ではないかもしれないけど、自分にはそれが正しいことであると納得できないからしない。考えすぎかもしれないけど、何かを習慣として取り入れるなら、それなりに納得（理解ではなく）した上で取り入れたいということです。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-1225816283802685838?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/1225816283802685838/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=1225816283802685838' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/1225816283802685838'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/1225816283802685838'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2008/06/15-use-srfi-1-tree-head.html' title=''/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-202388450135131732</id><published>2008-05-13T06:18:00.001+09:00</published><updated>2008-05-13T06:18:45.076+09:00</updated><title type='text'></title><content type='html'>&lt;br /&gt;    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;今年の連休の成果はスターウォーズを全編通して見たことだ（アニメ『クローン大戦』を含む）。それでちょっと思ったんだけど、Lisperにとって自分でLispを作ることは、ジェダイにとって自分でライトセイバーを作ることに似ている。おもちゃのLispなんて、少なくともSICPを読めば誰にでも書ける。とくにLispを使ってLispを書くなら、ベースにするLispのreadやシンボルのインターンが使える。今回、はじめて&lt;a href='http://hw001.gate01.com/sikano/src/es.tar.gz'&gt;CでひととおりLispっぽいものを書いてみた&lt;/a&gt;わけだけど、やっぱり大変だったのはreadとシンボルのインターンだった。だからこんなのがきちんと実行できたのがうれしかった。&lt;pre&gt;es0&amp;gt; (eq? (quote a) (quote a))&lt;br /&gt;#tt&lt;br /&gt;es1&amp;gt; (eq? (cons (quote a)) (cons (quote a)))&lt;br /&gt;#ff&lt;/pre&gt;&lt;br /&gt;で、ジェダイならライトセイバーを自分で作るわけだ。奪ったライトセーバーを振り回すだけのグリーバス将軍とは、その点が決定的に違う。グリーバス将軍は強いけど、フォースの加護はない。フォースの加護もなしにライトセーバのような前時代の武器を使うのは、回顧趣味にほかならない。ようするにカッコつけてるわけだ。ラムダの加護もなしにLispを使うようなものだ。ポインタの加護もなしにCを使うようなものだ。ところでいまさらCのポインタの話だけど、みんな&lt;a href='http://www.amazon.co.jp/dp/4774100900'&gt;藤原博文著『Cプログラミング専門課程』&lt;/a&gt;を読めばいいと思う。僕がかろうじてCを全然使えないというわけでもないのはこの本があったからだ。けっこう版を重ねているのに柱（ページ番号とかある部分）に誤記が残ってるとか、編集については微妙なとこもあるけど、本当にいい本なので、曙橋界隈で藤原さんを見かけるとこっそりうれしい。&lt;br /&gt;    &lt;/div&gt;&lt;br /&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-202388450135131732?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/202388450135131732/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=202388450135131732' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/202388450135131732'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/202388450135131732'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2008/05/lisperlisplispsicplisplisplispread.html' title=''/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-3057514746019052725</id><published>2008-05-06T16:32:00.006+09:00</published><updated>2011-02-10T14:44:11.724+09:00</updated><title type='text'>オレリスプでYコンビネータ</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;やっぱりリストの再帰ができないとリスプとはいえない。Yコンビネータが定義できるかやってみよう。Yコンビネータを使うと、関数に名前を付けずに再帰ができる。まあ、なんというか、「ラムダだけでここまでできる」みたいなのがうれしい。&lt;br /&gt;&lt;br /&gt;これがYコンビネータ（"The Little Schemer"より）。&lt;pre&gt;es20&amp;gt; (define Y &lt;br /&gt;        (lambda (le)&lt;br /&gt;          ((lambda (f) (f f))&lt;br /&gt;           (lambda (f) (le (lambda (x) ((f f) x)))))))&lt;/pre&gt;（この「Y」という名前は再帰に使うための名前じゃない。）&lt;br /&gt;&lt;br /&gt;たとえばリストの長さを計算する関数なら、こんなふうに実現できる。ちっとも再帰関数には見えないかもだけど、Yコンビネータのなかで「再帰する」ことが抽象化されている感じ。&lt;pre&gt;es24&amp;gt; ((Y (lambda (len)&lt;br /&gt;            (lambda (l)&lt;br /&gt;             (if (null? l)&lt;br /&gt;                 0&lt;br /&gt;                 (+ 1 (len (cdr l)))))))&lt;br /&gt;       (quote (beans beans we need jelly beans)))&lt;br /&gt;6.000000&lt;/pre&gt;なんかちゃんと動いてる！&lt;br /&gt;&lt;br /&gt;にしても、もともと「アトムか、ドットペアか」というだけのルールでS式をパーズしようという企画だったので、いまから「'」記法を導入するのはやっかいだなあ。&lt;br /&gt;&lt;br /&gt;あと、この例ではnull?を使っているけど、null?は組み込んではいない。null?とか自分のなかで定義するのがリスプなんだと思う。&lt;pre&gt;es0&amp;gt; (define null? &lt;br /&gt;       (lambda (ls)&lt;br /&gt;         (if (eq? (quote ()) ls)&lt;br /&gt;             #t #f)))&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-3057514746019052725?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/3057514746019052725/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=3057514746019052725' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/3057514746019052725'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/3057514746019052725'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2008/05/y.html' title='オレリスプでYコンビネータ'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-4165114378416781567</id><published>2008-05-05T23:26:00.002+09:00</published><updated>2011-02-10T14:43:49.467+09:00</updated><title type='text'>Cによるはじめてのオレリスプ</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;できたよできた！とりあえず階乗の関数を定義して計算できるようになった。&lt;pre&gt;k16@miffy:~/myproj/es$ ./es&lt;br /&gt;&lt;br /&gt;es0&amp;gt; (define fact&lt;br /&gt;        (lambda (n)&lt;br /&gt;          (if (eq? n 1)&lt;br /&gt;              1&lt;br /&gt;              (* n (fact (- n 1))))))&lt;br /&gt;fact&lt;br /&gt;es1&amp;gt; fact    &lt;br /&gt;#&amp;lt;closure ( n )&amp;gt;&lt;br /&gt;es2&amp;gt; (fact 10)&lt;br /&gt;3628800.000000&lt;br /&gt;es3&amp;gt; &lt;/pre&gt;ソースは&lt;a href="https://github.com/k16shikano/es"&gt;これ&lt;/a&gt;。メモリリークしまくっている状態だけど。あとで時間がとれたら感想とか書く。&lt;br /&gt;&lt;br /&gt;    &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-4165114378416781567?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/4165114378416781567/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=4165114378416781567' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/4165114378416781567'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/4165114378416781567'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2008/05/k16miffymyprojes.html' title='Cによるはじめてのオレリスプ'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-5536664494058025228</id><published>2008-03-30T22:02:00.003+09:00</published><updated>2011-02-10T14:52:30.504+09:00</updated><title type='text'>S式パーサからリスプへ</title><content type='html'>&lt;a href="http://k16journal.blogspot.com/2008/03/s-s-s-s-s.html"&gt;先週はS式パーザ（つまりread）をつくった&lt;/a&gt;ので、今週はcarとcdrとconsをつくった。そのときにevalとapplyをつくったので、ついでに四則演算にも対応した。途中なので結果だけ。&lt;pre&gt;&lt;font color="blue"&gt;es0&amp;gt;&lt;/font&gt;&lt;b&gt; (* 1 2)&lt;/b&gt;&lt;br /&gt;2.000000&lt;br /&gt;&lt;font color="blue"&gt;es1&amp;gt;&lt;/font&gt;&lt;b&gt; (+ 42 23)&lt;/b&gt;&lt;br /&gt;65.000000&lt;br /&gt;&lt;font color="blue"&gt;es2&amp;gt;&lt;/font&gt;&lt;b&gt; (cons answer (cons is (cons 42 ())))&lt;/b&gt;&lt;br /&gt;(answer . (is . (42.000000 . null)))&lt;br /&gt;&lt;font color="blue"&gt;es3&amp;gt;&lt;/font&gt;&lt;b&gt; (cdr (cons mouse (cons dolphin human)))&lt;/b&gt;&lt;br /&gt;(dolphin . human)&lt;br /&gt;&lt;font color="blue"&gt;es4&amp;gt;&lt;/font&gt;&lt;/pre&gt;はやくSchemeになりたいよう。のこり必要なもの。&lt;ol&gt;&lt;li&gt;環境（クロージャー）&lt;/li&gt;&lt;li&gt;インターン&lt;/li&gt;&lt;li&gt;プリティプリント&lt;/li&gt;&lt;li&gt;ガーベジコレクション&lt;/li&gt;&lt;li&gt;末尾最適化&lt;/li&gt;&lt;li&gt;call/cc&lt;/li&gt;&lt;/ol&gt;2まではSICPの知識だけで十分か。3はまあ、できているといえばできている。4から6はきびしいかな。やり方は理解できると思うけど、Cで書けるかどうかは別問題だ。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-5536664494058025228?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/5536664494058025228/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=5536664494058025228' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/5536664494058025228'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/5536664494058025228'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2008/03/sread-carcdrconsevalapply-es0-1-2-2.html' title='S式パーサからリスプへ'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-4449729902900354874</id><published>2008-03-23T22:35:00.006+09:00</published><updated>2011-02-10T14:51:59.863+09:00</updated><title type='text'>「S式はアトムまたはドットペア」を真に受けてyaccでパースする話</title><content type='html'>&lt;a href="http://kakutani.com/20080308.html#p03"&gt;「おまいらはS式が好きすぐる。」&lt;/a&gt;という感想にぐっときたので、S式について考え直してみることにした。具体的にはパーザを書くよ。&lt;br /&gt;&lt;br /&gt;S式そのものはとてもシンプル。アトムか、ドットペアか。つまり、&lt;pre&gt;S式 : アトム&lt;br /&gt;    | ( S式 . S式 )&lt;br /&gt;    ;&lt;/pre&gt;おなじみの (apple orange pizza) みたいなリストは、実際には null で終わっているドットペアの簡略表記にすぎない。この例であれば、その本当のすがたは (apple . (orange . (pizza . null))) という入れ子になったドットペア。そういえば null って本当は何のことなんだろう？ いつも()って書いてるから、空っぽなリストぐらいにしかみなしてなかったけど、よく考えるとよくわからん。&lt;br /&gt;&lt;br /&gt;まあとにかく、この「アトムか、ドットペアか」という単純な構文ルールだけをパーザジェネレータに与えてS式パーザを作りたい。&lt;br /&gt;&lt;br /&gt;YACCを使ってやってみよう。試行錯誤のすえ、構文解析の部分はこんな感じにした。&lt;pre&gt;%{&lt;br /&gt;  #define YYSTYPE Sexp*&lt;br /&gt;  %}&lt;br /&gt;%token ATOM&lt;br /&gt;%token DOT&lt;br /&gt;%token LPAREN&lt;br /&gt;%token RPAREN&lt;br /&gt;%%&lt;br /&gt;list:             { prompt(lineno); }&lt;br /&gt;| list '\n'&lt;br /&gt;| list sexp '\n'  { prints($2); prompt(lineno); }&lt;br /&gt;;&lt;br /&gt;&lt;br /&gt;sexp: ATOM&lt;br /&gt;| LPAREN sexp DOT sexp RPAREN  { $$ = mk_oblist($2, $4); }&lt;br /&gt;;&lt;/pre&gt;ここで Sexp はS式をあらわす構造体で、直感的にAtomとPairの共用体として定義した。&lt;pre&gt;typedef struct Sexp {&lt;br /&gt;  short type;&lt;br /&gt;  union {&lt;br /&gt;    struct Atom *atom;&lt;br /&gt;    struct Pair *pair;&lt;br /&gt;  } u;&lt;br /&gt;} Sexp;&lt;/pre&gt;Atomは浮動小数点数か文字列とする。Pairはもちろんcarとcdrで構成される。&lt;pre&gt;typedef struct Atom{&lt;br /&gt;  short type;&lt;br /&gt;  union {&lt;br /&gt;    double num; /* type = 0 */&lt;br /&gt;    char  *sym; /* type = 1 */&lt;br /&gt;  } u;&lt;br /&gt;} Atom;&lt;br /&gt;&lt;br /&gt;typedef struct Pair {&lt;br /&gt;  struct Sexp *car;&lt;br /&gt;  struct Sexp *cdr;&lt;br /&gt;} Pair;&lt;/pre&gt;そしてこの Pair を作る関数が mk_oblist。&lt;br /&gt;&lt;br /&gt;基本的には以上でおしまい。なんだけど、これだけではリスト表記をパーズできないのでつまらない。リスト表記のための構文規則を付け足せばいい話なんだけど、「アトムか、ドットペア」というS式のシンプルさに無駄にこだわることにして、字句解析のほうで対応したった！ もしかしたらちょっとしたプッシュダウンオートマトンの勉強をしたことになったのかもしれないけど、めんどくさいし面白くないので説明は省略。とりあえず自宅のDebian Lenny上ではこんなふうに動くものができた。&lt;pre&gt;$ &lt;b&gt;./es&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="blue"&gt;es0&amp;gt;&lt;/font&gt; &lt;b&gt;(((((42)))))&lt;/b&gt;&lt;br /&gt;(((((42.000000 . null) . null) . null) . null) . null)&lt;br /&gt;&lt;font color="blue"&gt;es1&amp;gt;&lt;/font&gt; &lt;b&gt;(the answer is 42)&lt;/b&gt;&lt;br /&gt;(the . (answer . (is . (42.000000 . null))))&lt;br /&gt;&lt;font color="blue"&gt;es2&amp;gt;&lt;/font&gt; &lt;b&gt;(() ())&lt;/b&gt;&lt;br /&gt;(null . (null . null))&lt;/pre&gt;&lt;br /&gt;浮動小数点数だと、&lt;a href="http://www.google.com/search?hl=en&amp;q=answer+to+life%2C+the+universe%2C+and+everything&amp;btnG=Google+Search"&gt;42&lt;/a&gt;という答えがなんだかうそっぽい。&lt;br /&gt;&lt;br /&gt;Expand S-expression にちなんで es という名前にしています。ソースはこちら。&lt;br /&gt;&lt;br /&gt;&lt;a href="https://github.com/k16shikano/es/blob/master/es.y"&gt;es.tar.gz&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-4449729902900354874?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/4449729902900354874/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=4449729902900354874' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/4449729902900354874'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/4449729902900354874'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2008/03/s-s-s-s-s.html' title='「S式はアトムまたはドットペア」を真に受けてyaccでパースする話'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-7361454217824412633</id><published>2008-03-15T11:31:00.001+09:00</published><updated>2008-03-15T11:31:47.189+09:00</updated><title type='text'>Sence of Mathmatics</title><content type='html'>&lt;br /&gt;    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;&lt;br /&gt;昨日の夜、なんとなくラジオを聞いていたら、文系にも数学のセンスは備わっていると誰が主張していた。（文系とか数学のセンスといった用語についての質問はうけつけません。そもそも途中でうちのこが泣き出したので、僕の聞き違いだったかもしれない。どうでもいいけど、うちのことツチノコは似ている。見ためが。）&lt;br /&gt;&lt;br /&gt;いわく、「マイナスかけるマイナスがプラスになるのは「反対の反対は賛成」と同じことで、そういうふうに言えば文系の人にだってすっきりするんだからね」みたいな話だったんだけど、それは数学のセンスじゃないと思う。&lt;br /&gt;&lt;br /&gt;どうしてもこの話から数学のセンスという何かについて語りたいなら、「マイナスかけるマイナス」が「反対の反対」だと小学校の教師に言われたときに、「反対の反対」を「マイナスたすマイナス」と考えなかった理由を問い返すのが数学のセンスだと思う。&lt;br /&gt;&lt;br /&gt;で、そんなセンスをもっていても小学校の教師から屁理屈をいうなと罵られるだけなので、数学のセンスに夢や希望を抱くのはやめたほうがいいと思う。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    &lt;/div&gt;&lt;br /&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-7361454217824412633?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/7361454217824412633/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=7361454217824412633' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/7361454217824412633'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/7361454217824412633'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2008/03/sence-of-mathmatics.html' title='Sence of Mathmatics'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-1084958619044534472</id><published>2008-03-11T12:10:00.004+09:00</published><updated>2011-02-10T14:49:55.620+09:00</updated><title type='text'>Gaucheで本を作るのFAQ</title><content type='html'>Gaucheで本を作る&lt;br /&gt;&lt;a href="http://www.slideshare.net/guest7a66b8/gauche/"&gt;http://www.slideshare.net/guest7a66b8/gauche/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;gauche.night2008の発表後に個別に受けた質問に答えます。&lt;br /&gt;&lt;br /&gt;&lt;hr/&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Q.&lt;/b&gt; 原稿をXMLで書かせられるってこと？&lt;br /&gt;&lt;b&gt;A.&lt;/b&gt; XMLでなくてもいいんだけど、XMLでお願いすることが多いです。&lt;br /&gt;&lt;br /&gt;歯切れの悪い答えですみません。ちょっと背景と理由を説明します。&lt;br /&gt;&lt;br /&gt;まずは「XMLでなくてもいい」についてですが、実例がいくつかあるので、それらを紹介。&lt;br /&gt;&lt;br /&gt;1つめの実例は、&lt;a href="http://ssl.ohmsha.co.jp/cgi-bin/menu.cgi?ISBN=978-4-274-06696-2"&gt;『RailsによるアジャイルWebアプリケーション開発』&lt;/a&gt;の旧版。このときは、原書のデータはXMLだったんだけど、下訳の時点でプレーンなテキストデータになってしまったため、XMLの原稿ではありませんでした。ただし、あとでDTPソフトを使ってページレイアウトをするオペレータさん向け、つまり人間向けのメタ情報は付いていました。人間向けのメタ情報っていうのは、たとえば箇条書きの行頭に「●」が付いているとか、サンプルコードの始まりと終わりにマークが付いているとか、補足説明の文はタブでインデントされてるとか、そういうやつです。で、どうしたかというと、そんな人間向けメタ情報をなんとなくパーズしてLaTeXに変換するスクリプトをGaucheで書きました。といっても、機械的な判断が可能なように、人間向けメタ情報のエディタでの編集は必要でした。原稿そのものは最後までプレーンなテキストデータを使いましたが（i.e. XMLに加工したりはしていない）、著者がいじれる原稿からmakeいっぱつで印刷用データを生成していたのは一緒です。このときの顛末は過去にまとめたことがあるので、そちらも見てみてください。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://k16journal.blogspot.com/2006/05/railsweb-railswebpdfpdflatexlatexlatex.html"&gt;『RailsによるアジャイルWebアプリケーション開発』の制作方式&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;2つめの実例は&lt;a href="http://ssl.ohmsha.co.jp/cgi-bin/menu.cgi?ISBN=978-4-274-06676-4"&gt;『マスタリングTCP/IP ルーティング編』&lt;/a&gt;です。このときは、とくに最終工程を意識したメタ情報がないテキストの原稿に、僕のほうでXMLタグを付けて、編集用の原稿にしました。著者の方々の校正では、初校や再校といったタイミングでPDFを印刷した校正紙に赤書きしてもらう、従来の方法をとりました（編集部内ではほぼデイリーでPDFを生成していたけど）。もっとも、この本の場合は図版がとても多く、その校正は紙に赤書きというスタイルがいちばん現実的だったというのもあります。編集者がいじれる原稿からmakeいっぱつで印刷用データを生成していたのは一緒です。&lt;br /&gt;&lt;br /&gt;3つめの実例は&lt;a href="http://ssl.ohmsha.co.jp/cgi-bin/menu.cgi?ISBN=4-274-06578-2"&gt;『プログラミングのための線形代数』&lt;/a&gt;です。この本は、著者の2人の原稿がまっとうなLaTeXだったので、そのままLaTeXで組んでしまいました。LaTeXの編集では三美印刷さんにお手伝いしてもらっています。なお一般には、著者独自マクロが入り乱れたLaTeXの原稿はうれしくありません。そのまま印刷所には入稿できないからです。LaTeX原稿は最終工程ではポータビリティが低いのです。&lt;br /&gt;&lt;br /&gt;「XMLでお願いすることが多い」理由については、次の質問ともかぶるので、ここではパス。&lt;br /&gt;&lt;br /&gt;&lt;hr/&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Q.&lt;/b&gt; Wikiとか使って原稿書きたいんだけど……&lt;br /&gt;&lt;b&gt;A.&lt;/b&gt; おすすめしません。&lt;br /&gt;&lt;br /&gt;いや、Wikiを否定しているのではなく、Wikiは技術書の原稿執筆には向かないと思う、という話です。初期的なアイデア出しや、アイデアの相互レビュー、一時的な原稿のプールなんかに使うぶんには、Wikiは技術書の執筆においてもとても優れたメディアです。&lt;br /&gt;&lt;br /&gt;でもWikiに依存して書いていると、最終的な本の構造が意識できない。&lt;br /&gt;&lt;br /&gt;技術書って、拾い読みしてもいいけど、やっぱり多くは頭から読むものなわけです。そのとき、構造があいまいな本は、とても読みにくい。ここで「構造」というのは、「目次」に近いけれど、もうちょっと体系的な本の姿のことです。新しい概念がいつ説明されるか、どのブロック（章や項）の下に書かれているか、前にどこで言及されていたか、その前後の文脈。こういった本を構成する要素の縦横のつながり方は、その本のわかりやすさにもろに影響します。構造があいまいで見通しが悪い技術書は、初心者の目線で読んでいるとつらい。Wikiで書く原稿はジグソーパズルすぎて、あらかじめ全体像を知っている人（本を書く人）には気持ちがいいけど、その一片ずつを順番に渡されて読むことになる人（本を読む人）にはちんぷんかんぷんだったりするわけです。Webであれば縦横にはったリンクが読んでいる人にとっても十分な手がかりになるのですが、頭から読む本の場合は読んでいる途中で迷子になった感を抱かせないだけのしっかりした構造が必要です。&lt;br /&gt;&lt;br /&gt;で、そういう技術書の原稿を書くのにWikiでやれる人っていうのは、限られるわけです（ゼロじゃないですもちろん）。その点では、構造化を強要されるXMLのほうに、書籍の原稿執筆のための形式としての分があると思います。繰り返しになりますが、アイデア出しやアイデアのまとめにはWikiが優れていると思います。でもそれを本にしようとおもったら、頭から読まれることを強く意識して、体系的に再構築する必要があります。&lt;br /&gt;&lt;br /&gt;そして、それは技術書の編集者が手伝える仕事でもありますね（むしろ得意なはず）。&lt;br /&gt;&lt;br /&gt;&lt;hr/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-1084958619044534472?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/1084958619044534472/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=1084958619044534472' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/1084958619044534472'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/1084958619044534472'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2008/03/gauche-httpwww.html' title='Gaucheで本を作るのFAQ'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-1674192163516968572</id><published>2008-03-09T23:34:00.005+09:00</published><updated>2011-06-06T21:43:12.066+09:00</updated><title type='text'>gauche.night2008で発表しました</title><content type='html'>gauche.night2008のgauche.gongで発表した。プレゼンはこちら。&lt;br /&gt;&lt;br /&gt;Gaucheで本を作る&lt;br /&gt;&lt;a href="http://www.slideshare.net/guest7a66b8/gauche/"&gt;http://www.slideshare.net/guest7a66b8/gauche/&lt;/a&gt;&lt;br&gt;&lt;br /&gt;&lt;br /&gt;このプレゼンそのものが、下書きのテキストに気ままにXMLっぽいタグを付けて、それからXML→LaTeXへの&lt;a href="https://github.com/k16shikano/xml2tex/blob/master/sample/rules.scm"&gt;変換ルール&lt;/a&gt;を定義して、そのルールを使って&lt;a href="https://github.com/k16shikano/xml2tex/blob/master/xml2tex.scm"&gt;xml2tex.scm&lt;/a&gt;で変換して作ったもの。（実際にルールを使って変換してるのは、&lt;a href="https://github.com/k16shikano/xml2tex/blob/master/xmltex/latex.scm"&gt;latex.scm&lt;/a&gt;と&lt;a href="https://github.com/k16shikano/xml2tex/blob/master/xmltex/cnvr.scm"&gt;cnvr.scm&lt;/a&gt;。）&lt;br /&gt;&lt;br /&gt;仕様の定かでないタグ付けテキストから、いかにちょっとのコードでLaTeXへの変換ルールを作れるかってところを最後にデモで見てほしかったんだったんだけど、時間が足りなかったのでここで補足。&lt;br /&gt;&lt;br /&gt;たとえば、1ページ目のPDFはこんな感じで、&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/k16/2320472981/" title="cover by Keiichirou Shikano, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2183/2320472981_d14dd9398e_m.jpg" width="240" height="184" alt="cover" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;原稿はこんなだったんだけど、&lt;pre&gt;&amp;lt;page&gt;&lt;br /&gt; &amp;lt;p0&gt;Gaucheで本を作る&amp;lt;/p0&gt;&lt;br /&gt; &amp;lt;p3 vskip="4zh" hskip="12zw"&gt;株式会社オーム社開発部&amp;lt;/p3&gt;&lt;br /&gt; &amp;lt;p3 hskip="12zw"&gt;鹿野 桂一郎&amp;lt;/p3&gt;&lt;br /&gt; &amp;lt;p3 hskip="12zw"&gt;kshikano@ohmsha.co.jp&amp;lt;/p3&gt;&lt;br /&gt;&amp;lt;/page&gt;&lt;/pre&gt;ちょっとタイトルにワクでも付けたいなと思ったら、こんなふうに適当なタグでくるんでみて、&lt;pre&gt;&amp;lt;page&gt;&lt;br /&gt; &amp;lt;p0&gt;&amp;lt;box&gt;Gaucheで本を作る&amp;lt;/box&gt;&amp;lt;/p0&gt;&lt;br /&gt; &amp;lt;p3 vskip="4zh" hskip="12zw"&gt;株式会社オーム社開発部&amp;lt;/p3&gt;&lt;br /&gt; &amp;lt;p3 hskip="12zw"&gt;鹿野 桂一郎&amp;lt;/p3&gt;&lt;br /&gt; &amp;lt;p3 hskip="12zw"&gt;kshikano@ohmsha.co.jp&amp;lt;/p3&gt;&lt;br /&gt;&amp;lt;/page&gt;&lt;/pre&gt;rules.scmにこんな2行を足すだけで（LaTeXの\fboxはワク付の箱でテキストを囲むコマンド）、&lt;pre&gt;(define-tag box&lt;br /&gt;  (make-latex-cmd 'fbox))&lt;/pre&gt;こんなふうになる。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/k16/2321288064/" title="modified-cover by Keiichirou Shikano, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2342/2321288064_b7edd24532_m.jpg" width="240" height="184" alt="modified-cover" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;実際の書籍の原稿だとこんなに単純ではないし、社内で使っているコードはここで公開しているのとは違うけれど、それでもやっていることはほぼ同じです。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;謝辞&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;勢いで申し込んでしまって後悔もしたけれど、Gaucheを実際の商品（書店に並んでいる本）の製作で全面的に使っていることを話せる機会がもらえてよかったです。えんどうさんはじめ、gauche.nightの企画と実現に尽力されているみなさん、本当にお疲れさまでした。デモへの参加を後押ししてくれたhisashimさん、角谷さんと、shiroさんにも感謝です。ありがとうございました。っていうか、shiroさんには、それ以前にGaucheを開発されたことに感謝しないといけないわけですが。shiroさんだけでなく、日々Gaucheの開発とメンテナンスを続けているたくさんの方々にもあらためて感謝です。あと、こんなやり方の本作りに付き合っていただいている著者、訳者、トップスタジオのみなさん、会社のひと、とくにctakaoさんの家の方角には足を向けて寝られないと思ってるんですが、あにいく毎晩その向きで寝るしかない感じです。すみません。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-1674192163516968572?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/1674192163516968572/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=1674192163516968572' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/1674192163516968572'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/1674192163516968572'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2008/03/gauche.html' title='gauche.night2008で発表しました'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm3.static.flickr.com/2183/2320472981_d14dd9398e_t.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-1417822745125788327</id><published>2008-03-06T12:14:00.002+09:00</published><updated>2008-03-06T12:29:40.003+09:00</updated><title type='text'></title><content type='html'>SICPは、口語では「しっくぴー」と読まれているらしい。&lt;br /&gt;ただし、「あべるそんあんどさすまん」とか「すとらくちゃーあんどいんたーぷりてーしょんおぶこんぴゅーたーぷろぐらむす」といったフォーマルな呼び方を好む人が多いようだ。&lt;br /&gt;&lt;br /&gt;SICP - comp.lang.scheme&lt;br /&gt;&lt;a href="http://groups.google.com/group/comp.lang.scheme/browse_thread/thread/d6bc378a91aee7eb/33cb6ca736234ec6?#33cb6ca736234ec6"&gt; I wonder what is the correct spelling for SICP abbreviation.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;あまり返信が伸びてないなので、英語圏の人たちにとってはどうでもいい話なのかも。いずれにせよ「えすあいしーぴー」という言い方は、あまりしないみたい。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-1417822745125788327?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/1417822745125788327/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=1417822745125788327' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/1417822745125788327'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/1417822745125788327'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2008/03/sicp-sicp-comp.html' title=''/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-8690781244844751092</id><published>2008-01-19T17:27:00.000+09:00</published><updated>2008-01-19T17:51:40.597+09:00</updated><title type='text'></title><content type='html'>あまりに憤ったので脊髄反射的に書くけど、そもそも&lt;a href="http://www.oreilly.co.jp/editors/archives/000155.html"&gt;こんなふうにゲラに赤書きしてもらう&lt;/a&gt;という本の作り方は悲しすぎます。そして、2月発行予定の書籍に1/11の時点でこれだけの赤字が入っていて、DTPソフトを使って修正する人の作業が間に合うのかとても心配です。おそらくはかなりテクニカルでセンシティブな内容の赤字が入っていると思うので、必ずしも本書の内容を理解しているわけではない人が手作業で各ページごとに絵として修正するには、著者や編集者による修正漏れ確認の手間も含めてとても時間がかかるものだからです。一般に技術書の制作なんてそんなもんだろと言われたら、内情を知る立場ではぐうのねも出ないわけですが、少なくとも僕のチームには「それじゃやばい」という空気がいっぱいだし、そうしない努力もしているつもり。こんな写真が公開されるのは、来月にきちんとしたものが発行されるからこそだという見方もできるのかもしれませんが、この本については読者としてとても楽しみなので、あまり不安にさせるような写真は出さないでほしい。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-8690781244844751092?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/8690781244844751092/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=8690781244844751092' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/8690781244844751092'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/8690781244844751092'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2008/01/2111dtp.html' title=''/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-8883628838878897982</id><published>2007-12-29T13:58:00.001+09:00</published><updated>2007-12-29T21:56:56.507+09:00</updated><title type='text'></title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;&lt;br /&gt;年賀状かいた。&lt;pre&gt;%!&lt;br /&gt;&lt;&lt; /PageSize [285 420] &gt;&gt; setpagedevice&lt;br /&gt;newpath&lt;br /&gt;/Times-Bold findfont 340 scalefont setfont&lt;br /&gt;7 200 moveto &lt;br /&gt;(2) false charpath&lt;br /&gt;&lt;br /&gt;/Times-Bold findfont 230 scalefont setfont&lt;br /&gt;148 250 moveto &lt;br /&gt;(0) false charpath&lt;br /&gt;&lt;br /&gt;/Times-Bold findfont 200 scalefont setfont&lt;br /&gt;10 55 moveto&lt;br /&gt;(0) false charpath&lt;br /&gt;&lt;br /&gt;/Times-Bold findfont 440 scalefont setfont&lt;br /&gt;67 10 moveto&lt;br /&gt;(8) false charpath&lt;br /&gt;clip&lt;br /&gt;/Georgia-Bold findfont 13 scalefont setfont&lt;br /&gt;0 11 450 { %for&lt;br /&gt;    &lt;br /&gt;    /r1 {rand 23 mod 17 div} def&lt;br /&gt;    /r2 {rand 13 mod 17 div} def&lt;br /&gt;    /r3 {rand 17 mod 17 div} def&lt;br /&gt;    r1 r2 r3 setrgbcolor&lt;br /&gt;    newpath&lt;br /&gt; 0 exch moveto&lt;br /&gt; (200820082008200820082008200820082008200820082008200820082008200820082008200820082008) show&lt;br /&gt;} for&lt;/pre&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/k16/2145559335/" title="DSC_0326 by Keiichirou Shikano, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2006/2145559335_3cce1c5149_m.jpg" width="240" height="160" alt="DSC_0326" /&gt;&lt;/a&gt;&lt;br /&gt;    &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-8883628838878897982?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/8883628838878897982/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=8883628838878897982' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/8883628838878897982'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/8883628838878897982'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2007/12/blog-post_29.html' title=''/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm3.static.flickr.com/2006/2145559335_3cce1c5149_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-5892349854689790251</id><published>2007-12-27T22:27:00.001+09:00</published><updated>2007-12-27T22:35:00.832+09:00</updated><title type='text'></title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;ケリー・リンクの&lt;a href='http://www.amazon.co.jp/dp/4152088397/'&gt;『マジック・フォー・ビギナーズ』&lt;/a&gt;（柴田元幸訳）。英語の日記によれば&lt;a href='http://k16ex.blogspot.com/2007/11/biblio.html'&gt;11月5日&lt;/a&gt;に買ったものらしい。ほとんど2ヵ月かけて読んだわけか。本を読むのが仕事だというのに、この遅読っぷり。いろんな人の日記やブログを読んでいると、すごい勢いで書評やら新刊紹介やらが更新されていて、本当にすごいと思う。僕は今年、何冊本を読んだんだろう（仕事として編集したものは除く）。どうして早く読めないんだろう。何につっかかってるんだろう。&lt;br /&gt;&lt;br /&gt;たしかにケリー・リンクの小説には、つっかかるところは多い。不条理さとか荒唐無稽さとか、そういう表面的なところにつっかかるんじゃなくて、お話のせつなさにつっかかってしまう。ぶっちゃけ小説の外面がどんなに奇抜だろうと、もともとそういう要素を求めて彼女の本を読んでいるわけだから、その部分は快感なわけだ。快感すぎるわけだ。だからこそ異化された現実感が巧妙に襲ってきて、せつなくなる。もうね、最後に収録されている「しばしの沈黙」なんて、奥様と離れて生活せざるを得ない状況にある男性に読ませたら、間違いなくきゅんとなるよ。僕もスターライトたんに電話して、悪魔とチアリーダーのお話を語ってほしい！ あと、今の自分にとっては、「石の動物」に出てくるヘンリーにも共感を禁じえない。彼に限らず、ケリー・リンクの話に出てくる男性は、みんな斜めった現実に抗わなすぎ。そしてそれは、うちらの日常も一緒なんだろうな。そばにいるのが明らかなゾンビとか悪魔じゃなくて、ゾンビとか悪魔っぽい人間ってだけのことで。&lt;br /&gt;&lt;br /&gt;ところでケリー・リンクの翻訳作品には『スペシャリストの帽子』もあるけど、もし彼女の作品を初めて読んでみるってことなら、『マジック・フォー・ビギナーズ』のほうをすすめます。訳文の出来が違う。&lt;br /&gt;&lt;br /&gt;    &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-5892349854689790251?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/5892349854689790251/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=5892349854689790251' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/5892349854689790251'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/5892349854689790251'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2007/12/blog-post.html' title=''/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-3515294341140295972</id><published>2007-12-26T21:57:00.001+09:00</published><updated>2007-12-26T22:12:05.845+09:00</updated><title type='text'></title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;&lt;br /&gt;日暮里に「深セン」というあんかけチャーハン専門のこだわり店がある。「セン」の字は、土に川って書くやつね。香港から中国側に川渡ったところの深センと同じ漢字。そういえば昔、深センの駅で写真とってたら、軍人にすごい怒られたことがあったなあ。どうでもいいついでに、個人的に深センといえばチャイナドレス。香港では滅多に見かけないチャイナドレスの女の子だけど、深センに入るとやにわに街に登場する。あれは観光客向けのサービスだったのかもしれない。市場なんかにいたのは、生きたトリを詰め込んだ籠を担いで外人の僕らにまで売ろうとする農民服の女の子とかだったからなあ。2000年ころの話。&lt;br /&gt;&lt;br /&gt;で、日暮里の深センの話だけど、このあたりで生活している独身20代男性は毎日通うべきだと思う。うまい。この店の「あんかけチャーハン」は、同じようなメニューを食べさせてくれる店をほかに知らないので説明しにくいんだけど、ようは卵をからめてざっくりと炒めたライスに中華風の一品料理をたっぷりとのせたもの。一品料理のメニューとしては、麻婆豆腐、羊肉炒め、豚角煮炒め、青菜炒め、日替わり（鶏肉と旬の野菜炒めのことが多い）なんかが定番で、夜になると調達した食材に応じてさらに凝ったものが追加される。魚飯とか。こんなところでアドバタイズしてるくらいだから、どれも絶品なわけですよ。しかも安い。笑っちゃうくらいに熱いスープと工夫されたデザートが全品についていて、日替わりなんて600円なんだから。もっと高くてもいいのに。&lt;br /&gt;&lt;br /&gt;調理をしているのはマスター一人だし、基本は全部注文を受けてから作るので、タイミングが悪いとけっこう待たされる。でもまあ、調理している手際を見ているだけで相当楽しい気持ちになれる。ビールでも飲んでればいいしね。青島が350円。青島の黒が500円。もうちょっと儲けてもいいんじゃないかって心配になるような値段。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/k16/682114083/" title="R0011616 by Keiichirou Shikano, on Flickr"&gt;&lt;img src="http://farm2.static.flickr.com/1373/682114083_0b4917634f_m.jpg" width="240" height="180" alt="R0011616" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;この店の料理がどれくらいうまいかっていうと、僕が今日レアメニューのビーフンをうっかり頼んじゃって（チャーハンじゃないメニューをはじめて見た）、ビーフンってのはしいたけ嫌いにとっては第一級の危険食品なわけだけど、やっぱり入ってて、幸い乾燥物じゃなくて生だったので皿全体には被害がなく、全体としてはむしろいつもの深センクオリティで、だからがんばって先に個体だけをビールで流し込んでから残りをおいしくいただいた。それくらいにうまいのです。（しいたけを身体に取り入れるのなんて、たぶんもう確実に20年以上ぶりだ。）&lt;br /&gt;&lt;br /&gt;    &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-3515294341140295972?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/3515294341140295972/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=3515294341140295972' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/3515294341140295972'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/3515294341140295972'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2007/12/2000-20600-350500.html' title=''/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm2.static.flickr.com/1373/682114083_0b4917634f_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-8186683899579868024</id><published>2007-12-13T19:09:00.001+09:00</published><updated>2011-02-10T14:53:17.027+09:00</updated><title type='text'>GhostScriptでヒラギノを使うまとめ</title><content type='html'>ghostscript でヒラギノが使いたい。&lt;br /&gt;&lt;br /&gt;PostScriptで遊んでいて歯がゆいナンバーワンは、後置記法なんかじゃなく、日本語の出力だったりする。gsまわりのパッケージを一通りインストールした Debian であれば、/Ryumin-Light-EUC-H とか指定するだけで、とりあえずは日本語を出力することはできる。でも、そのときに使われるフォントは、/var/lib/defoma/gs.d/dirs/fonts/cidfmap に登録されている TrueType のもの。職場にはきちんとハコで購入したヒラギノがあるのに、何が悲しくて微妙に美しくない TrueType のフォントを使わなければならないのか。最近の ghostscrpt なら OpenType のフォントにも対応しているはずだ。ところが、この cidfmap を編集しても、OpenType のフォントを使えるようにはならないらしい。&lt;br /&gt;&lt;br /&gt;そこで、Debian の ghostscript でヒラギノ（というかOpenTypeフォント一般）を使う方法のまとめ。ghostscript のバージョンについては複雑すぎるので省略。少なくとも 8.15 では以下の2つを実行すればいい。&lt;ol&gt;&lt;li&gt;FontResourceDir/CIDFont に、フォントのCIDデータを用意する。&lt;/li&gt;&lt;li&gt;FontResourceDir/Fontに、フォントと同じ名前のファイルを作って、フォント辞書を生成するコードを用意する。&lt;/li&gt;&lt;/ol&gt;FontResourceDirは、Debianなら/usr/share/gs-esp/*.**/lib/gs_res.psで定義されているディレクトリで、やはりDebianなら/usr/share/gs-esp/*.**/Resource/ になる。（*.**はghostscriptのバージョン。8.15とか）&lt;br /&gt;&lt;br /&gt;1. については、フォントのファイル（*.otf）へのシンボリックリンクをFontResourceDir/CIDFont に張っておけばOK。&lt;br /&gt;&lt;br /&gt;2. で用意するコードは、たとえばUTF-8の横書き用ヒラギノ角ゴシックW3のものであれば、&lt;pre&gt;/HiraKakuPro-W3-UniJIS-UTF8-H&lt;br /&gt;/UniJIS-UTF8-H /CMap findresource&lt;br /&gt;[/HiraKakuPro-W3 /CIDFont findresource]&lt;br /&gt;composefont&lt;br /&gt;pop&lt;/pre&gt;これをHiraKakuPro-W3-UniJIS-UTF8-Hという名前のファイルに保存して FontResourceDir/Font に置く。このファイルは、使いたいフォントとエンコードごとに必要。&lt;br /&gt;&lt;br /&gt;ちなみに composefont は、スタックからフォント名とCMapのデータとCIDフォントのデータをとって、フォント辞書を生成し、それをスタックの一番上に積むオペレータ。だから最後に pop がいる。&lt;br /&gt;&lt;br /&gt;これできれいな日本語が出力できるようになった。&lt;pre&gt;/HiraKakuPro-W3-UniJIS-UTF8-H findfont 30&lt;br /&gt;scalefont setfont&lt;br /&gt;newpath 30 700 moveto ( いつまでも責了しないのは本じゃない。 ) show&lt;br /&gt;newpath 30 660 moveto ( そんなのは、ただのドキュメントだ！  ) show&lt;br /&gt;newpath 380 620 moveto ( by ctakao  ) show&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/k16/2108461448/" title="japanese-test by Keiichirou Shikano, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2172/2108461448_d96547fd9d.jpg" width="353" height="500" alt="japanese-test" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-8186683899579868024?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/8186683899579868024/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=8186683899579868024' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/8186683899579868024'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/8186683899579868024'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2007/12/ghostscript-postscriptgs-debian-ryumin.html' title='GhostScriptでヒラギノを使うまとめ'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm3.static.flickr.com/2172/2108461448_d96547fd9d_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-7212119098068167002</id><published>2007-11-20T21:48:00.000+09:00</published><updated>2007-12-07T12:27:47.972+09:00</updated><title type='text'></title><content type='html'>&lt;b&gt;追記（2007/12/10）&lt;/b&gt;&lt;br /&gt;報告が遅くなりましたが、Jin-Hwan Choさんにすぐに修正対応していただきました。&lt;br /&gt;&lt;br /&gt;[cvs] Diff of /dvipdfmx/src/pdfdev.c &lt;a href="http://cvs.ktug.or.kr/viewcvs/dvipdfmx/src/pdfdev.c?r1=1.63&amp;r2=1.64"&gt;http://cvs.ktug.or.kr/viewcvs/dvipdfmx/src/pdfdev.c?r1=1.63&amp;r2=1.64&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;困っている人は、CVSの先端をビルドするか、20071115 のスナップショットに上記のパッチを当てるだけでも大丈夫そう。&lt;br /&gt;&lt;br /&gt;&lt;b&gt;追記ここまで&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;dvipdfmx をアップデートしたら2日間はまってしまった。どうやらetchの dvipdfmx には注意が必要らしい。&lt;br /&gt;&lt;br /&gt;自分が遭遇した不具合は2つ。&lt;ol&gt;&lt;li&gt;dvipdfmx（20050831）の picture 環境で、multiput の出力がずれる&lt;/li&gt;&lt;li&gt;細身のCourierフォント（pcrr8rn）が dvipdfmx で細くならない&lt;br/&gt;（&lt;a href="http://oku.edu.mie-u.ac.jp/~okumura/texfaq/qa/44806.html"&gt;http://oku.edu.mie-u.ac.jp/~okumura/texfaq/qa/44806.html&lt;/a&gt;）&lt;/li&gt;&lt;/ol&gt;このうち 2. のほうは updmap の問題らしく、TeX Q&amp;A にある&lt;a href="http://oku.edu.mie-u.ac.jp/~okumura/texfaq/qa/44807.html"&gt;土村さんのパッチ&lt;/a&gt;で解決する。&lt;br /&gt;&lt;br /&gt;1. については、次のような2種類の図形を描いてみると問題がはっきりわかる。&lt;pre&gt;\begin{picture}(100,10)%&lt;br /&gt;    \multiput(0,0)(.1,0){1000}{\circle*{10}}&lt;br /&gt;\end{picture}%&lt;br /&gt;&lt;br /&gt;\begin{picture}(100,10)%&lt;br /&gt;    \put(0,-10){\circle*{10}}&lt;br /&gt;    \put(100,-10){\circle*{10}}&lt;br /&gt;\end{picture}%&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;上下の picture は、それぞれ同じ幅になることが期待されるけど、dvipdfmx（20050831）では multiput したほうが長くなってしまう。（20070518 でも同じ。）&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/k16/2049195549/" title="dvipdfmx-result by Keiichirou Shikano, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2130/2049195549_5632635c93_m.jpg" width="240" height="140" alt="dvipdfmx-result" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;dvips で ps にして Acrobat 7.0 で pdf にすると、期待どおり同じ長さになる。（以前のバージョンのdvipdfmx（20040411）でも同じ長さになる。）&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/k16/2049195559/" title="dvipd-acrobat-result by Keiichirou Shikano, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2148/2049195559_891b9e6032_m.jpg" width="240" height="155" alt="dvipd-acrobat-result" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;原因も修正方法も解明できなかったので、とりあえず報告のメールを送った。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-7212119098068167002?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/7212119098068167002/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=7212119098068167002' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/7212119098068167002'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/7212119098068167002'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2007/11/dvipdfmx-2etch-dvipdfmx-2.html' title=''/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm3.static.flickr.com/2130/2049195549_5632635c93_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-89242770938082927</id><published>2007-11-18T19:48:00.001+09:00</published><updated>2007-11-18T19:48:26.092+09:00</updated><title type='text'></title><content type='html'>&lt;br /&gt;    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;&lt;br /&gt;テスト&lt;br /&gt;    &lt;/div&gt;&lt;br /&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-89242770938082927?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/89242770938082927/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=89242770938082927' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/89242770938082927'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/89242770938082927'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2007/11/blog-post.html' title=''/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-1563417086058838235</id><published>2007-10-20T12:35:00.000+09:00</published><updated>2007-10-20T12:51:47.669+09:00</updated><title type='text'></title><content type='html'>やっぱりSocket370のマザーなんて壊滅だった。唯一すぐ手に入ったまっとうな商品が、&lt;a href="http://www.supermicro.com/products/motherboard/P3/815E/P3TSSE.cfm"&gt;SuperMicroのP3TSSE&lt;/a&gt;で、実売は23000円。どう考えても2007年の買い物じゃないけど、しかたない。メーカー取り寄せとのことだったけど、「Your Best P4 Motherboard」と書かれた箱に入ってやってきたので、もうメーカーにもまともな在庫はないのかもしれない。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/k16/1645786238/" title="Photo Sharing"&gt;&lt;img src="http://farm3.static.flickr.com/2317/1645786238_3d4b2fc447_m.jpg" width="240" height="180" alt="supermicro p3tsse" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;でもこれ815EだしDDRは使えないんだよな。PC133のメモリも何枚か持っていたはずなんだけど、こないだ古いPCを処分したときに一緒に引き取ってもらっちゃたみたい。さすがにもう使うことはないだろうと思ったと思われる。しかたないのでメモリも買う。512MBで20000円。げー。いまどきPC133のSDRAMって信じられないくらい高額なのね……。6000円くらいのへなちょこなバルク品も試してみたんだけど、認識されなかった。最近はメモリの相性なんてほとんど気にしなくなってたので、ここでふたたび時代に取り残されている感。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-1563417086058838235?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/1563417086058838235/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=1563417086058838235' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/1563417086058838235'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/1563417086058838235'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2007/10/socket370-supermicrop3tsse-230002007.html' title=''/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm3.static.flickr.com/2317/1645786238_3d4b2fc447_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-3667972519842560475</id><published>2007-10-16T21:03:00.000+09:00</published><updated>2007-10-16T21:12:38.157+09:00</updated><title type='text'></title><content type='html'>どうやらマザーボードを買い換えないとだめらしい。買い換えるのはいいんだけど、いまどきDDR PC2100に対応したまともなSocket370のボードなんて手に入るのかなあ。&lt;br/&gt;&lt;br /&gt;&lt;br /&gt;やっぱりTualatinだよね。&lt;br/&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/k16/1586692651/" title="Photo Sharing"&gt;&lt;img src="http://farm3.static.flickr.com/2244/1586692651_9caa239165_m.jpg" width="240" height="180" alt="tualatin" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-3667972519842560475?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/3667972519842560475/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=3667972519842560475' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/3667972519842560475'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/3667972519842560475'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2007/10/ddr-pc2100socket370-tualatin.html' title=''/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm3.static.flickr.com/2244/1586692651_9caa239165_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-8638184441800071557</id><published>2007-10-12T23:34:00.000+09:00</published><updated>2007-10-12T23:36:50.630+09:00</updated><title type='text'></title><content type='html'>SXMLから、ある属性を持つ要素をSXPathを使って取り出したい。たとえば英語と日本語の文章からなるこんなデータから、lang属性が"ja"の要素を取り出したい。&lt;pre&gt;(define e&lt;br /&gt;  '(*TOP*&lt;br /&gt;    (p (|@| (lang "ja"))&lt;br /&gt;       "こんにちはこんにちは"&lt;br /&gt;       (emph "日本語です"))&lt;br /&gt;    (p (|@| (lang "en"))&lt;br /&gt;       "hellohello"&lt;br /&gt;       (emph "I got english"))&lt;br /&gt;    (m (p (|@| (lang "ja"))&lt;br /&gt;          "あしたは休み")&lt;br /&gt;       (p (|@| (lang "en"))&lt;br /&gt;          "I can't work any more"))))&lt;/pre&gt;どうやらSXPathで遊ぶときは、「真偽を返す関数」をsxml:xxxみたいな名前の関数に渡してコンバータを作り、それを要素に適用するというのが常套っぽい。いまは属性をもとに評価したいので、「真偽を返す関数」としては「lang属性の値が"ja"かどうかテストするプロシージャ」になるんだろうな。そして木全体をめぐりたいので、sxml:descendantで作ったコンバータをルートノードに適用すればよさそうだ。&lt;pre&gt;(use sxml.sxpath)&lt;br /&gt;(use sxml.tools)&lt;br /&gt;&lt;br /&gt;(define (f r n v)&lt;br /&gt;  ((sxml:descendant&lt;br /&gt;    (lambda (e) (equal? "ja" (sxml:attr e 'lang))))&lt;br /&gt;   r))&lt;br /&gt;&lt;br /&gt;(define q (sxpath `(,f)))&lt;/pre&gt;実行結果&lt;pre&gt;&lt;font color="blue"&gt;gosh&amp;gt;&lt;/font&gt; &lt;b&gt;(q e)&lt;/b&gt;&lt;br /&gt;((p (|@| (lang "ja")) "こんにちはこんにちは" (emph "日本語です")) &lt;br /&gt; (p (|@| (lang "ja")) "あしたは休み"))&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-8638184441800071557?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/8638184441800071557/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=8638184441800071557' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/8638184441800071557'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/8638184441800071557'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2007/10/sxmlsxpathlangja-define-e-top-p-lang-ja.html' title=''/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-2464137779363133211</id><published>2007-10-09T22:51:00.000+09:00</published><updated>2007-10-09T22:58:21.036+09:00</updated><title type='text'></title><content type='html'>つっかかるようなシューベルトが好きといえばわかる人にはわかるとおり、ぼくはアファナシエフの弾くシューベルトが好きだ。で、10月1日に彼が来日してシューベルト&lt;b&gt;も&lt;/b&gt;弾くというので、トッパンホールにいってきた。さすがに大御所の演奏会だけあっていい値段だったし、聴衆もおじいさんおばあさんが多くてなんだかなーという感じ。彼らの大半はシューベルト&lt;b&gt;だけ&lt;/b&gt;が目当てなんだろうな。でも残念でした。この日、アファナシエフが弾きたかったのは、途中の休憩をはさんで演目の真ん中に演奏したシルベストロフだったらしい。それをはさんで演奏したシューベルトの即興曲は、明らかに軽く流してた。すごくうまいけど。&lt;br /&gt;&lt;br /&gt;そもそもシューベルトの特にピアノ曲は、例えばかわいい女の子といっしょにいる最中に「この楽しい時間はどうしていつか終わってしまうんだろう」みたいに思い始めてしまったときのあの何ともいえない気分が永遠に引きのばされる感じがたまらないと思うんだけど、そういう雰囲気には欠ける演奏だった。楽しい（pleasure）が幸せ（happy）に結び付くとは限らないってダライ・ラマは言ってるけど、だからこそ「楽しさをなんとか引きのばして幸せを錯覚したい」っていう気分にきゅんとなるわけで、そうでないシューベルトは老後の楽しみにはいかもしれないけど（なにしろアファナシエフはすごくうまい）、ぼくが聴きたいのとは違う。&lt;br /&gt;&lt;br /&gt;アファナシエフはピアノソナタ18番をレコーディングしてるけど、そこではこの錯覚した幸せ感を満喫できる。こないだの高橋アキの13番にも同じ印象を受けた。10月1日のアファナシエフは、むしろシルベストロフの曲で、この感じを演奏者として楽しんでいた気がする。そういえば高橋アキはアンコールにサティの「おまえがほしい」を弾いて、それを聴いていたときは「ぶちこわしじゃん」と思ったけど、あの堂々巡り感も同じような世界観なのかもしれない。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-2464137779363133211?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/2464137779363133211/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=2464137779363133211' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/2464137779363133211'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/2464137779363133211'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2007/10/101-pleasurehappy-18-13-101.html' title=''/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-1618985222317304701</id><published>2007-10-06T21:46:00.000+09:00</published><updated>2007-10-06T22:41:26.583+09:00</updated><title type='text'></title><content type='html'>自分用のメモ。なんかこんな感じのリストがあるとする。&lt;pre&gt;(define life&lt;br /&gt;  '(i (value "2007")&lt;br /&gt;      "年"&lt;br /&gt;      (ii (value "10")&lt;br /&gt;          "月"&lt;br /&gt;          (iii (en "9")&lt;br /&gt;               "日"))&lt;br /&gt;      (delimiter "/")&lt;br /&gt;      (value "2009")&lt;br /&gt;      "年"&lt;br /&gt;      (ii (value "1")&lt;br /&gt;          "月"&lt;br /&gt;          (iii (en "31")&lt;br /&gt;               "日"))&lt;br /&gt;      (iii (value "10")&lt;br /&gt;           "日")))&lt;/pre&gt;一番上の階層のテキスト情報だけを抜きたい。&lt;br /&gt;つまり、iiとiiiのタグの子孫を飛ばして読んでいきたい。結果として得たい文字列は、"2007年/2009年"。&lt;br /&gt;&lt;br /&gt;SXPathを使う。&lt;pre&gt;(use sxml.sxpath)&lt;br /&gt;&lt;br /&gt;(define (text-self elem)&lt;br /&gt;  (sxml:string ((node-self (ntype?? '*any*)) elem)))&lt;br /&gt;&lt;br /&gt;(text-self&lt;br /&gt; (cons 'dummy&lt;br /&gt;       ((sxml:child (sxml:invert (ntype-names?? '(ii iii)))) life)))&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-1618985222317304701?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/1618985222317304701/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=1618985222317304701' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/1618985222317304701'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/1618985222317304701'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2007/10/define-life-i-value-2007-ii-value-10.html' title=''/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-8732081781435640399</id><published>2007-09-30T22:18:00.000+09:00</published><updated>2007-09-30T22:24:21.871+09:00</updated><title type='text'></title><content type='html'>9月20日に高橋アキの&lt;a href="http://members.jcom.home.ne.jp/akitakahashi/dramatic5.htm"&gt;ピアノドラマティック・シリーズ　#5&lt;/a&gt;にいってきた。高橋アキについては、一時期よくサティを弾いていた人という認識しかなかったし、今回の演目にもシューベルトの13番とかあったので、もっと「耳にやさしい」コンサートかと思ってたよ。自分のなかでシューベルトブームだったのと、チェロのローハン・デ・サラムが競演してコダーイの無伴奏チェロとかドビュッシーのソナタとかやるということだったので、それなら奥さまがチェロを聴いてみたがっていたしちょうどいいかと思ってチケットを買った。&lt;br /&gt;&lt;br /&gt;で、このローハンおじさん、高橋アキがモンポウとかシューベルト13番のような聴き心地のいいクラシカルな演目をやるといってるところに「オレにコダーイをひかせろ」といって殴り込んできただけのことはある。メロディックなさじ加減ゼロ。たとえばヨーヨー・マのひくコダーイは、このむちゃくちゃハードな技巧の曲を可能なかぎり美しく聴かせようみたいなサービス精神に溢れているんだけど、ローハンおじさんにそんな気配はない。最後の一音なんて、ほとんど放り投げてるもんな（ヨーヨーのCDでは、たっぷり響かせて終わる）。もう、この演奏だけでファンになりました。翌週の27日にも渋谷でローハンおじさんが聴けるというので、もちろんそちらにもいってきた。&lt;br /&gt;&lt;br /&gt;27日のほうは、フルートのカリン・レヴァインと競演で、現代曲オンリー。50人くらいしか聴衆のいない&lt;a href="http://www.anewcityguide.com/list/11532"&gt;小さな演奏会&lt;/a&gt;だったけど、これがまた強烈だった。ローハンおじさんはコダーイに加えて、クセナキス（本人はゼナキスと発音してた）と松村禎三（！）のソロ曲を演奏してくれた。クセナキスはもともとプログラムにあって、期待もしてたんだけど、ゆうに期待を裏切ってくれる。松村禎三は、追悼として当日プログラムに追加されていた。17絃箏のための祈祷歌をチェロ独奏むけにアレンジしたものらしい。最初からチェロ独奏の曲でしょうっていうくらいの完成度なんですが、それは松村禎三の曲の力ですか、それともローハン・デ・サラムのうまさですか。なんかいま東京でレコーディングしているらしいんだけど、コダーイはもちろん、このクセナキスのKottosと松村禎三をなんとか収録していただけないものでしょうか。&lt;br /&gt;&lt;br /&gt;この日はフルートのカリン・レヴァインさんもよかったな。とくにカイヤ・サーリアホとジャチント・シェルシ。フルートってこんなにいろんな音が出る楽器だったんですね。バスフルートやアルトフルートの独奏曲を生で聴く機会があるとは思いませんでした。&lt;br /&gt;&lt;br /&gt;高橋アキを忘れていたわけではなく、9月20日の演奏にはものすごく共感するんだけど、いかんせん後にやった9月27日の演奏会の印象のほうが強烈に残っているのですっかり話がずれた。とくに、つっかかるようなシューベルトは、そうでなければシューベルトをあえて聴く意味はないよねと個人的にはすごく同意したい。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-8732081781435640399?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/8732081781435640399/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=8732081781435640399' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/8732081781435640399'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/8732081781435640399'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2007/09/920-5-13-13cd27-2750-17kottos-920927.html' title=''/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-5203864232280804097</id><published>2007-09-23T22:57:00.000+09:00</published><updated>2007-09-23T23:10:32.010+09:00</updated><title type='text'></title><content type='html'>現在の書籍の製作スタイルでは、横長のモニターを縦にして使うほうが都合がいい。とにかくビルドしたPDFのページを画面いっぱいに大きくして確認したいのである。そして書籍のページというものは横長ではなく縦に長い。ところが職場で使っている24インチのモニターはスタンドがへぼくて縦にして使うことができない。それでスタンドをはずして机の上に平置きにして無理やり縦にして使ってみた。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/k16/1428427694/" title="Photo Sharing"&gt;&lt;img src="http://farm2.static.flickr.com/1244/1428427694_75c1e261bf_m.jpg" width="240" height="180" alt="R0011978" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;これがあんがい使える。廃熱も大丈夫なようだ。&lt;br /&gt;&lt;br /&gt;本当はPDFを見開きで確認したいので、このサイズのモニターが二枚はほしいところ。もちろんちゃんとアームつきでな。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-5203864232280804097?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/5203864232280804097/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=5203864232280804097' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/5203864232280804097'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/5203864232280804097'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2007/09/pdf24-pdf.html' title=''/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm2.static.flickr.com/1244/1428427694_75c1e261bf_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-2625668201696331918</id><published>2007-08-20T11:38:00.000+09:00</published><updated>2007-08-20T11:48:49.843+09:00</updated><title type='text'></title><content type='html'>先週、&lt;a href="http://k16journal.blogspot.com/2007/08/gauche-kakai-2004.html"&gt;2004年ごろには Gauche に KAKAI のライブラリがあったらしい&lt;/a&gt;とか書いたけど、&lt;a href="http://gauche.cvs.sourceforge.net/gauche/Gauche-kakasi/"&gt;sourceforge のページから今でもダウンロードできる&lt;/a&gt;と shiro さんに教えていただいた。ありがとうございます。（そして、ろくに確認せず適当なことを書いていてすみません。）&lt;br /&gt;&lt;br /&gt;しかもインストールしたら使えた。&lt;pre&gt;(use text.kakasi)&lt;br /&gt;(kakasi-begin :JH :p)&lt;br /&gt;(display (kakasi-convert "素子"))&lt;br /&gt;(newline)&lt;br /&gt;(kakasi-end)&lt;/pre&gt;これを kakasi-trial.scm とすると、&lt;pre&gt;$ &lt;b&gt;gosh -V&lt;/b&gt;&lt;br /&gt;Gauche scheme interpreter, version 0.8.10 [utf-8,pthreads]&lt;br /&gt;$ &lt;b&gt;gosh kakasi-trial.scm&lt;/b&gt;&lt;br /&gt;{もとこ|そし}&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-2625668201696331918?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/2625668201696331918/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=2625668201696331918' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/2625668201696331918'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/2625668201696331918'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2007/08/2004-gauche-kakai-sourceforge-shiro-use.html' title=''/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-4997357044261645083</id><published>2007-08-17T17:45:00.001+09:00</published><updated>2010-06-03T17:05:04.222+09:00</updated><title type='text'></title><content type='html'>&lt;b&gt;［2010年6月3日 追記］&lt;a href="http://note.golden-lucky.net/2010/06/emacs-emacs-22.html"&gt;改良版はこちら&lt;/a&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;emacs で、検索パターンをその後の編集中ずっとハイライトにしたい。インクリメンタルサーチの結果でもハイライトされるけど、あれだと編集をはじめるとハイライトが解除されてしまうので、使えない。&lt;br /&gt;具体的には、作業中のバッファであるパターンを一時的にハイライトして、それを確認しながらを作業するための方法がほしい。こんな具合。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/k16/1146982188/" title="Photo Sharing"&gt;&lt;img src="http://farm2.static.flickr.com/1412/1146982188_fe744bd02b_o.png" width="498" height="526" alt="highlight" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;この例は、 ja タグで囲まれた部分をハイライトするようにしたところ。普段はハイライト不要なんだけど、たとえば「 ja にも en にも出てくる語を検索して周辺の文章を編集したいんだけど en 内にあるほうは無視してもいいや」といった作業に便利じゃない？&lt;br /&gt;&lt;br /&gt;で、とりあえず作ってみた関数。&lt;pre&gt;;;; let designated pattern be highlight&lt;br /&gt;(defun highlight-regexp (re)&lt;br /&gt;  (interactive "sRegexp: \n")&lt;br /&gt;  (make-face 'my-highlight-face)&lt;br /&gt;  (set-face-foreground 'my-highlight-face "black")&lt;br /&gt;  (set-face-background 'my-highlight-face "yellow")&lt;br /&gt;  (defvar my-highlight-face 'my-highlight-face)&lt;br /&gt;  (setq font-lock-keywords (list (list re 0 my-highlight-face t)))&lt;br /&gt;  (font-lock-fontify-buffer))&lt;/pre&gt;M-x highlight-regexp すると正規表現の入力を促されるので、そこで適切なパターンを指定すると、上の例のようにハイライトされる。そういえば解除するときのことは考えてなかった。あと、上の例ではなんとなく改行をまたいだマッチに成功してるけど、emacs の正規表現である以上、改行をまたいだパターンのマッチは期待通りにいかないと覚悟すべき。やっぱりこのエディタは、本当のところは文章のパワー編集には向かないんじゃないだろうか。&lt;br /&gt;&lt;br /&gt;まあ問題はあるけど、ここまではよかった。&lt;br /&gt;&lt;br /&gt;実はいま c さんに、「xyzzy で同じことがしたい」と脅されている。xyzzy は普段使ってないから、色の付け方とかわからんのですよ……。&lt;br /&gt;Windows なら EmEditorとかで GUI のメニューから同じようなことができるから、とりあえずそっちでいいんじゃないかなあ。だめ？&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-4997357044261645083?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/4997357044261645083/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=4997357044261645083' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/4997357044261645083'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/4997357044261645083'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2007/08/emacs-ja-ja-en-en-let-designated.html' title=''/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-7270488056887670215</id><published>2007-08-16T21:55:00.000+09:00</published><updated>2007-08-16T22:57:23.611+09:00</updated><title type='text'></title><content type='html'>昨日、Gauche には KAKAI のライブラリとかないとか書いたけど、&lt;a href="http://practical-scheme.net/gauche/oldnews.html"&gt;2004年ごろにはあったらしい&lt;/a&gt;。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-7270488056887670215?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/7270488056887670215/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=7270488056887670215' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/7270488056887670215'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/7270488056887670215'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2007/08/gauche-kakai-2004.html' title=''/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-9047919458333395009</id><published>2007-08-15T12:45:00.000+09:00</published><updated>2007-08-15T13:13:21.888+09:00</updated><title type='text'></title><content type='html'>cさんに「索引の読み仮名をひらがなで明示的に指定するのは前時代すぎてあほみたいだ。休み明けまでに何とかしとけ」と恫喝されたので、彼女が休みのあいだに急いで対策することにした。&lt;br /&gt;&lt;br /&gt;まあ、実際の cさんはそんなひどい言い方をする人ではなく、ちょうかわいいんだけど、たしかに LaTeX ベースで本を作っていると索引のふりがな入力がうっとうしい。労力の問題だけでなく、原稿にひらがなが氾濫して読みにくくなるという意味でもうっとうしい。&lt;br /&gt;&lt;br /&gt;漢字かな変換にはKAKASIを使うのが常套なんだろうな。Gauche には Ruby とちがって KAKASI のライブラリはないけれど、ほとんどジョーカーみたいな c-wrapper がある。&lt;br /&gt;これで libkakasi.h に宣言されているCの関数が Gauche から使える。&lt;pre&gt;(use gauche.charconv)&lt;br /&gt;(use c-wrapper)&lt;br /&gt;(c-load-library "/usr/lib/libkakasi.so.2.1.0")&lt;br /&gt;(c-include "/usr/include/libkakasi.h")&lt;br /&gt;&lt;br /&gt;(define (kanji-&gt;hira str)&lt;br /&gt;  (let ((base-ces "utf-8")&lt;br /&gt;        (kakasi-ces "iso2022jp"))&lt;br /&gt;    (kakasi_getopt_argv 3 '("kakasi" "-JH" "-p"))&lt;br /&gt;    (ces-convert&lt;br /&gt;      (x-&gt;string (kakasi_do (ces-convert str base-ces kakasi-ces)))&lt;br /&gt;      kakasi-ces base-ces)))&lt;/pre&gt;KAKASIがUTF-8を扱えないのが厄介だけど、それ以外はとても素直に Gauche で漢字かな変換ができる。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;font color="blue"&gt;gosh&amp;gt;&lt;/font&gt; &lt;b&gt;(kanji-&gt;hira "素子")&lt;/b&gt;&lt;br /&gt;{もとこ|そし}&lt;/pre&gt;さて、この「素子」のようにユニークな読みを決定できない項目があると困っちゃうんだけど、「もとこ」か「そし」かの判断を機械的にすべきではなさそうだ&lt;br /&gt;（「この素子を開発したのは素子さんです」問題）。だから、こういうのだけは人力であらかじめ指定しておくのが最適な対応だと思うのですが、それでかまわないでしょうか？＞ cさん&lt;br /&gt;こんなふうにマークアップ原稿がLaTeXへと変換されるようにします。&lt;pre&gt;&amp;lt;p&amp;gt;&lt;br /&gt;  この素子を開発したのは素子さんです。&lt;br /&gt;    &amp;lt;indexterm&amp;gt;&amp;lt;i1 sortas="そし"&amp;gt;素子&amp;lt;i2&amp;gt;開発者&amp;lt;/i2&amp;gt;&amp;lt;/i1&amp;gt;&amp;lt;/indexterm&amp;gt;&lt;br /&gt;    &amp;lt;indexterm&amp;gt;&amp;lt;i1 sortas="もとこ"&amp;gt;素子&amp;lt;/i1&amp;gt;&amp;lt;/indexterm&amp;gt;&lt;br /&gt;    &amp;lt;indexterm&amp;gt;&amp;lt;i1&amp;gt;開発者&amp;lt;/i1&amp;gt;&amp;lt;/indexterm&amp;gt;&lt;br /&gt;&amp;lt;/p&amp;gt;&lt;/pre&gt;↓&lt;pre&gt;&lt;br /&gt;この素子を開発したのは素子さんです。\index{そし@素子!かいはつしゃ@開発者}\index{もとこ@素子}\index{かいはつしゃ@開発者}&lt;/pre&gt;&lt;br /&gt;&lt;hr&gt;&lt;br /&gt;&lt;i&gt;参考：&lt;/i&gt;&lt;br /&gt;&lt;a href="http://karetta.jp/article/blog/oneline/008137"&gt;今日の一行::ひらかなのインデックス&lt;/a&gt; の cut-sea さんの解&lt;br /&gt;ごとけんさんの&lt;a href="http://raa.ruby-lang.org/project/ruby-kakasi/"&gt; ruby-kakasi &lt;/a&gt;の kakasi.c&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-9047919458333395009?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/9047919458333395009/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=9047919458333395009' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/9047919458333395009'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/9047919458333395009'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2007/08/c-c-latex-kakasigauche-ruby-kakasi-c.html' title=''/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-5979370531272122665</id><published>2007-08-10T15:56:00.000+09:00</published><updated>2007-08-10T19:35:57.259+09:00</updated><title type='text'></title><content type='html'>もう、PostScriptでフィボナッチ数列くらいなら昼休みにコーヒー飲みながらでも考えられる。&lt;pre&gt;/fib {0 1 2 index -1 1 {pop exch 1 index add} for} def&lt;/pre&gt;&lt;br /&gt;ただ、せっかく PostScript なので、結果を印刷とかもしたい。印刷には show オペレータを使うわけだけど、show は文字列（string）しかとれない。fib オペレータが返すのは数値（integer）なので、文字列の型に変換する必要がある。&lt;br /&gt;&lt;br /&gt;PostScript で型を文字列に変換するには、=string cvs とすればいいようだ。&lt;pre&gt;%!&lt;br /&gt;/fib {0 1 2 index -1 1 {pop exch 1 index add} for} def&lt;br /&gt;/Palatino-Linotype findfont 300 scalefont setfont&lt;br /&gt;10 10 moveto&lt;br /&gt;11 fib == =string cvs show&lt;/pre&gt;これでページの左下に大きく「89」と印刷される。やっぱりPalatinoフォントの数字は美しい。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/k16/1068170559/" title="Photo Sharing"&gt;&lt;img style="border:1px solid #000000" src="http://farm2.static.flickr.com/1438/1068170559_433874d297_m.jpg" width="170" height="240" alt="fib-11" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;さらにグラフなど描いてみる。&lt;pre&gt;%!&lt;br /&gt;/fib {0 1 2 index -1 1 {pop exch 1 index add} for} def&lt;br /&gt;20 setlinewidth&lt;br /&gt;&lt;br /&gt;1 1 21 { % for&lt;br /&gt;    /i exch def&lt;br /&gt;    /x 27 i mul def&lt;br /&gt;&lt;br /&gt;    0 setgray&lt;br /&gt;    /Palatino-Linotype findfont 10 scalefont setfont&lt;br /&gt;    10 x 5 sub exch moveto&lt;br /&gt;    i fib == =string cvs show&lt;br /&gt;&lt;br /&gt;    /r {rand i mod 21 div} def&lt;br /&gt;    r r r setrgbcolor&lt;br /&gt;    newpath&lt;br /&gt;        x 30 moveto&lt;br /&gt;        i fib == 10 div 30 add x exch lineto&lt;br /&gt;        stroke&lt;br /&gt;} for&lt;br /&gt;&lt;br /&gt;showpage&lt;/pre&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/k16/1069033306/" title="Photo Sharing"&gt;&lt;img  style="border:1px solid #000000" src="http://farm2.static.flickr.com/1151/1069033306_e761cfd8b2_m.jpg" width="170" height="240" alt="fib" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-5979370531272122665?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/5979370531272122665/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=5979370531272122665' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/5979370531272122665'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/5979370531272122665'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2007/08/postscript-fib-0-1-2-index-1-1-pop-exch.html' title=''/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm2.static.flickr.com/1438/1068170559_433874d297_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-5717055224889506432</id><published>2007-08-07T18:22:00.000+09:00</published><updated>2007-08-07T20:33:32.330+09:00</updated><title type='text'></title><content type='html'>PostScript で階乗のつづき。こんどは for 文で。&lt;pre&gt;/func {1 exch -1 1 {mul} for} def&lt;/pre&gt;ようするに、自分がしたい操作に必要な変数が、適切な数だけ適切な順番でスタックに積まれているようにすればいいらしい。そしてスタックというやつからは、直前に積んだものだけを取り出すことができる。&lt;br /&gt;&lt;br /&gt;たとえば上記で定義した階乗のオペランド func を以下のように呼び出すと、&lt;pre&gt;&lt;font color="blue"&gt;GS&amp;gt; &lt;/font&gt;&lt;b&gt;5 func&lt;/b&gt;&lt;/pre&gt;まず 5 がスタックに積まれる。この 5 は「funcへの引数」のつもりなんだけど、スタックから見るとそんなつもりはなくて、ただ値が積まれただけ。次は func を積むんだけど、func は上記のように定義されているので、その定義の一番最初にある 1 がスタックに積まれる。この時点のスタックの状態はこんな感じ。&lt;pre&gt; 1 &lt;br /&gt;---&lt;br /&gt; 5 &lt;/pre&gt;func の定義によれば、次は exch だ。これは、それまでスタックの1番上にあった要素とその下の要素を入れ替える。つまり、スタックの状態はこうなる。&lt;pre&gt; 5&lt;br /&gt;---&lt;br /&gt; 1&lt;/pre&gt;さらに -1 と 1 を順番に積んで、スタックの状態はこうなる。&lt;pre&gt; 1 &lt;br /&gt;---&lt;br /&gt;-1&lt;br /&gt;---&lt;br /&gt; 5&lt;br /&gt;---&lt;br /&gt; 1&lt;/pre&gt;ここで、本文が mul だけの for が登場する。for というオペレータは、スタックの値を 3つ消費し、それぞれの値を深いほうから順番に「繰り返しの最初」「繰り返しの更新」「繰り返しの終わり」として本文を繰り返す。ただし毎回の繰り返しでは、スタックの先頭に、そのターンにおける変数&lt;b&gt;のようなもの&lt;/b&gt;が積まれる。こう書くと複雑だけど、ようは最初に本文を実行するときには「5」が、2回目は「4」が、...、5回目は「1」がスタックの先頭に積まれるということ。つまり1回目の繰り返しのとき、スタックの状態はこう。&lt;pre&gt; 5&lt;br /&gt;---&lt;br /&gt; 1&lt;/pre&gt;本文の mul は、このスタックから値を 2つ取り出して、それらの積をあらためてスタックに積む。したがってスタックの状態は、&lt;pre&gt;5&lt;/pre&gt;2回目の繰り返しに際してスタックの先頭に「4」が積まれる。&lt;pre&gt; 4 &lt;br /&gt;---&lt;br /&gt; 5&lt;/pre&gt;このスタックで mul を適用すると、&lt;pre&gt; 20&lt;/pre&gt;3回目の繰り返しに際してスタックの先頭に「3」が積まれる。&lt;pre&gt; 3 &lt;br /&gt;---&lt;br /&gt; 20&lt;/pre&gt;mul を適用して&lt;pre&gt; 60&lt;/pre&gt;4回目の繰り返しに際してスタックの先頭に「2」が積まれる。&lt;pre&gt; 2 &lt;br /&gt;---&lt;br /&gt; 60&lt;/pre&gt;mul を適用して&lt;pre&gt;120&lt;/pre&gt;5回目の繰り返しに際してスタックの先頭に「1」が積まれる。&lt;pre&gt; 1 &lt;br /&gt;---&lt;br /&gt;120&lt;/pre&gt;mul を適用して&lt;pre&gt;120&lt;/pre&gt;おしまい。こうして最後のスタックの値を取り出せば（そのためには == を使う）、5の階乗の値が得られる。&lt;br /&gt;&lt;br /&gt;たぶん用語の使い方はいいかげん。はやく教科書こないかな。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-5717055224889506432?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/5717055224889506432/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=5717055224889506432' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/5717055224889506432'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/5717055224889506432'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2007/08/postscript-for-func-1-exch-1-1-mul-for.html' title=''/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-6631978364237583773</id><published>2007-08-06T00:04:00.000+09:00</published><updated>2007-08-09T21:11:40.090+09:00</updated><title type='text'></title><content type='html'>PostScript が意外におもしろいので真剣に勉強してみようと思う。教科書は、Web で PDF が全部公開されている &lt;a href="http://www.rightbrain.com/pages/books.html"&gt;"Thinking in PostScript"&lt;/a&gt; に決めた。書籍はもうとっくに絶版らしい。でも物理的な本が手もとにないとつらいんだよなあ。Amazon マーケットプレイスにも出品されているけどバカみたいに高額なので（6000円以上）、US の同様のサービスに注文した（600円くらい）。まだ届かない。出荷された気配もない。もう待ちきれないよう。&lt;br /&gt;&lt;br /&gt;というわけで、試行錯誤しながら階乗を考えてみた。&lt;pre&gt; /func {dup 1 eq {1 mul} {dup 1 sub func mul} ifelse} def&lt;/pre&gt;実行結果。&lt;pre&gt;&lt;font color="blue"&gt;GS&amp;gt;&lt;/font&gt; &lt;b&gt;10 func ==&lt;/b&gt;&lt;br /&gt;3628800&lt;br /&gt;&lt;font color="blue"&gt;GS&amp;gt;&lt;/font&gt; &lt;b&gt;20 func ==&lt;/b&gt;&lt;br /&gt;2.43290202e+18&lt;br /&gt;&lt;font color="blue"&gt;GS&amp;gt;&lt;/font&gt; &lt;b&gt;100 func ==&lt;/b&gt;&lt;br /&gt;inf.0&lt;/pre&gt;どうやら再帰的なオペレータの定義ができるらしい。はじめは、ふつうに for を使って解こうとしたんだけど、わかりませんでした。&lt;br /&gt;&lt;br /&gt;ところで Emacs の ps-mode は GS のビューワーと連動して出力結果がリアルタイムで見られてすごい。便利すぎ。ただしお絵描きを始めると日付が変わるようだ。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-6631978364237583773?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/6631978364237583773/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=6631978364237583773' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/6631978364237583773'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/6631978364237583773'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2007/08/postscript-web-pdf-thinking-in.html' title=''/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-4827421881943601335</id><published>2007-06-23T21:06:00.001+09:00</published><updated>2011-02-10T14:56:47.279+09:00</updated><title type='text'>Schemeの多値の正体は継続</title><content type='html'>SICPでは「多値」を表立って使うことはない。ただ、5.2.2で2種類のリストをやりとりするときに2変数のプロシージャを使った一見するとトリッキーな処理が登場して、これが実は多値なんだよという種明かしを脚注4でやっている。さらに、そのトリッキーな2変数プロシージャのことを継続（continuation）と呼ぶと説明している。&lt;br /&gt;&lt;br /&gt;多値も継続だったのか。&lt;br /&gt;&lt;br /&gt;噛みしめるために小さな例を考えてみた。つぎのプロシージャ one は、プロシージャ sincos が返す 2 値を受け取り、その 2 乗和を返す。sincos は引数の角度に対する sin の値と cos の値を返すので、プロシージャ one は引数にどんな数値を指定しても実数の 1 を返す。&lt;pre&gt;(define (one rad)&lt;br /&gt;  (receive (sin cos)&lt;br /&gt;      (sincos rad)&lt;br /&gt;    (+ (* sin sin) (* cos cos))))&lt;br /&gt;&lt;br /&gt;(define (sincos rad)&lt;br /&gt;  (values&lt;br /&gt;    (sin rad) (cos rad)))&lt;/pre&gt;このプロシージャ one は、values や receive という組み込みの多値のしくみを使わなくても、つぎのように継続を表すプロシージャ cont を使って多値を模倣できる。&lt;pre&gt;(define (one rad)&lt;br /&gt;  (sincos&lt;br /&gt;    rad&lt;br /&gt;    (lambda (sine cosine)&lt;br /&gt;      (+ (* sine sine) (* cosine cosine)))))&lt;br /&gt;&lt;br /&gt;(define (sincos rad cont)&lt;br /&gt;  (cont (sin rad) (cos rad)))&lt;/pre&gt;いちおう実行結果。&lt;pre&gt;&lt;font coloe="blue"&gt;gosh&amp;gt;&lt;/font&gt;&lt;b&gt;(one 123456)&lt;/b&gt;&lt;br /&gt;1.0&lt;br /&gt;&lt;font coloe="blue"&gt;gosh&amp;gt;&lt;/font&gt;&lt;b&gt;(one -9876)&lt;/b&gt;&lt;br /&gt;1.0&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;まとめ&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;計算の一部または全部をどうにかしたい場合があって（よその関数に渡したいとか、ちょっと保留しておきたいとか）、そのときの定石は「プロシージャでくるんでしまえ」。で、そういうプロシージャのことを「継続」（continuation）と呼ぶ。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-4827421881943601335?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/4827421881943601335/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=4827421881943601335' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/4827421881943601335'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/4827421881943601335'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2007/06/sicp5.html' title='Schemeの多値の正体は継続'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-8646555153411398201</id><published>2007-06-18T20:36:00.000+09:00</published><updated>2007-06-18T20:40:45.679+09:00</updated><title type='text'></title><content type='html'>ついやってしまった。&lt;br /&gt;&lt;br /&gt;Functional Programming IAT&lt;br /&gt;関数型指数（潜在的な関数型プログラミングの嗜好度）をはかる IAT&lt;br /&gt;&lt;a href="http://dame.dyndns.org/misc/fpiat/"&gt;http://dame.dyndns.org/misc/fpiat/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;「あなたの関数型指数は 0.62331761674765 です。正が関数型、負が手続き型です。」&lt;br /&gt;&lt;br /&gt;でも、設問では"Lisp"（Schemeではない）が関数型言語とされているんだけど、それはどうなの？&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-8646555153411398201?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/8646555153411398201/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=8646555153411398201' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/8646555153411398201'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/8646555153411398201'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2007/06/functional-programming-iat-iat-httpdame.html' title=''/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-1832926285736799962</id><published>2007-06-17T22:16:00.000+09:00</published><updated>2007-06-17T22:24:30.611+09:00</updated><title type='text'></title><content type='html'>練習問題を放置したままだったSICPの第5章をぽちぽち再開。こうやって再読してみると、すっかりどんな話だったか忘れてる。やっぱり手を動かさないで本を&lt;b&gt;読んでいるだけ&lt;/b&gt;じゃなんにも身につかない。編集という、まさに&lt;b&gt;読んでいるだけ&lt;/b&gt;の職業に自分が従事している現実を呪うのはこういう瞬間だ。ただの逆ギレだけど。&lt;br /&gt;&lt;br /&gt;というわけで第5章の練習問題に着手しはじめた。ところがすぐに困っちゃったのは、この章の内容がGauche（などのSchemeインタプリタ）で式を実行すれば確かめられる話じゃないこと。とくに5.2節でレジスタマシンのシミュレータをSchemeで作るまでは、紙と鉛筆でデータの流れを図示したりしながら、脳内レジスタマシンを妄想して読み進めるしかない。「レジスタマシンの動作を手でシミュレートしろ」といった問題を考えるのは楽しいんだけど、どうにも「わかった気になっているだけかも」という懸念がぬぐえないのが気持ち悪い。&lt;b&gt;どうでもいいけど、専門書や専門雑誌の編集者を楽しく長く続けていくのに求められる最強のスキルは、「わかった気になったところで留まっていられる」ことだとおもう。前々から気がついてはいたけれど、最近になってひどく実感するようになった。こういう感情をわざわざ書きとめているということは、そういうことだ。ここまでどうでもいい話。&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;この気持ち悪さはレジスタマシンがあれば解決する。かといって5.2節でシミュレータを作るまで待ってられないし（経験上、1問でも練習問題をぬかすと最後まで練習問題に手をつけずに読了する。帰納法で証明できたらかっこいいかもね）、そもそもSchemeでシミュレートするっていうのも気持ちが悪い。最初にこの章を読んだときは「これは教科書として画期的なアイデアだ」と思ったけど、実際はめんどくささのランクをひとつ繰り上げているだけなような気もする。&lt;br /&gt;&lt;br /&gt;アセンブリというわけにもいかないので、Cで書いてみることにした。たとえばフィボナッチ数列の第n項を求めるレジスタマシンのコントローラ（原書512ページのFigure5.12）。&lt;pre&gt;/* Implementation of a recursive fibonachi machine in C.&lt;br /&gt;   (Figure 5.12 of "SICP")&lt;br /&gt;   2007/6/17&lt;br /&gt;   k16.shikano@gmail.com&lt;br /&gt;*/ &lt;br /&gt;&lt;br /&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;#define STACKSIZE 100&lt;br /&gt;&lt;br /&gt;void fibloop();&lt;br /&gt;void afterfib1();&lt;br /&gt;void afterfib2();&lt;br /&gt;void fibdone();&lt;br /&gt;void immediate();&lt;br /&gt;void rtc(int);&lt;br /&gt;&lt;br /&gt;void initstack();&lt;br /&gt;void save(int);&lt;br /&gt;int restore();&lt;br /&gt;&lt;br /&gt;int cont = 0;&lt;br /&gt;int val;&lt;br /&gt;int n;&lt;br /&gt;&lt;br /&gt;main(int argc, char *argv[])&lt;br /&gt;{ &lt;br /&gt;  initstack();&lt;br /&gt;  n = atol(argv[1]);&lt;br /&gt;&lt;br /&gt;  fibloop();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void fibloop()&lt;br /&gt;{&lt;br /&gt;  while(n &amp;gt;= 2)&lt;br /&gt;    {&lt;br /&gt;      save(cont);&lt;br /&gt;      cont = 1;&lt;br /&gt;      save(n);&lt;br /&gt;      n = n - 1;&lt;br /&gt;    }&lt;br /&gt;  immediate();&lt;br /&gt;}  &lt;br /&gt;&lt;br /&gt;void afterfib1()&lt;br /&gt;{&lt;br /&gt;  n = restore();&lt;br /&gt;  cont = restore();&lt;br /&gt;  n = n - 2;&lt;br /&gt;  save(cont);&lt;br /&gt;  cont = 2;&lt;br /&gt;  save(val);&lt;br /&gt;  fibloop();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void afterfib2()&lt;br /&gt;{&lt;br /&gt;  n = val;&lt;br /&gt;  val = restore();&lt;br /&gt;  cont = restore();&lt;br /&gt;  val = val + n;&lt;br /&gt;  rtc(cont);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void immediate()&lt;br /&gt;{&lt;br /&gt;  val = n;&lt;br /&gt;  rtc(cont);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void fibdone()&lt;br /&gt;{&lt;br /&gt;  printf("answer = %d\n", val);&lt;br /&gt;  exit(1);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;/* return to continue */&lt;br /&gt;void rtc(int c)&lt;br /&gt;{&lt;br /&gt;  switch(c)&lt;br /&gt;    {&lt;br /&gt;    case 0: fibdone();&lt;br /&gt;    case 1: afterfib1();&lt;br /&gt;    case 2: afterfib2();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;/* naive stack implementation */&lt;br /&gt;int stack[STACKSIZE];&lt;br /&gt;int *pstack;&lt;br /&gt;int *pinit;&lt;br /&gt;&lt;br /&gt;void initstack()&lt;br /&gt;{&lt;br /&gt;  pstack=stack;&lt;br /&gt;  pinit=pstack;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void save(int val)&lt;br /&gt;{&lt;br /&gt;  if (pstack &amp;gt; pinit+STACKSIZE){&lt;br /&gt;    perror("Reached Stack End");&lt;br /&gt;    exit(1);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  *pstack=val;&lt;br /&gt;  ++pstack;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int restore()&lt;br /&gt;{&lt;br /&gt;  if (pstack == pinit){&lt;br /&gt;    perror("Reached Stack Head");&lt;br /&gt;    exit(1);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  --pstack;&lt;br /&gt;  return *pstack;&lt;br /&gt;}&lt;/pre&gt;スタックの機能をでっちあげて、Figure5.12にあるSchemeっぽい式をもじどおりCに置き換えただけ。コンパイルして実行すると（想定内のセグメンテーション違反はおこすけど）あっさりうごく。&lt;pre&gt;k16@debian:~/play $ ./fib 24&lt;br /&gt;answer = 46368&lt;br /&gt;k16@debian:~/play $ ./fib 25&lt;br /&gt;セグメンテーション違反です&lt;/pre&gt;&lt;br /&gt;これは、Cでフィボナッチを書きました、という話ではなく、これまでSchemeというレイヤでプログラミングしているときに再帰関数だと思っていたコレが、&lt;pre&gt;(define (fib n)&lt;br /&gt;        (if (&lt; n 2)&lt;br /&gt;            n&lt;br /&gt;            (+ (fib (- n 1)) (fib (- n 2)))))&lt;/pre&gt;その下のレイヤでは上記のCのコードのようなレジスタへの代入とスタックへの出し入れだけの形（現代のコンピュータがかろうじて完璧に扱える形）に解くほぐせて、しかも動く、という話なんだよね。プログラミング言語っていうのは、もしかして、ここで手動で試してみたコードからコードへの変換みたいな処理を自動的に行うしくみのことなのか？&lt;br /&gt;&lt;br /&gt;なんだかこの本を読みはじめたときのようなわくわく感が。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-1832926285736799962?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/1832926285736799962/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=1832926285736799962' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/1832926285736799962'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/1832926285736799962'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2007/06/sicp5-5gauchescheme5.html' title=''/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-8224538958259923099</id><published>2007-05-31T12:50:00.000+09:00</published><updated>2007-05-31T12:55:28.623+09:00</updated><title type='text'></title><content type='html'>地球の裏側までトンネルを掘ってボールを落としたらどうなるかという話題になった。空気がなくて、他の天体の重力の影響を無視できて、トンネルが地球の重心を通る直線で、トンネルの壁が重力によって押しつぶされなくて、なんかほかにもいろいろ条件を満たすなら、ボールは反対側の地表付近まで届く。トンネルの途中でぴたっと止まっちゃうことはない。力学は昔も今もさっぱり自信がないんだけど、その理由を文章で説明するとしたらこんな感じになると思う。&lt;br /&gt;&lt;pre&gt;ボールはトンネルの真ん中まで落ちるあいだ、つねに一定の加速度で移動する。&lt;br /&gt;つまり、どんどん速度が増える。&lt;br /&gt;トンネルの真ん中付近を突っ切るときが最速で、そこから先は正反対の向きの加速度で移動する。&lt;br /&gt;つまり、だんだんゆっくりになる。&lt;br /&gt;そのうち前半の行程で得たエネルギーを使い果たし、反対側の地表付近で一瞬静止して、今度はもときた方向へ落ちていく。&lt;br /&gt;以下繰り返し。&lt;/pre&gt;&lt;br /&gt;で、こういう問題を考えるときは「地球の中心に全質量が集中している」と見たてることになっているわけだけど、その理由を説明するのがむずい。この場合の「見たて」は、たとえば数学で「0.99999… = 1」とか規定するのと違って、そう考えると議論に都合がいいからという性質だけのものじゃなく、もっと本質的な話だったはず（もちろん、どんな理学的な説明だって「そのほうが都合がいいから」って言い方はできるんだろうけど……）。で、昼休みにWikipediaを見てみたら、あっさり証明がのっていた。（読んではいない）&lt;br /&gt;&lt;br /&gt;Shell theorem&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Newton%27s_sphere_theorem"&gt;http://en.wikipedia.org/wiki/Newton%27s_sphere_theorem&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;もしボールがトンネルを移動している最中に球に地球が真っ二つに割れたら？という話も出たけど、それまでにボールが得ている運動エネルギーと変化した周囲の重力から得るエネルギーとが均衡するように動くとしか……（実際には地球を真っ二つに割ることになった外因からのエネルギーがいちばん大きく影響するんじゃない？）&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-8224538958259923099?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/8224538958259923099/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=8224538958259923099' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/8224538958259923099'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/8224538958259923099'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2007/05/0.html' title=''/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-7166015115091738119</id><published>2007-05-28T09:56:00.001+09:00</published><updated>2011-02-10T15:11:04.704+09:00</updated><title type='text'>パズル「グリッド色分け問題」少し改良版</title><content type='html'>「組合せ最適化」をぱらぱらめくったけど安直な方法が見つけられなかったので、オクトーバーフェストに行ってビールをのみながらほげほげ考えていたら、行ごとに組み合わせを求めつつ枝刈りして、それを枝刈りしながら列に集めれば、ずいぶんメモリを省略できるはずだと思いついた。実際これはうまくいって、4x4程度なら瞬時に計算できる。&lt;br /&gt;&lt;br /&gt;たとえば10番目に得られた結果。10番目であることに特に意味はない。&lt;br /&gt;&lt;table&gt;&lt;tr&gt;  &lt;td style="background-color:green"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:orange"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:green"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:orange"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;  &lt;td style="background-color:orange"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:blue"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:orange"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:green"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;  &lt;td style="background-color:blue"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:green"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:blue"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:orange"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;  &lt;td style="background-color:orange"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:blue"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:green"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:blue"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;(use srfi-1)&lt;br /&gt;(use util.stream)&lt;br /&gt;&lt;br /&gt;(define (line-colorings width colors pred)&lt;br /&gt;  (cond ((= 1 width)&lt;br /&gt;         (apply stream (zip (iota colors colors -1))))&lt;br /&gt;        ((= 0 colors)&lt;br /&gt;         stream-null)&lt;br /&gt;        (else&lt;br /&gt;         (let R ((top colors))&lt;br /&gt;           (if (= 0 top)&lt;br /&gt;               stream-null&lt;br /&gt;               (stream-append&lt;br /&gt;                (stream-filter&lt;br /&gt;                 pred&lt;br /&gt;                 (stream-map (cut cons top &lt;&gt;)&lt;br /&gt;                             (line-colorings (- width 1) colors pred)))&lt;br /&gt;                (R (- top 1))))))))&lt;br /&gt;&lt;br /&gt;;; (stream of lists) -&gt; (stream of lists)&lt;br /&gt;(define (grid-colorings hight rows patterns pred)&lt;br /&gt;  (cond ((= 1 hight)&lt;br /&gt;         patterns)&lt;br /&gt;        ((stream-null? patterns)&lt;br /&gt;         stream-null)&lt;br /&gt;        (else&lt;br /&gt;         (let R ((top (stream-car patterns))&lt;br /&gt;                 (rest (stream-cdr patterns)))&lt;br /&gt;           (stream-append&lt;br /&gt;            (stream-filter&lt;br /&gt;             pred&lt;br /&gt;             (stream-map (cut append top &lt;&gt;)&lt;br /&gt;                         (grid-colorings (- hight 1) rows patterns pred)))&lt;br /&gt;            (if (stream-null? rest)&lt;br /&gt;                stream-null&lt;br /&gt;                (R (stream-car rest) (stream-cdr rest))))))))&lt;br /&gt;&lt;br /&gt;(define (tiles lines rows colors)&lt;br /&gt;  (stream-filter &lt;br /&gt;   (cut egalite? &lt;&gt; (quotient (* lines rows) colors) colors)&lt;br /&gt;   (grid-colorings lines rows &lt;br /&gt;     (line-colorings rows colors &lt;br /&gt;       (cut stripe? &lt;&gt;))&lt;br /&gt;     (cut staggered? &lt;&gt; rows))))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;;;;; predicates&lt;br /&gt;; Doesn't the list contain adjacent cells with same color?&lt;br /&gt;(define (stripe? ls)&lt;br /&gt;  (cond ((null? ls)&lt;br /&gt;         #t)&lt;br /&gt;        ((null? (cdr ls))&lt;br /&gt;         #t)&lt;br /&gt;        (else&lt;br /&gt;         (let ((v (car ls))&lt;br /&gt;               (w (cadr ls)))&lt;br /&gt;           (and (not (= v w))&lt;br /&gt;                (stripe? (cdr ls)))))))&lt;br /&gt;&lt;br /&gt;; Doesn't the list contain vertically adjucent cells with same color?&lt;br /&gt;(define (staggered? ls rows)&lt;br /&gt;  (let R ((rows (transpose ls rows)))&lt;br /&gt;    (if (null? rows)&lt;br /&gt;        #t&lt;br /&gt;        (and (stripe? (car rows))&lt;br /&gt;             (R (cdr rows))))))&lt;br /&gt;&lt;br /&gt;; Does each color appear at least n times?&lt;br /&gt;(define (egalite? ls n c)&lt;br /&gt;  (let R ((c c) (ls ls))&lt;br /&gt;    (cond ((= c 0) #t)&lt;br /&gt;          ((&lt; (length ls) n) #f)&lt;br /&gt;          (else&lt;br /&gt;           (receive (the-colors rest)&lt;br /&gt;               (partition (cut = c &lt;&gt;) ls)&lt;br /&gt;             (and (&gt;= (length the-colors) n)&lt;br /&gt;                  (R (- c 1) rest)))))))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;;;;; some list utils&lt;br /&gt;(define (group ls n)&lt;br /&gt;  (receive (front end)&lt;br /&gt;      (split-at ls n)&lt;br /&gt;    (if (null? end)&lt;br /&gt;        (list ls)&lt;br /&gt;        (cons front (group end n)))))&lt;br /&gt;(define (transpose ls rows)&lt;br /&gt;  (apply zip (group ls rows)))&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-7166015115091738119?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/7166015115091738119/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=7166015115091738119' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/7166015115091738119'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/7166015115091738119'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2007/05/4x4-1010-use-srfi-1-use-util.html' title='パズル「グリッド色分け問題」少し改良版'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-4012244893479876564</id><published>2007-05-26T22:19:00.001+09:00</published><updated>2011-02-10T15:09:44.164+09:00</updated><title type='text'>パズル「グリッド色分け問題」をSchemeで解く</title><content type='html'>自宅のトイレにはディック・ブルーナのポスターがもう何年も張ってある。全体がグリッドに仕切られていて、そのひとつひとつに彼の代表作から抜き出した絵が並べられてるんだけど、そのうちの1枚に描かれているテーブルクロスの柄が気になってしょうがない。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/k16/514233835/" title="Photo Sharing"&gt;&lt;img src="http://farm1.static.flickr.com/246/514233835_825b8ad1ba_m.jpg" width="240" height="180" alt="R0011516" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;どうしてこのテーブルクロスは、きちんと格子が塗り分けられていないんだろう。左下で青いマスが横に並んじゃっているのがどうにも気持ち悪い。行列の成分でいうと33と34の2つ。もしスプーンがおかれてなかったら境界が識別できないじゃないか。4x4のグリッドを3色で塗り分けるパターンなんていくらもあるだろうに。&lt;br /&gt;&lt;br /&gt;というわけでパターンを求めてみる。&lt;br /&gt;&lt;br /&gt;戦略は、まず塗り分けのパターンをすべて求めて（つまり隣同士が同じ色に塗られるパターンを含む）、そのうちで3色をちゃんと使ってうまく塗り分けられているものを取り出す。&lt;br /&gt;&lt;br /&gt;「3色をちゃんと使ってうまく塗り分けられている」はどう評価しよう？　&lt;br /&gt;とりあえず、どの色も少なくとも5回（16÷3）は使われていて、隣同士が違う色になっていればよしとしよう。（デザイン上のよしあしを評価するとしたら何を考えたらいい？）&lt;br /&gt;&lt;br /&gt;4x4のグリッドを塗り分けるパターンは、長さ16のリストであらわすことにする。使う色は1,2,3という数値で表す。つまり、リストの各要素には、各マスの色を意味する1,2,3のいずれかの数値がはいる。これをグリッドの左上→右下という順番で並べる。たとえば以下のような塗り分けは、(1 3 2 3 3 2 1 2 1 3 2 1 3 2 1 3) というリストであらわすことにする。（ 1：青、2：オレンジ、3：緑）&lt;br /&gt;&lt;br /&gt;&lt;table&gt;&lt;tr style="border-collapse:collapse border-style:solid"&gt;  &lt;td style="background-color:blue"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:green"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:orange"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:green"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="border-collapse:collapse border-style:solid"&gt;  &lt;td style="background-color:green"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:orange"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:blue"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:orange"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="border-collapse:collapse border-style:solid"&gt;  &lt;td style="background-color:blue"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:green"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:orange"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:blue"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="border-collapse:collapse border-style:solid"&gt;  &lt;td style="background-color:green"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:orange"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:blue"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:green"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;隣同士が別の色で塗り分けられているかどうかは、ベタに縦横の関係を調べる patch? というプロシージャを定義して、それで済ませることにする。&lt;pre&gt;(define (stripe? ls)&lt;br /&gt;  (cond ((null? ls)&lt;br /&gt;         #t)&lt;br /&gt;        ((null? (cdr ls))&lt;br /&gt;         #t)&lt;br /&gt;        (else&lt;br /&gt;         (let ((v (car ls))&lt;br /&gt;               (w (cadr ls)))&lt;br /&gt;           (and (not (= v w))&lt;br /&gt;                (stripe? (cdr ls)))))))&lt;br /&gt;(define (patch? ls n m)&lt;br /&gt;  (and (let L ((lines (group ls n)))&lt;br /&gt;         (if (null? lines)&lt;br /&gt;             #t&lt;br /&gt;             (and (stripe? (car lines))&lt;br /&gt;                  (L (cdr lines)))))&lt;br /&gt;       (let R ((rows (transpose ls n)))&lt;br /&gt;         (if (null? rows)&lt;br /&gt;             #t&lt;br /&gt;             (and (stripe? (car rows))&lt;br /&gt;                  (R (cdr rows)))))))&lt;/pre&gt;ところでgroupとtransposeは、いつも使いたいときに一瞬探すんだけど見つからなくて、そのたびに下手な実装をしてる気がする。今回はこんなんで。&lt;pre&gt;(define (group ls n)&lt;br /&gt;  (receive (front end)&lt;br /&gt;      (split-at ls n)&lt;br /&gt;    (if (null? end)&lt;br /&gt;        (list ls)&lt;br /&gt;        (cons front (group end n)))))&lt;br /&gt;(define (transpose ls rows)&lt;br /&gt;  (apply zip (group ls rows)))&lt;/pre&gt;&lt;br /&gt;塗り分けパターンをすべて求めるにはどうしたらいいか。&lt;br /&gt;&lt;br /&gt;たとえば、3つのマスを3色で塗り分けるやり方をすべて求めることを考えてみよう。以下のようなマスA,B,Cを緑黒赤の3色で塗り分けるパターンをすべて求めたい。&lt;br /&gt;&lt;br /&gt;&lt;table&gt;&lt;tr&gt;&lt;td style="background-color:white; border-style:outset; border-color:black"&gt;&lt;div style="width:1em"&gt; A &lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:white; border-style:outset; border-color:black"&gt;&lt;div style="width:1em"&gt; B &lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:white; border-style:outset; border-color:black"&gt;&lt;div style="width:1em"&gt; C &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;いま、都合よく R という関数があって、これを使うと2マスを3色で塗り分けパターンが全部求められるとしよう。R を使えば、以下の 3つの結果をよせ集めることで、3マスの塗り分けパターンを求めることができる。&lt;ol&gt;&lt;li&gt;Aを緑に塗って、BとCは R に従って塗り分ける全パターン&lt;/li&gt;&lt;li&gt;Aを黒に塗って、BとCは R に従って塗り分ける全パターン&lt;/li&gt;&lt;li&gt;Aを赤に塗って、BとCは R に従って塗り分ける全パターン&lt;/li&gt;&lt;/ol&gt;ようするに、うしろの塗り分け方さえ全部求まってれば、先頭の色だけとっかえひっかえした結果をよせ集めることで、全体の塗り分けがすべて得られる。&lt;br /&gt;&lt;br /&gt;&lt;table&gt;&lt;tr&gt;&lt;td style="background-color:green"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:green"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:green"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="background-color:green"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:green"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:black"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="background-color:green"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:green"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:red"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="background-color:green"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:black"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:green"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="background-color:green"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:black"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:black"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="background-color:green"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:black"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:red"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="background-color:green"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:red"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:green"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="background-color:green"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:red"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:black"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="background-color:green"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:red"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:red"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="background-color:black"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:green"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:green"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="background-color:black"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:green"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:black"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="background-color:black"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:green"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:red"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="background-color:black"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:black"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:green"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="background-color:black"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:black"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:black"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="background-color:black"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:black"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:red"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="background-color:black"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:red"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:green"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="background-color:black"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:red"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:black"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="background-color:black"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:red"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:red"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="background-color:red"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:green"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:green"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="background-color:red"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:green"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:black"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="background-color:red"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:green"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:red"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="background-color:red"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:black"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:green"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="background-color:red"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:black"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:black"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="background-color:red"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:black"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:red"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="background-color:red"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:red"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:green"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="background-color:red"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:red"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:black"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="background-color:red"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:red"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:red"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;このアイデアをストリームを使ってダイレクトにコードにするとこんな感じ。Scheme だと簡単すぎ。&lt;pre&gt;(use srfi-1)&lt;br /&gt;(use util.stream)&lt;br /&gt;&lt;br /&gt;(define (gen-colorings width colors)&lt;br /&gt;  (cond ((= 1 width)&lt;br /&gt;         (apply stream (zip (iota colors colors -1))))&lt;br /&gt;        ((= 0 colors)&lt;br /&gt;         stream-null)&lt;br /&gt;        (else&lt;br /&gt;         (let R ((top colors))&lt;br /&gt;           (if (= 0 top)&lt;br /&gt;               stream-null&lt;br /&gt;               (stream-append&lt;br /&gt;                 (stream-map (cut cons top &amp;lt;&amp;gt;)&lt;br /&gt;                             (gen-colorings (- width 1) colors))&lt;br /&gt;                 (R (- top 1))))))))&lt;/pre&gt;あとは、先に定義した patch? を使ってストリームをフィルタリングすればいい。どの色もだいたい平等に塗られているかどうかを調べるプロシージャ egalite? も定義しておいて、ここであわせてフィルタリングする。&lt;pre&gt;&lt;br /&gt;(define (tiles n m c)&lt;br /&gt;  (stream-filter &lt;br /&gt;   (lambda (tone)&lt;br /&gt;     (and &lt;br /&gt;      (egalite? tone n c) &lt;br /&gt;      (patch? tone n m))&lt;br /&gt;   (gen-colorings (* n m) c)))&lt;br /&gt;&lt;br /&gt;(define (egalite? ls n c)&lt;br /&gt;  (let R ((c c) (ls ls))&lt;br /&gt;    (cond ((= c 0) #t)&lt;br /&gt;          ((&amp;lt; (length ls) n) #f)&lt;br /&gt;          (else&lt;br /&gt;           (receive (the-colors rest)&lt;br /&gt;               (partition (cut = c &amp;lt;&amp;gt;) ls)&lt;br /&gt;             (and (&amp;gt;= (length the-colors) n)&lt;br /&gt;                  (R (- c 1) rest)))))))&lt;/pre&gt;これで (tiles 4 4 3) とかって実行すれば、塗り分けパターンを順次計算してくれるストリームが帰ってくる。はずなんだけど、実際には組み合わせが爆発しちゃう。16マスを3色に塗り分けようと思ったら 3&lt;sup&gt;16&lt;/sup&gt; = 43,046,721 のパターンがありうるわけで、すべての塗り分けパターンからなるリストを作ったりすると巨大なリストになって身動きが取れなくなると思ってストリームを使ってみたんだけど、どのみち4x4=16マスの3色塗り分けを全部求めるのは無理だったもよう。&lt;br /&gt;しかたがないので、問題を1行小さくして 3x4 の横長のテーブルクロスの3色塗り分けを求めてお茶を濁すことにした。&lt;pre&gt;&lt;font color="blue"&gt;gosh&amp;gt;&lt;/font&gt; &lt;b&gt;(define s (tiles 4 3 3))&lt;/b&gt;&lt;br /&gt;s&lt;br /&gt;&lt;font color="blue"&gt;gosh&amp;gt;&lt;/font&gt; &lt;b&gt;(stream-&gt;ref s 1)&lt;/b&gt;&lt;br /&gt;(3 2 1 3 2 1 3 2 1 2 1 3)&lt;br /&gt;&lt;font color="blue"&gt;gosh&amp;gt;&lt;/font&gt; &lt;b&gt;(stream-ref s 2)&lt;/b&gt;&lt;br /&gt;(3 2 1 3 2 1 2 1 3 2 1 3)&lt;br /&gt;&lt;font color="blue"&gt;gosh&amp;gt;&lt;/font&gt; &lt;b&gt;(stream-ref s 3)&lt;/b&gt;&lt;br /&gt;(3 2 1 2 1 3 2 1 3 2 1 3)&lt;br /&gt;&lt;font color="blue"&gt;gosh&amp;gt;&lt;/font&gt; &lt;/pre&gt;最初に得られる結果を先の色定義（ 1：青、2：オレンジ、3：緑）で塗り分けると、こうなる。&lt;br /&gt;&lt;br /&gt;&lt;table&gt;&lt;tr&gt;&lt;td style="background-color:green"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:orange"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:blue"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:green"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="background-color:orange"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:blue"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:green"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:orange"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="background-color:blue"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:orange"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:blue"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;td style="background-color:green"&gt;&lt;div style="width:1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;ついでに、このHTMLテーブルを描くのにでっちあげた補助関数。&lt;pre&gt;(define (tile-&amp;gt;html tile rownum)&lt;br /&gt;  (define (num-&amp;gt;color n)&lt;br /&gt;    (cond&lt;br /&gt;     ((= 1 n) "blue")&lt;br /&gt;     ((= 2 n) "orange")&lt;br /&gt;     ((= 3 n) "green")&lt;br /&gt;     (else    "black")&lt;br /&gt;     ))&lt;br /&gt;  (define (line-&amp;gt;str line)&lt;br /&gt;    (string-append &lt;br /&gt;     "&amp;lt;tr&amp;gt;\n  "&lt;br /&gt;     (apply string-append &lt;br /&gt;       (map (lambda (cell)&lt;br /&gt;              (string-append "&amp;lt;td style=\"background-color:" &lt;br /&gt;            (num-&amp;gt;color cell) &lt;br /&gt;       "\"&amp;gt;&amp;lt;div style=\"width:1em\"&amp;gt;&amp;amp;nbsp;&amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt;"))&lt;br /&gt;                               line))&lt;br /&gt;     "\n&amp;lt;/tr&amp;gt;\n"))&lt;br /&gt;  (define (lines-&amp;gt;str lines)&lt;br /&gt;    (string-append "&amp;lt;table&amp;gt;\n" &lt;br /&gt;                   (apply string-append (map (cut line-&gt;str &amp;lt;&amp;gt;) lines))&lt;br /&gt;                   "&amp;lt;/table&amp;gt;\n"))&lt;br /&gt;  (lines-&gt;str (group tile rownum)))&lt;/pre&gt;しかし、tilesの引数は順番を逆にするべきだったな。行と列がいれかわってて紛らわしいことこのうえない。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-4012244893479876564?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/4012244893479876564/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=4012244893479876564' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/4012244893479876564'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/4012244893479876564'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2007/05/1-333424x43-3-3-5163-4x4161231231-3-2-3.html' title='パズル「グリッド色分け問題」をSchemeで解く'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm1.static.flickr.com/246/514233835_825b8ad1ba_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-4960711500867475824</id><published>2007-05-18T18:40:00.001+09:00</published><updated>2011-02-10T14:59:04.619+09:00</updated><title type='text'>XMLっぽい構造をパースする</title><content type='html'>指定した範囲の内側でだけ、テキストのパターン置換をしたい。つまり、こういうことがしたい。&lt;pre&gt;&lt;font color="blue"&gt;gosh&amp;gt;&lt;/font&gt; &lt;b&gt;str&lt;/b&gt;&lt;br /&gt;&lt;font color="green"&gt;"&amp;lt;title&amp;gt;&lt;br /&gt;  &amp;lt;en&amp;gt;Introduction&amp;lt;/en&amp;gt;&lt;br /&gt;  &amp;lt;ja&amp;gt;は じ め に&amp;lt;/ja&amp;gt;&lt;br /&gt;&amp;lt;/title&amp;gt;&lt;br /&gt;&amp;lt;p&amp;gt;&lt;br /&gt;  &amp;lt;en&amp;gt;&lt;br /&gt;    Here we'll discuss about english&lt;br /&gt;      &amp;lt;footnote&amp;gt;&lt;br /&gt;        &amp;lt;p class="footnote"&amp;gt;&lt;br /&gt;          Or, any language you speak as a native tongue.&lt;br /&gt;        &amp;lt;/p&amp;gt;&lt;br /&gt;      &amp;lt;/footnote&amp;gt;&lt;br /&gt;    .&lt;br /&gt;  &amp;lt;/en&amp;gt;&lt;br /&gt;  &amp;lt;ja&amp;gt;&lt;br /&gt;    ここでは日本語&lt;br /&gt;      &amp;lt;footnote&amp;gt;&lt;br /&gt;        &amp;lt;p class="footnote"&amp;gt;&lt;br /&gt;          で な く て も、母 国 語 な ら な ん で も い い。&lt;br /&gt;        &amp;lt;/p&amp;gt;&lt;br /&gt;      &amp;lt;/footnote&amp;gt;&lt;br /&gt;    について説明しよう。&lt;br /&gt;  &amp;lt;/ja&amp;gt;&lt;br /&gt;&amp;lt;/p&amp;gt;"&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="blue"&gt;gosh&amp;gt;&lt;/font&gt; &lt;b&gt;(regexp-replace-all-among-all 'ja #/\b\s\b/ str "")&lt;/b&gt;&lt;br /&gt;&lt;font color="green"&gt;"&amp;lt;title&amp;gt;&lt;br /&gt;  &amp;lt;en&amp;gt;Introduction&amp;lt;/en&amp;gt;&lt;br /&gt;  &amp;lt;ja&amp;gt;はじめに&amp;lt;/ja&amp;gt;&lt;br /&gt;&amp;lt;/title&amp;gt;&lt;br /&gt;&amp;lt;p&amp;gt;&lt;br /&gt;  &amp;lt;en&amp;gt;&lt;br /&gt;    Here we'll discuss about english&lt;br /&gt;      &amp;lt;footnote&amp;gt;&lt;br /&gt;        &amp;lt;p class="footnote"&amp;gt;&lt;br /&gt;          Or, any language you speak as a native tongue.&lt;br /&gt;        &amp;lt;/p&amp;gt;&lt;br /&gt;      &amp;lt;/footnote&amp;gt;&lt;br /&gt;    .&lt;br /&gt;  &amp;lt;/en&amp;gt;&lt;br /&gt;  &amp;lt;ja&amp;gt;&lt;br /&gt;    ここでは日本語&lt;br /&gt;      &amp;lt;footnote&amp;gt;&lt;br /&gt;        &amp;lt;p class="footnote"&amp;gt;&lt;br /&gt;          でなくても、母国語ならなんでもいい。&lt;br /&gt;        &amp;lt;/p&amp;gt;&lt;br /&gt;      &amp;lt;/footnote&amp;gt;&lt;br /&gt;    について説明しよう。&lt;br /&gt;  &amp;lt;/ja&amp;gt;&lt;br /&gt;&amp;lt;/p&amp;gt;"&lt;/font&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://k16journal.blogspot.com/2007/03/gosh-str-is-paragraph.html"&gt;先日&lt;/a&gt;のような邪道な試行錯誤をしたり、再帰下降パーザについて少し勉強したりした結果、地道にパーズするのがいちばんだということがよく分かった。PerlやJaveなら優れたXML処理のライブラリを使うべきなのかもしれないね。&lt;br /&gt;&lt;br /&gt;置換をほどこしたい領域（上の例では&amp;lt;ja&amp;gt;...&amp;lt;/ja&amp;gt;の部分）を取り出すことから考えよう。その前に、XMLっぽいテキストを構成するパーツを先頭から順番に取り出してくれるプロシージャ read-xml があると仮定する。read-xml を一回呼ぶと、「&amp;lt;title&amp;gt;」や「&amp;lt;p class="footnote"&amp;gt;」のようなタグ、もしくは、タグの前後の本文を、テキストの先頭から順番にゲットできる。こんな感じ。&lt;pre&gt;(with-input-from-string "aaa&amp;lt;p&amp;gt;bbb&amp;lt;/p&amp;gt;ccc"&lt;br /&gt;  (lambda ()&lt;br /&gt;    (read-xml) ; ⇒ aaa&lt;br /&gt;    (read-xml) ; ⇒ &amp;lt;p&amp;gt;&lt;br /&gt;    (read-xml) ; ⇒ bbb&lt;br /&gt;    (read-xml) ; ⇒ &amp;lt;/p&amp;gt;&lt;br /&gt;    (read-xml) ; ⇒ ccc&lt;br /&gt;  ))&lt;/pre&gt;&lt;br /&gt;この read-xml でひとつずつパーツを取り出してチェックしていく。探している領域を開始するタグ（いまの例では&amp;lt;ja&amp;gt;）が取り出せたら、終了を表すタグ（いまの例では&amp;lt;/ja&amp;gt;）が現れるまで次々にパーツをつないでいくことで、ほしい領域が取り出せる。領域がネストしている可能性もあるので、開始タグの数もチェックしておくようにする。ざっくり書くとこんな感じ。利便性を考えて、領域の前後の文字列も返すようにした。&lt;pre&gt;(define (xml-maximal-region tagname)&lt;br /&gt;  (define (xmltag? e)&lt;br /&gt;    (and (&amp;gt; (string-length e) 1)&lt;br /&gt;         (char=? #\&amp;lt; (string-ref e 0))))&lt;br /&gt;  (define (tag-&amp;gt;name e)&lt;br /&gt;      (string-trim-right&lt;br /&gt;       (x-&amp;gt;string (string-drop e 1))&lt;br /&gt;       #\&amp;gt;))&lt;br /&gt;  (define (start-tag? e)&lt;br /&gt;    (and (xmltag? e)&lt;br /&gt;         (equal? (x-&amp;gt;string tagname)&lt;br /&gt;                 (tag-&amp;gt;name e))))&lt;br /&gt;  (define (end-tag? e)&lt;br /&gt;    (and (xmltag? e)&lt;br /&gt;         (equal? (x-&amp;gt;string tagname)&lt;br /&gt;                 (string-drop (tag-&amp;gt;name e) 1))))&lt;br /&gt;  (define (rest-xml)&lt;br /&gt;    (let R ((next (read-xml)))&lt;br /&gt;      (if (string-null? next)&lt;br /&gt;          ""&lt;br /&gt;          (string-append next (R (read-xml))))))&lt;br /&gt;  (define (in-region e body c before)&lt;br /&gt;    (cond ((string-null? e)&lt;br /&gt;           (error "Premature end of input -- GET-XMLTAGGED-MAXIMAL-REGION"))&lt;br /&gt;          ((end-tag? e)&lt;br /&gt;           (if (= 0 c)&lt;br /&gt;               (values before (string-append body e) (rest-xml))&lt;br /&gt;               (in-region (read-xml) (string-append body e) (- c 1) before)))&lt;br /&gt;          ((start-tag? e)&lt;br /&gt;           (in-region (read-xml) (string-append body e) (+ c 1) before))&lt;br /&gt;          (else&lt;br /&gt;           (in-region (read-xml) (string-append body e) c before))))&lt;br /&gt;  (define (out-region e body before)&lt;br /&gt;    (cond ((string-null? e)&lt;br /&gt;           (values before "" ""))&lt;br /&gt;          ((start-tag? e)&lt;br /&gt;           (in-region (read-xml) e 0 before))&lt;br /&gt;          (else&lt;br /&gt;           (out-region (read-xml) body (string-append before e)))))&lt;br /&gt;  (out-region (read-xml) "" ""))&lt;/pre&gt;&lt;br /&gt;この xml-maximal-region を使えば、求めるプロシージャ regexp-replace-all-among-all が簡単に定義できる。&lt;pre&gt;(define (regexp-replace-all-among-all region-declaration rx str sub)&lt;br /&gt;  (with-input-from-string str&lt;br /&gt;    (lambda ()&lt;br /&gt;      (receive (before region after)&lt;br /&gt;           (xml-maximal-region region-declaration)&lt;br /&gt;        (string-append before&lt;br /&gt;                       (regexp-replace-all rx region sub)&lt;br /&gt;                       (if (string-null? after)&lt;br /&gt;                           after&lt;br /&gt;                           (regexp-replace-all-among-all region-declaration rx after sub)))))))&lt;/pre&gt;あとは read-xml を書けばいい。むずかしいところはないけど面倒。長いので、全体とあわせて下記を参照。&lt;br /&gt;&lt;br /&gt;&lt;a href="https://github.com/k16shikano/xml-modoki"&gt;replace-among.scm&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;References&lt;/i&gt;&lt;br /&gt;&lt;hr/&gt;「なんでも再帰」Shiro Kawai（2003/1）&lt;br /&gt;&lt;a href="http://www.shiro.dreamhost.com/scheme/docs/tailcall-j.html"&gt;http://www.shiro.dreamhost.com/scheme/docs/tailcall-j.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;『Perl &amp;amp; XML』：Erik T. Ray,Jason McIntosh（2002/11）&lt;br /&gt;&lt;a href="http://www.amazon.co.jp/dp/4873111064"&gt;http://www.amazon.co.jp/dp/4873111064&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-4960711500867475824?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/4960711500867475824/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=4960711500867475824' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/4960711500867475824'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/4960711500867475824'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2007/05/gosh-str-here-well-discuss-about.html' title='XMLっぽい構造をパースする'/><author><name>keiichirou shikano</name><uri>https://profiles.google.com/101368821540656246763</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-60rNKCknP8M/AAAAAAAAAAI/AAAAAAAAAII/yddIiqGIGLg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9197115.post-6707024613288509979</id><published>2007-04-30T17:51:00.000+09:00</published><updated>2007-04-30T18:25:04.725+09:00</updated><title type='text'></title><content type='html'>二分木が描きたい。&lt;br /&gt;&lt;br /&gt;Scheme を使っていると木を使うことが多い（Scheme に限らないけど）。教科書なんかには整形された木の絵がよく出てくるけど。あれはみんなどうやって描いているんだろう。きっと PostScript のコマンドを生成したりして描いているに違いない。そこで、再帰下降パーザの例としてありがちな四則演算を表す木を描くのに挑戦してみた。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://hw001.gate01.com/sikano/src/arithmetic-culc-tree.scm"&gt;arithmetic-culc-tree.scm&lt;/a&gt;&lt;br /&gt;&lt;pre&gt;$ &lt;b&gt;gosh arithmetic-culc-tree -tree ps&lt;/b&gt;&lt;br /&gt;&lt;b&gt;1*2+3*((4+5)-7)/(8+9)&lt;/b&gt;&lt;br /&gt;%!&lt;br /&gt;&lt;&lt; /PageSize [460.0 350.0] &gt;&gt; setpagedevice&lt;br /&gt;newpath&lt;br /&gt;175.0 297.0 moveto&lt;br /&gt;85.0 270.0 lineto&lt;br /&gt;175.0 297.0 moveto&lt;br /&gt;265.0 270.0 lineto&lt;br /&gt;...&lt;i&gt;(以下略)&lt;/i&gt;&lt;/pre&gt;&lt;br /&gt;convert で png に変換した結果。&lt;br /&gt;&lt;img src="http://hw001.gate01.com/sikano/src/complex-tree.png"/&gt;&lt;br /&gt;もうちょっと見ための改善の余地がありそうだけどもうつかれた。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9197115-6707024613288509979?l=note.golden-lucky.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://note.golden-lucky.net/feeds/6707024613288509979/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9197115&amp;postID=6707024613288509979' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/6707024613288509979'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9197115/posts/default/6707024613288509979'/><link rel='alternate' type='text/html' href='http://note.golden-lucky.net/2007/04/sch
