Archive for 7月, 2008

Common Lispと改行コード

水曜日, 7月 30th, 2008

CLでread-lineを使ってファイルを読み込んでいるとき気づいたのですが、
read-lineは

改行によって終了された行を読む。
これは行を文字列として返す。
(改行文字を含まない。)
(CLtL2日本語版第2版より)

という風に説明があったのですが、
#\Linefeed(LF)は読み飛ばしてくれるものの、
#\Return(CR)が思いっきり残っていました。
ストリーム開くときに:external-formatみたいな感じで、
改行コードも指定できたりしないんですかね。
読み込むときは改行コードの判定処理をする必要があるのであれば、
結局自力でなんとかしないといけないとは思いますが、
書き込むときは~%一発で済ませたいものです。


そうそう、リトルバスターズ エクスタシーですが、
プログラミングをしたいという欲求に負けてしまい、
現在、朱鷺戸さんに殺されかけるところまでしかやってません。
それにしても、朱鷺戸さんのBGMがKeyの過去のアルバムにあった
「駆ける」だったのが一番驚きました。

実践Common Lisp買うついでにTOEIC受けてきた

日曜日, 7月 27th, 2008


ジュンク堂に行く道の途中に試験会場があったから、
ついでにTOEICを受けてきただけなんだからね。
英語の先生に「TOEIC受けないと単位はやらん」
といわれてしかたなく受けたわけじゃないんだからね。
か、勘違いしないでよ!

なんかさ、試験官がいろんな注意事項といっしょに、
「健康を第一に考え、空調はつけたままにします。」
とか言ってたの。健康を第一にってなんだよ。
本当に健康を考えるなら設定温度をもう少し上げて、
外との気温差を少なくする方がいいじゃないのかとか思ったんだけど、
まあ涼しかったしいいか。

そんな訳で、「実践Common Lisp」買いました。
まだ、本当に最初の方しか読んでいないのですが、謝辞が少し面白かったです。
この手の本の謝辞には大抵の場合、
「KnuthがTeXを作ってくれたことに感謝する」
みたいに、TeXに関することが書いてあったりするんですけど、
実践Common Lispだと、

もう1つ、執筆中に欠かせなかったリソースとして、
Marc Battyaniが書いてくれたPDF生成と組版のためのCommon Lispライブラリである
CL-PDFとCL-TYPESETTINGがある。
CL-TYPESETTINGで自分用の赤書きに使うPDFを整形し、
CL-PDFで本の中に出てくる図のベースを生成した。
(ページvii 謝辞)

とか書いてるんですよ。
そこにまでCommon Lispを使うのかと少し笑ってしまいました。
なんでもCLで仕事をする人がいるという都市伝説を聞いたことがあるけど、
あの都市伝説は本当だったのか…

しかし、不幸なことに今は試験期間中なんですよね。
実践Common Lispを読むのは後回しになりそうです。
ただでさえ、プログラミングやらTOEICやらに時間を費やしたのですから、
そろそろ勉強をしないとさすがにヤバいぞと思ってきたんですよ。
でも、目の前に開発環境があると、ついプログラミングを続けてしまうと。
それで、FreeBSDを終了して代わりにWindowsを起動したんですよ。
「ふはは、これでプログラミングはできまい」
と安心してたら、金曜に買ったリトルバスターズ エクスタシーのパッケージが目に入ってしまいました。
そして私は、パッケージの中に入っている、
ディスクに手を伸ばしてしまったのです…
(終わり。主に試験が。)

with-output-to-stringと文字コード

日曜日, 7月 27th, 2008

Common LispでWebアプリのお話。
POSTで日本語(UTF-8)を含んだ文字列を送信すると、文字化けしてしまったので、
原因を調べてみると、URLデコードを行っている関数が犯人のようでした。

(defun url-decode-string (s)
(with-output-to-string (out)
(do ((i 0 (1+ i)))
((>= i (length s)) out)
(let ((c (char s i)))
(case c
(#\% (setf c (code-char (parse-integer s
:start (+ i 1) :end (+ i 3)
:radix 16 :junk-allowed t)))
(unless (null c) (write-char c out))
(incf i 2))
(#\+ (write-char #\Space out))
(otherwise (write-char c out)))))))

outの文字コードがしていされていないのが原因だと思うんですけど、
with-output-to-stringでは:external-formatキーワードは指定できないようです。
ストリームを開いた後に文字コードをしている方法はないかと調べてみたら、
system::set-stream-external-formatなる関数があったのですが、
string-streamには使用できないみたいです。
色々苦心してみましたが結局解決策が見つからず、
一旦バイト列に入れてから文字列に変換することにしました。

;;; CLISP only
(defun url-decode-string2 (s)
(let ((arr (make-array (length s) :element-type '(mod 256))))
(do ((i 0 (1+ i))
(j 0 (1+ j)))
((>= i (length s))
(ext:convert-string-from-bytes arr charset:utf-8 :end j))
(let ((c (char s i)))
(case c
(#\% (setf c (parse-integer s
:start (+ i 1) :end (+ i 3)
:radix 16 :junk-allowed t))
(unless (null c) (setf (aref arr j) c))
(incf i 2))
(#\+ (setf (aref arr j) (char-code #\Space)))
(otherwise (setf (aref arr j) (char-code c))))))))

ext:convert-string-from-bytesという関数がバイト列を文字列に変換してくれます。
バイト列に文字コードを指定して文字列を直す関数があるのは非常に便利ですね。
残念ながらCL標準ではないようですが、大抵の処理系にはこの手の関数があるようです。

祖父地図

土曜日, 7月 26th, 2008


今日(いつのまにか正確には昨日になってしまった)は
「リトルバスターズ エクスタシー」
の発売日でしたね。
そんなわけでもちろん全力で買いにいきました。
去年、リトルバスターズが発売された時もちょうど試験期間中で、
店が開く時間と、試験時間が重なっていたため、
頑張って問題をといて途中退出をして全力で店に向かったものの、
すでに長い長い列が出来上がってました(開店20分後について確か2時間待ち)。
今回は、幸いにも試験時間と店が開く時間が重なっていなかったため、
開店10分前にお店に行ったんですよ。
そしたらすでに店は開いてて、店内に結構長い列。
およそ25分待ちでした。暇な学生は多いですね…
で、本当はすぐにインストールして遊びたかったんですが、
試験期間中なのでぐっとこらえて、
プログラミングに勤しむことにしました。

以前言ったとおり、今はCL-WIkiを改造して変なものを作っているんですが、
なんかいじりすぎて、もはや元のコードがほとんど残ってない状態になってきました。
多分、似たような機能も書き直したりしてるし、かなり無駄なことをしている気もしますが、
まあ、楽しいからいいということにしておきます。
それで、 [Wiki記法-> HTML] なコードを書いてて思ったんですが、
リスト (HTMLのです。ulタグとかolタグ)が入れ子になっていて、
その深さが 1段->3段 といった風にとんだ場合どうするか結構迷います。
pukiwikiの動作を見てみたら、スタイルだけはうまくごまかして、
実際のHTMLの構造は 1段->2段 のようになっているみたいです。
なんだかその動作もどうかと思い、
内容のない2段目を作ってみたんですがどうにもかっこ悪い…

  • hoge
      • foo
  • bar

まあ、そもそも段数が飛ぶようなものを書くのがあまりいいこととは思えませんし、
放置しといていいですよね。きっと。

試験とプログラミングは2つで1つなの

水曜日, 7月 23rd, 2008

*思えば中学1年の2学期の中間試験からだった*
プログラミングが妙にはかどるな、と思ったら試験間近なんですよ。
むしろ試験間近だからはかどるのかもしれません。

ひょとして今って試験直前?
以下の項目が3つ以上当てはまれば試験直前です。
1. プログラミングが妙に楽しい
2. プログラミングが妙にはかどる
3. 今作っているモノの今後の見通しがたっている
4. 勉強の今後の見通しはたっていない

試験がいつあるのか分からなくなってしまった方は、
ぜひ上のチェック表をご利用ください。
CLでWebアプリな話
現在、Lispサーバは、
1)ソケット作る
2)accept
3)処理
4)2に戻る
というごくごくシンプルなコードになっているんですが、
ご覧のとおり、同時に1リクエストしか処理できません。
やっぱし並列化すべきですかね。
CLでマルチスレッドってmpライブラリとかいうのを使えばよかったんだっけ…
あと、並列化すると、ファイルの排他制御とかが必要になりますが、
CLってそこらへんの機能を備えてるんでしょうか。
それにしても、セッション管理とか作って、せっかく楽しくなってきたのに、試験ですよ。
ほんと、プログラミングが楽しくなるといつも試験が目の前に。
一体どうなってるんでしょうか。
*ブログの過去のエントリーをあさって見た*

そろそろ、スクリーンショットや体験版を出したいんですが、もう少し時間がかかりそうです。
インタプリタ周りを触ってたらシナリオの方が全く進んでなかったりします。
試験前ですが、勉強も全く進んでません。
(2007/01/29 魔法の呪文はリリカルなの?)
全くもって使い道のないものをつくってしまいましたが、
大学の試験が近づいていることから逃避することによって発生するエネルギーを、
プログラミングによって発散した結果、生まれてしまったかわいそうなプログラムなので、
どうか生暖かい目で見守ってください。
(2008/01/25 PostScriptの上のLispの上のPostScript)
       ____
     /      \
   /  _ノ  ヽ、_  \
  /  o゚⌒   ⌒゚o  \  もう試験間近だお…
  |     (__人__)    |  きっと単位沢山落とすお…
  \     ` ⌒´     /
(2008/01/27 やる夫がgauche.nightの第1部座談会に出演するそうです)
       ____
     /⌒  ⌒\     これは神のお告げに違いないお!
   /( ●)  (●)\    試験なんか捨てて、新たにLispインタプリタを
  /::::::⌒(__人__)⌒::::: \   作れという神の意思なんだお!
  |     |r┬-|     |  
  \      `ー’´     /   
(2008/02/01 やる夫が変な夢をみたそうです)
ニコニコ動画のスクリプト『ニコスクリプト』の話。
試験期間中というのもあって(*)、こういうものを作ってみました。
(*)試験期間中は逃避エネルギーによってプログラミングの効率は普段の三倍まで上昇する
(2008/02/01ニコニコ動画で三目並べ)
明日でようやく試験も終わりです。
なので、こんなものを作りました。
(2008/02/05 ニコニコ動画でシューティング)

・・・やっぱし試験前はプログラミングの神様が私の元に降りてきて、
「試験はいいから。プログラミングをやりなさい」
と囁いているようにしか思えません。

サーバサイドでCommon Lispを使いたい!

日曜日, 7月 20th, 2008

今日は風子の誕生日ですね。
風子、誕生日おめでとー。
まあ、それは置いといて、
サーバサイドでCommon Lispを使いたい!
*サーバでCLの処理系を動かす*
まず、どうやってCLの処理系を動かすか、少し考えてみました。
1. CGIとしてCLを走らせる (恐ろしく遅い予感)
2. 何か専用のモジュールとか使う
3. 頑張って何とかする
で、調べてみたら、mod_lispというものがあるそうです。
FreeBSDならportsから簡単に入れることが出来ます。
これは、Apacheにきたリクエストを「Lispサーバ」に渡し、Lispサーバからのレスポンスを
元のレスポンスとして返すものです。Reverse Proxyのようなもの?
この「Lispサーバ」は、mod_lisp専用のプロトコルを話すCLのプログラムです。
これは、Apacheと同一マシンで動かしても異なるマシンで動かしてもいいようです。
ここで、少し疑問。
mod_lispという名前の割には全然Lispが関係ない気がします。
なんというかLisp『でも』使えると言った感じが…

*CLで書かれたWebアプリケーション*
CLで書かれた便利なものはないかと探してみたら、
CL-Wikiと、CLikiというものを発見。
CLikiは色々出来る半面、導入が面倒な(気がした)ため、CL-Wikiを使ってみました。
これは、Wikiだけではなく、HTTPサーバの役割も果たすようです。
上記サイトからCL-Wikiのソースをダウンロードし展開し、CLISP上で
> (load “start.lisp”)
とすると、ポート8080にCL-Wikiのサーバが立ち上がりました。
試しにブラウザから127.0.0.1:8080にアクセスすると無事表示されました。
次に、Apacheと共存させるために、mod_lispを入れた後に、http.confに次のような内容を追加。

#lisp
LoadModule lisp_module /usr/local/libexec/apache22/mod_lisp2.so
LispServer  127.0.0.1 8080 "cl-wiki"
<Location /lisp>
SetHandler lisp-handler
</Location>

これで、127.0.0.1/lisp/にアクセスがあると、リクエストがCL-Wikiに飛ばされますが、
このままでは動作しません
最初に書いたとおり、mod_lispは独自のプロトコルを使うため、
CL-Wikiの話す言葉をHTTPからmod_lispのものに書き換える必要があります。
とりあえず、必要そうなところを適当に書き換えたところ、
部分的ではありますが、無事CL-Wikiが動作しました。
ところで、勝手にソース書き換え単ですが、CL-Wikiのライセンスってどうなってるんでしょうか。
調べてもどこにもライセンスが書いてない気が…

*誰かエロい人教えて*
ちょこっと遊ぶ分にはうまく動いたようですが、
実際に外部に公開する場合、このやり方で大丈夫なんでしょうか。
CLを使ったWebサービスってどうなってるんだろう…
(AllegroCLのあれこれを使うっていうのは無しで(^^))
(追記)
CL-Wikiの作者のonjoさんにCL-Wikiを自由にあれこれする許可を頂きました。
ありがとうございます。

OSC行ってきた2。

日曜日, 7月 20th, 2008

懇親会で沢山ビール飲めて満足した。

OSC行ってきた。

金曜日, 7月 18th, 2008

OSCに行ってきた。
K*BUGさんのブースで初音ミクが動いてた。
楽しかった。

BSDで制御してるらしいです。
あと、なでしこの中の人とお話した。
なでしこは日本語の識別子を許すけど、
「から」や「へ」がキーワードとなっているので、
『おから』のような識別子が使えないそうだ。
おからに関するプログラムを書く機会がどれほどあるかは分からないが、
個人的には非常に悲しくなった。おからは美味しいのに…

情報工学ってなんだろう…

金曜日, 7月 18th, 2008

計算量に関して – 矢沢久雄の情報工学“再”入門を祝すCommentsAdd Star経由で、
矢沢久雄の情報工学“再”入門という記事を知ったのですが、
指摘されている通り、確かに内容が激しく怪しいです。
以前、「日経ソフトウエア」という雑誌を読んでいると、
この矢沢さんが書いてある記事があったんですよ。

**
設問 ヘビ
ある世界には、文字だけで出来た不思議なヘビが住んでいます。
このヘビはA種とB種の2種類が確認されていますが、
それ以外の種類がいる可能性もあります。
A種は “>’”の後に1個以上の”=”が並んだ後、”#”が着て、
さらに前と同じ個数の”=”が続き、”~”(半角チルダ)で終わります。
B種は”>^”の後に”Q=”が1個以上並んだ後、”~~”(半角チルダ2個)で終わります。

A種の例:>'===#===~      >'==#==~
B種の例:^Q=Q=Q=Q=~~  >^Q=Q=~~

ヘビを文字列データとして受け取り、
それがどんな種類かを判別して、A種の場合はA、
B種の場合B、A種でもB種でもない場合はNAを出力して
出力するプログラムを作成してください。
(略)
**
(略)
そして、三つ目の方法は、状態遷移図を描いて、
文字列の末尾で終了状態になればパターンが一致したと判定するものです。
これが正攻法かもしれませんが、かなり面倒でしょう。
「オートマトン」という言葉を聞いたことがあるかもしれません。
与えられた入力に対して、内部の状態が遷移(状態を表す変数の値が変化)する
架空のマシンです。
最後の1文字を入力したときに終了状態になることを「入力を受理した」といいます。
つまり判定OKというわけです。
状態遷移図を描く方法はオートマトンの考え方をもとにしています。
(略)
(日経ソフトウエア 2007年 7月号より)

なんだかおかしくないでしょうか。
A種のヘビは = の数をかぞえる必要があるため、鳩の巣原理より、
有限オートマトンで記述できず、状態遷移図も書けないのでは無い気がします。
(プッシュダウンオートマトンなら記述できますが、
それを単に「状態遷移図」と呼んでいいものなのか。)
そう思って編集部に質問のメールを投げてみたんですよ。
そして、返ってきた返事がこれです。

筆者の矢沢久雄さんにも確認したところ,
ご指摘の通りです。
オートマトンは数を数えられないので,
オートマトンを使うことで,ヘビAの「#」記号の左右にくる
「=」記号の並び数をバランスさせることはできません。
本文で言及している「状態遷移図」も,もちろん有限オートマトンと
して描くことはできません。
筆者としては,考え方がオートマトンに類似しているという
ニュアンスのつもりだったようです。ただ,「…の考え方を基
に」という言い方は,確かに紛らわしかったように思います。

……ニュアンス(´・ω・`)
もう一度読み直してみたら、こんなことが書いてました。

タイトルは「ヘビ」ですが、一般には「正規表現」と呼ばれる
分野に属する問題です。

あの・・・正規表現って思いっきり有限オートマトンと同じもの・・・
Perlの正規表現とかだったらマッチした回数とか取得できるんでしょうか。
そんなことを思い出しました。

CLでプログラム書いた

月曜日, 7月 14th, 2008

最近少しずつですがCLの勉強を続けていますが、
本やらを読むだけで一向にプログラムを書いていなかったんですが、
突如CLのプログラムを「書かなければならない」という珍しい状況におかれ、
ようやくCLでそこそこの規模のプログラムを書きました。
*覚えたこと*

(with-open-file
...
:external-format charset:euc-jp)

このように書けば文字コードを指定してファイルを開くことが出来ます。
このサイトなんかが参考になりました。
*勉強の効果(?)*
今まで、なるべく代入を使わないようにして、
再帰を沢山使ってプログラムを書いていたんですが、
今回はsetq, do, do*, dolistを多用しました。
無駄にかっこつけてもしかたないですしね(Lispなのに…)。
doマクロのなかでいくつか変数つくってsetqで代入とかやってたら、
なんだかCのプログラム書いてるのと似たような気分になりました。
そんなプログラム書いてたら、
時折出てくるmapcarが凄くいいものに見えてきました。
やっぱり簡潔に書けるっていい。
しかし、残念だったのが勉強した手のloopマクロを一切使わなかったことです。
やりたいことはdoやdolistで十分できましたし、
そもそもloopマクロで知ってる機能が少なすぎるのかもしれません。
……というか、単にループと代入を沢山使ったプログラムを、
勉強の効果と呼んでいいのやら(笑)
*マクロが便利だけど疲れる*
40行程度のマクロを作ったら、物凄く疲れました。
もっと細かく分割した方がいいのでしょうかね。
まあ、疲れた分、あとでずいぶん楽できたのでよかったです。


*どうでもよくないこと:*
前のエントリーで「ひだまりスケッチ365」とか出力してしまいましたが、
正確なタイトルは「ひだまりスケッチ×365」でした。
正直,スマンかった(AA略