[トップ][一覧][最近の更新]

archives/2005/09

Dylan/open-dylan-1.0beta1

gwydion dylanからOpen Dylan 1.0beta1が出てる。

いまのところバイナリ配布のみのようだ。

Dylanはicfp05でも頑張ってる(でもやっぱりHaskellっょぃ)。

私自身もDylanを使ったコードは書いたことないのだけど、 ずっと前からOpenBSDでは2nd bootできない。多分トランポリン周りだろうな。

  • と思ったらboehm-gcのあたりで死んでるな。なんだろ。

Security/toyocrypt

Category of Security

とうとう解読まで到達。

以前の話のタネになったのが今年の2月。SHA-1が破られた、とかいってたころ。

流れが速過ぎる。

そういえば最近mp3エンコしてないな。aoTuVばっかり。

Scheme/Gauche/Gauche-lazy-ffi

Category of Scheme

gauche.uvectorをサポートした。 <c-pointer>からs8vectorへ変換したり、その逆をしたりすることができるようになった。

ということで、Scheme/Gauche/2005/09/25/Gauche-lazy-ffiの、

  • ヒープをダンプする手続きを書くこと(名前はpointer-to-vectorかなあ)

は解決。きっちりテストしてないけど大丈夫でしょう。多分。

追加事項

  • Cの関数に文字列以外に<c-pointer>も指定できるようにしたので、 コールバック形式の関数も使用できるようになった。 calleeはCで書かれていないと駄目なのは仕方がない(どうやってGaucheで書かれた手続きをコールバック関数のアドレスとして渡せばいいんだい?)。
    • Gaucheのevalをffiに渡せばいいのか、 ってそういう問題じゃなくて、Cの呼出し形式をGaucheで生成できないのが原因。 なんとかうまくやれないかな。
  • サンプルとしてlibcurlを使って curlのサンプル をGauche-lazy-ffiで書き直したコードを付けた。ま、楽勝でしょ。

OpenBSD/Note:emacs-brokenness

Category of OpenBSD

追記: archives/2005/09/27

どうやら直ったようだ。

これかな?

Memo/captcha

巷ではcaptchaと呼んでいるらしい(Wikipedia:Captcha, Google:captcha)。

completely automated public Turing test to tell computers and humans apartの略なんだって。 こんなところでチューリングテストの話題が。へー。

OpenBSD-cvs:ports/graphics/p5-GDとAPIが違うみたいなのでいじってみた。 このバージョンだとアルファブレンドできないっぽいな。

--- captcha.pl.orig     Sun Sep 25 09:36:47 2005
+++ captcha.pl  Sun Sep 25 09:48:12 2005
@@ -23,8 +23,9 @@
     my $im = new GD::Image($width, $height);

     # 背景色と文字色
-    my $bg = $im->colorAllocateAlpha(255, 255, 255, 127);
+    my $bg = $im->colorAllocate(255,255,255);
     my $fg = $im->colorAllocate(0, 0, 0);
+    $im->transparent($bg);

     # TrueType fontで文字を描画
     my @bounds = $im->stringFT($fg, $font, 9, 0, 0, 14, $string);
@@ -37,11 +38,11 @@

     # 出力用画像を別に作り、元画像から文字の部分のみをコピー
     my $outim = new GD::Image($owidth + 2, $oheight + 2);
-    $outim->colorAllocateAlpha(255, 255, 255, 127);
+    $outim->colorAllocate(255, 255, 255);
     $outim->copy($im, 1, 1, $srcx, $srcy,  $owidth, $oheight);

     # 画像をファイルへ出力
-    my $png_data = $outim->png(9);
+    my $png_data = $outim->png;
     open (OUT, ">$png_file") or die;
     binmode OUT;
     print OUT $png_data;

sf:jocrの腕試し。 昔MSが配っていたcour.ttf(今はsf:corefontsとして再配布中)で試してみた。

$ ls test?.png | xargs -L 1 gocr -m 124 -C ".0123456789@abcdefghijklmnopqrstuvwxyz"
t l___d i nt _ __ n_t
__tc_0n0_.dcyt . 0c_0
intec_estin0_.dsit.c0m
rle6__e_.dm0c_e .inf0
tc_0utle_.di__ .my.ti_

さすがに字が小さ過ぎてダメ。 14pointにすると、

$ ls test?.png | xargs -L 1 gocr -m 124 -C ".0123456789@abcdefghijklmnopqrstuvwxyz"
...

お、全部認識した。

しかし、絵で認証すると著しくアクセシビリティが落ちそうだ。 本家captcha版なんてもっとクネクネしてるし、 画像自体もdpi固定なので、閲覧者にページの見栄えを強制することになりそう。 最低でも音声サポートと人力ヘルプセンターは必須か。

あ、画像関連はSVGで、という手もありか。

人間が認識できて、機械に認識できないことがある、 という仮定がそもそも微妙な気がする。

参考:

Scheme/Gauche/Gauche-lazy-ffi

Category of Scheme

とりあえず自前でポインタ型を作った: files:Gauche-lazy-ffi-20050925.tar.gz

使い方はScheme/Gauche/Gauche-lazy-ffi参照。

ポインタを扱う手続きのアイデアはCLiki:UFFIから頂いてきた。

このことで、Scheme/Gauche/2005/09/21/Gauche-lazy-ffiのときの問題、

  • 破壊的代入ができない(gethostname(3)みたいなのはアウト)
  • void*が表現できない

の両方が解決。

ここまででほとんど用は足りるのだけど、少し欲が出てきたので、以下TODO。

  • ヒープをダンプする手続きを書くこと(名前はpointer-to-vectorかなあ)
  • 構造体をパックする手続きを書くこと(今でも要素をベタ書きすれば動くと思うけど面倒)

Scheme/Gauche/Gauche-lazy-ffi

Category of Scheme

もうちょっといじってみた: files:Gauche-lazy-ffi-20050922.tar.gz

  • テストスクリプトをOS非依存にした。
  • chicken版にもうちょっと近付いた。

せっかくだからページを作ろう。Scheme/Gauche/Gauche-lazy-ffi

Scheme/Gauche/Gauche-lazy-ffi

Category of Scheme

なんちゃってffiのつくりかけ: files:Gauche-lazy-ffi-20050921.tar.gz

libffi

eggs:lazy-ffiみたいなのを目指したのだけど似ても似つかないものに。

  • 破壊的代入ができない(gethostname(3)みたいなのはアウト)
  • void*が表現できない

なところが偽物。

(define libm (lazy-ffi:open "libm.so.2.0"))
(lazy-ffi:function libm "sin" lazy:double 1.0)
=>0.8414709848078965

単にScmObjをlibffiに渡しているだけなので、 偽物から脱却するには、 自前のヒープとそれをやりとりするためのインターフェースを作成しないと駄目か。

Scheme/jail

Category of Scheme

Gaucheでファイル入出力だけを禁止する方法。めもめも。

Chickenだとeggs:sandboxなんてものあるのな。

てか変なコードの実行が心配だったら、それだけじゃなくて、 OSの保護機構を使うとか仮想化するとか新しいテスト専用マシンを作るとか、 これらを同時に使って対策するとかしたほうがいいような。

ソフトウェアでなんとかするにしても、chroot(8)なりjail(8)なりqemuなりknoppixなり、 これって結局面倒臭さと安全性の度合とのトレードオフなのだけど、いろいろあるよね。

Scheme/quack-pretty-lambda-p

Category of Scheme

そういえばquack。 手元のものは古かったので、 ダウンロードしてChangeLog読んだ。

;; * Pretty-lambda fontification. (GNU Emacs 21 only.)

おお。EmacsWiki:PrettyLambdaが入ってる。

スクリーンショット再掲。

[image]

実はしばらく使っていたのだけど、lambda→λは慣れると平気。 むしろエディタ上で無駄なスペースが圧縮されてよい感じ。

半端なところからコピペしたらソースコードが壊れる問題は直っているのかしら。 この問題がなかったら常用できるのにな。

以前の書き込み。

Scheme/Note:quack-pretty-lambda-p

Category of Scheme

え、2003-01-03の時点でもう入ってる?

;; Version 0.17 (2003-01-03)
;; * Pretty-lambda is supported well under GNU Emacs 21, when using PLT
;; Style fontification. Enable via the Options menu. (Based on
;; approach by Stefan Monnier; suggested by Ray Racine.)

ソース読んでないだけだったorz

Lisp/Scheme/Note:slime-for-scheme48

Category of Lisp
Category of Scheme

そういえばscheme48のインタプリタはエラーで中断/再開できるのだった。 goshでもできたっけ?

あー、それにslimeでごにょごにょしようとするなら、 インタプリタ側でtcp/ipのportを開いて待ってやらないといけないのか。

swank-scheme48以下のschemeコードを流し読んでみたけど、げー。けっこう複雑ね。 セッション管理もreplも全部自前だし。全コードで4000行越えてるし。 もはやslimeとは別物感あり。

Lisp/Scheme/slime-for-scheme48

Category of Lisp
Category of Scheme

slimeをひさびさにcvs updateしてみた。

  • swank-scheme48/: New backend.

キタ━━━━(゜∀゜)━━━━ッ!!

いや、まてよ。 ということはこいつをいじればgoshなりcsiなりもslimeで動かせるのかな?

quack以外の選択肢が突如浮かび上がってきた予感。

Lisp/Scheme/Chicken/guess-jp.egg

Category of Lisp
Category of Scheme
Category of Chicken

ChickenでもGaucheのguessを使えるようにしてみた: (files:guess-jp.egg)

必要なもの

chicken-2.0 on OpenBSD-currentで動作確認。 大抵の環境で動くでしょう。

インストール

 # chicken-setup guess-jp.egg

使いかた

$ echo '(require-extension guess-jp)(display (guess-jp "ほげ"))(newline)' | \
gauche-cesconv --to-code EUC-JP > euc.scm
$ csi -quiet -batch euc.scm
EUC-JP
$ gauche-cesconv --to-code UTF-8 euc.scm > utf8.scm
$ csi -quiet -batch utf8.scm
UTF-8

自分で書いたのはインストールのためのコードも含めて20行程度。 chickenのEasy FFIとオートビルドの連携はなかなか興味深い。


作ってから eggs:charconvなるものがあることを知ったorz

OpenBSD/emacs-brokenness

Category of OpenBSD

原因判明。

最近のOpenBSD-cvs:src/libexec/ld.soのcommitが悪さをしているらしい。

  1. Rework symbol lookup to more closely match sun's documentation, now treats dlopens as load groups. ok kurt@
  2. Cleanly handle the case where a dynamic object is opened, but one of it's dependant libraries is missing. return NULL for a handle instead of causing the program to exit.

とかいうてる。

 # cd /usr/src/libexec/ld.so && cvs -q update -Pd -D "1 week ago"
 # make depend all install cleandir

で以前のように動作するようになった。

OpenBSDの変更に問題があるのか、 EmacsがいままでのOpenBSDに挙動に合せて、 何かトリッキーなことをやっているのか、のどちらかなんだよなあ。

他のソフトは全く問題ないから恐らく後者に修正すべき点があるんだろうな。 Emacsのソース読むか。

OpenBSD/emacs-brokenness

Category of OpenBSD

ぐはっ。Emacsが壊れた。

キーを叩く毎にcpu loadがいっぱいいっぱいになる。なんじゃこりゃ。

いろいろ思い当るふしがあるので(馬鹿でかい~/.emacsとか、ちょっとまえにfsckしたとか、ひさびさに# make buildしたとか)、 原因究明は難しい。というか恐しく面倒。

これじゃあS式入力できねえずら。困った。メールも読めないねえ。

Scheme/reverse-polish-notation-calculator

Category of Scheme

ひらいさんとのやりとりの後で、

うーん、いまいちエラー処理がかっこ悪いような気がします。

が出た時点でお茶吹いた。

エラー処理がちょっとおさまり悪いですかねぇ。

え、え〜と……


これだけでは何なので、

せっかくだからutil.matchを使って書いてみた。 かなり邪道っぽいコードになった。

せっかくだからreplに(pはしないけど)。

せっかくだから使える命令はforth風。

  • bye: 終了
  • d: forthの"."
  • s: forthの".s"
  • drop
  • dup
  • over
  • rot
  • swap
  • 四則演算

入力例

2 3 4 + swap / d

とかすれ。

ソース

$ cat rpncalc.scm
#!/usr/bin/env gosh

(use util.match)
(use rfc.base64)
(use gauche.charconv)

(define global-stack '())

(define (rpcalc expr stack)
  (define (not-num? n)
    (not (number? n)))
  (if (null? expr)
      stack
      (let ((newstack (cons (car expr) stack)))
        (match newstack
               (('bye _ ...)
                (print "BYE!")
                (exit))
               (('d _ ...)
                (cond ((null? stack)
                       (print "no room")
                       '())
                      (else (display (car stack))(display " ")
                            (rpcalc (cdr expr) (cdr stack)))))
               (('s _ ...)
                (rpcalc-write stack)
                (rpcalc (cdr expr) stack))
               (('drop a b ...)
                (rpcalc (cdr expr) b))
               (('dup a b ...)
                (rpcalc (cdr expr) (cons a (cons a b))))
               (('over a b c ...)
                (rpcalc (cdr expr) (cons b (cons a (cons b c)))))
               (('rot a b c d ...)
                (rpcalc (cdr expr) (cons c (cons a (cons b d)))))
               (('swap a b c ...)
                (rpcalc (cdr expr) (cons b (cons a c))))
               (('+ a b c ...)
                (rpcalc (cdr expr) (cons (+ b a) c)))
               (('- a b c ...)
                (rpcalc (cdr expr) (cons (- b a) c)))
               (('* a b c ...)
                (rpcalc (cdr expr) (cons (* b a) c)))
               (('/ a b c ...)
                (rpcalc (cdr expr) (cons (/ b a) c)))
               (((? not-num? _) _)
                (print "no room")
                stack)
               (((? not-num? a) _ ...)
                (format #t "not number '~a'\n" a)
                stack)
               ((a ...)
                (rpcalc (cdr expr) newstack))))))

(define (rpcalc-read)
  (read-from-string (string-append "(" (read-line) ")")))

(define (rpcalc-write stack)
  (display (regexp-replace-all #/^[\(](.*)[\)]$/
                               (write-to-string (reverse stack)) "\\1 ")))

(define (rpcalc-eval expr env)
  (set! global-stack (rpcalc expr global-stack)))

(define (rpcalc-print ...)
  (print "ok"))

(define (rpcalc-prompt)
  #t)

(print (ces-convert
        (base64-decode-string
"GyRCPWs2bCQ3JCQ5UyRsJD8lVyVtJTAlaSVfJXMlMDhAOGwzJiRLOkYkUzVfQCQ8ZyQsISob
KEIKCiAKCiAbJEIhISEhISEbKEJ8GyRCITEbKEJ8fBskQiExGyhCfCAKIBskQiEhISEhMxso
QnwbKEklGyhCIBskQiJPGyhCIBsoSSUbKEJ8GyRCJU4hITNkJGwka0tAJSIlJCU5JEckOSRo
ITwbKEIgCiAbJEIhISEhISEbKEJ8GyRCITIbKEJ8fBskQiEyGyhCfCAKGyRCISEhISEhGyhC
ICAbJEIiQBsoQiAgGyRCIkAhISEhGyhCIA==")
        "utf-8"))

(read-eval-print-loop rpcalc-read rpcalc-eval rpcalc-print rpcalc-prompt)

Lisp/Scheme/pp

Category of Lisp
Category of Scheme

WiLiKi:Gauche:PrettyPrintに昔書いたコードをぺたり。 オリジナルの方を貼るのは恥ずかしいので(末尾再帰ですらない。hehe)、 WiLiKi:hiraさんの改良版の方をば。

そういえば、WiLiKi:hiraさん最近見かけないのですが、 どうしたんでしょうか。日記も更新が止まってるし。

WiLiKi/Hack

Category of Hack

WiLiKiのちょっとしたハックをまとめたページを作ろう。

どこまで増えるかな。

Erlang/string

Category of Erlang

Erlang/2005/09/05/こんなLLはXXだにて文字列型がないと書いたが、 どういうことかというと、あれだ。 Cといっしょ。 Erlangにおける文字列は要するにリスト。Cだとポインタだから正確には違うか。

> string:equal("hello", [104,101,108,108,111]).
true

Cと違った明白な利点はやはり、car, cdrがそのまま引っぱってこれることでしょう。

例えば、公式配布のドキュメントに付いてくるサンプルとして、 下のような順列のリストを作る関数permsを例にとってみる。

The following example generates all permutations of the elements in a list:

perms([]) -> [[]];
perms(L)  -> [[H|T] || H <- L, T <- perms(L--[H])].

We take take H from L in all possible ways. The result is the set of all lists [H|T], where T is the set of all possible permutations of L with H removed.

> perms([b,u,g]).
[[b,u,g],[b,g,u],[u,b,g],[u,g,b],[g,b,u],[g,u,b]]

リストの内包表記の例なんだけど、この話は置いておいて、 これがそのまま文字列にも適用できる。

> lists:foreach(fun (X) -> io:fwrite("~s ", [X]) end, perms:perms("anagram")).

おお、アナグラム生成プログラムが3行で書けた。

でもまあ文字列型がないと、他のLL言語のように正規表現でウヴォアー、 ってができないのでちと痛い。

Memo/rubic-cube

ルービックキューブといえば………

これでしょう。

メタマジック・ゲーム

群論の話ももちろん出ます。さわりだけですが。 群論を使えばN次元のキューブが自動で解ける話など、当時は、へー、と思ったものです。

N次元のキューブとしては、 Magic Cube 4Dで4次元のキューブが遊べます。 おすすめ。

ホフスタッターといえばGEBですが、これもおもしろい。 あとは、マインズ・アイも抜きには語れないでしょう。

Lisp/Scheme/RtS:いわた

Category of Lisp
Category of Scheme

WiLiKi:Scheme:RoadToScheme

最初にSchemeを使ったのはいつ頃でしたか、またその処理系は?

DOSの上でSCMをTurbo C++(2nd Edition)でコンパイルして遊んでいた記憶がある。 いつの話だろう。 もっと疑問なのはどうやってS式をインデントしていたのか、ということだ。

そのころに比べてもさっぱり上達してないのがorz

どうしてSchemeを使ってみようと思ったのでしょう

そこにあったから。

それまで良く使っていた他の言語は?

Cかなあ。あとは8086アセンブラ。 開発環境がPC9801上のDOSしかなかったので、 たいていの言語はビルドするのもかなわなかった。 UNIX文化への憧れはここらへんにあったのかもね。

どのくらいSchemeを使い込んでいますか?

どのくらいかなあ。少なくともプロダクションコードは書いたことないな。

研究には、主にSTkとGaucheとSCMを使ってる。

STkはGUIとお絵描きのためだと割り切れば今でもわりと使える。 Postscriptで出力できるのが便利(論文に直接貼れる)。 Tcl/Tkは途中で飽きたけどこっちはおもしろい。 デバッグメッセージがわかりづらいのが難。

Gaucheは文字列処理のためかなあ。 OpenBSDで動くようになったのがつい最近(3.4のころ)なので、 ちょっとくやしい思いをした。

SCMはリスト処理がとにかく速いのでシミュレーションに使用。 高分子鎖を生成してGeomviewに喰わせたり。

Schemeについて感じてることをざっくばらんにどうぞ

根底に流れるミニマリズムがよい。

覚えるべきことが少ない。 でも、工夫しないと何もできないことの裏返しなのかも。

Erlang/こんなLLはXXだ

Category of Erlang

erlangは次に該当。

  • 各オブジェクト毎にプロセスを作って本当にメッセージ通信
  • 文字列リテラルがない
  • 変数の先頭が勝手に大文字になる
    • いや、勝手じゃないけど
    • 先頭が大文字は変数、小文字はシンボル。もちろんそうしないやり方もある

やっぱerlangはXXなのかー。


よだん

野暮かもしれないけど横から勝手につっこみ(というかスポイラーというか)。 LLDN参加してないけど。

  • よめない(whitespace
  • 全部大文字
    • 昔のFORTRANとかLISPとかはそうじゃなかった?つかASCII以前はそうじゃね?
  • 制御がgotoとifだけ
    • アセンブラだとifすらないことも、って違うか
  • ASCIIにない記号が入ってる
  • まず時刻を入力
    • command.comナツカシス
  • ファイルが16個までしか開けない/対話インタプリタを立ち上げると"How many files (0-15)?"/行番号必須
    • N88 BASICテラナツカシス
  • 半角カナのみサポート
    • 昔のLogoってそうじゃなかった?未確認。
  • 使われない予約語が200個/2006年にはユーザの大半がリタイア
  • ソースをカセットテープで配布
  • ネトランにマスコットフィギュアが
  • 頭に"net"が付いたpatch集で開発が続いているが、本家にマージされない
    • 4.3BSD
  • 変数名に$%^&*-_+=\|がつかえる
    • Lisp/Scheme(手続き名にもつかえる)
      > (define -_- #f)
      > (define-macro ~_~ (lambda vars `(set! ,@vars)))
      > (define *_* +)
      > (define |^_^| 1)
      > (define +_+ 2)
      > (~_~ -_- (*_* |^_^| +_+))
      > -_-
      -> 3
      
    • 変数名に`とか'とか"とかがエスケープ無しで使えたらもっとXXかも
  • 処理系の名前が(ぴーーー)(放送禁止
  • プロンプトがギコ猫
    • しぃ言語: プロンプトじゃなかった。わりぃ。
  • 起動時マスコットをAA表示
    • これってインタプリタにはけっこう多いよ。例えばBiglooとか。阿部のAAはやだなあ。
  • "All your base are belong to us"や"You is big fool man"のような品質のドキュメントしか無い
  • 処理系がライフゲームのグライダーガンとブリンカー等を組み合わせて構築されている
  • 処理系に人狼が紛れ込んでいる
    • 人狼BBS
  • 言語の名前で検索するとエロゲーがヒット
  • 記法がXMLだ
    • XSLT: お世話になってます
    • SXSLTはもっとcool
  • メジャーバージョンアップでObject指向が導入されると、ヌルいユーザーがみんな逃げる
    • これって、p
  • ボトルを99本数えることしかできない
  • 変数の先頭が勝手に大文字になる
    • ExcelのオートコレクトがデフォルトでONの件について
  • 右から左に書く
    • forth/postscript系?述語が逆なだけか。
  • 国防総省のメインフレームとマルペケができる

Security/bo2k-fu-plugin

Category of Security

まだ開発が続いているbo2k

新たに強力なプラグインが追加された。

元はwww.rootkit.comFU rootkitというもので、Windowsのカーネルにはりついて、 これは任意のファイルとプロセスを隠せるようにするドライバらしい(もちろんドライバ自身もユーザプロセスから見えなくなる)。

まあrootkitの動作としてはありきたりかもしれないけど、 bo2kに入るとなるとかなりアレだ。

Erlang/reverse-polish-notation-calculator

Category of Erlang

同じく、たなかさんのねた: 逆ポーランド電卓

Schemeで書く場合でも、副作用を用いないで書くように心掛ければ、 リスト処理のよい練習になるのではないでしょうか。

勉強のために作っていらっしゃるそうなので、 邪魔をしないようにerlangで。

$ cat rpcalc.erl
-module(rpcalc).
-export([rpcalc/1]).

op (X, M, N) ->
    case X of
        '+' -> M + N;
        '-' -> M - N;
        '*' -> M * N;
        '/' -> M / N;
        _   -> unknown
    end.

rpcalc ([], N, S) when is_number(N) ->
    [N | S];
rpcalc ([], X, [M, N | S]) ->
    [op(X, N, M) | S];

rpcalc ([H | T], N, S) when is_number(N)->
    rpcalc(T, H, [N | S]);
rpcalc ([H | T], X, [M, N | S]) ->
    rpcalc(T, H, [op(X, N, M) | S]).

rpcalc ([H | T]) ->
    rpcalc(T, H, []).

$ erl
1> c(rpcalc).
{ok,rpcalc}
2> io:fwrite("~w~n", rpcalc:rpcalc([2, 3, '*', 4, 5, '+', '*'])).
54
ok

パターンマッチ万歳。

WiLiKi/Blog

ねるWiki:NelDiary:2005-09-06にて原作者さまから反応が。

この割りきり方は、非常にセンスがよいなぁ、と感心しきり。

ずぼらなだけです。はい。

少しインスパイアーされたので、また、改造しよう。

おお、期待してます。

あ、でも、つぎはいろいろやってみたいので、kahua-webにするかも...

まあそんなことおっしゃらずに……

それにしても、ウェブアプリケーションサーバ(以下アプリケーションサーバ)かあ。 ここはレンタルサーバだからアプリケーションサーバは無理だろうなあ。 Apacheと共存とか(mod_proxyを使う?)、 アプリケーションサーバの再起動とかどうするねん。

まあ、アプリケーションサーバが使えたとしても、 kahua-webやUnCommonWebみたいなのは使わないだろうな。 私にとってウェブページで何かを公開するということは、 辺境探索の足跡みたいなものなので(こういう発想がオールドタイプ)。

もしアプリケーションサーバが可能なら、

くらいは試してみたい(yawsは手元の環境で起動中。埋め込みerlang萌え)。 どちらもモヒカンどころか北京原人が出そうなくらい辺境。

Zopeは絶対使わない候補。でもイントラネットではこっそりPloneを立ち上げていたり。


せっかくだから専用のページなぞつくってみる: WiLiKi/Blog

Memo/prompt

Memo/2005/09/05/promptの続き。

仮想端末でエスケープシーケンスの打ち方がわからないので(恥、 EmacsでC-qC-[を使って一時ファイルを作成。 OpenBSD-man:sourceで更新。

おお。緑色になった。昔のマイコンみたい。 そういえば私もDOSのころは環境変数PROMPTをいじってカラフルにしていた覚えが。

入力行狭っ。と思ったら、カーソルが被さったときは消えてくれるのですね。 RPS1なんて知りませんでした。メモメモ。

時間はどうなんでしょう。私の場合、 壁紙を1時間おきに変えるようにしているため、 仮想端末を透過させていると大体の時間がわかるので、 プロンプトには設定してません。

dateにしてもttyにしてもコマンドラインで叩けば出るので、 あとはコマンドプロンプトに設定するかどうかは単に使用頻度だけなんですよね。

Programming/fixedpoint-and-memoise

Category of Programming

仕切りなおします。

Memo/prompt

こういうやりとりをしたのだけど、 おまえらどんなプロンプトにしていますか?

私は上のように、

 ホスト名,tty番号,終了ステータス$ 

にしてる。

デフォルトでフルパスを設定してあるログインシェルがあるけど、 あれってうざったいだけで役に立たないと思う。 パスが深くなったらどうするの、とか。

というか、いくら鳥頭の私でも、 カレントディレクトリくらいは覚えていられるので不要(サーバ屋さんなら知らないけど)。 忘れたらpwdを鬼のように打鍵。

そういえば、いつもTERM=xterm-256colorだけど、 プロンプトは色づけしてないな。 ルートはいつも

 #

だし(/bin/ksh)。

Programming/Note:fixedpoint-and-memoise

Category of Programming

  • より完全なSchemeによるmemoiseの考察がWiLiKi:fuyukiさんによって書かれている。

Erlang/Note:memoise

Category of Erlang

うむ。N=1000程度でスローダウンするのはやっぱりおかしい。

Scheme版

(define (memoise f)
  (let ((m '()))
    (lambda (x)
      (cond ((assoc x m) => cdr)
            (else
             (let ((n (f x)))
               (set! m (cons (cons x n) m))
               n))))))

(define (fib x)
  (if (<= x 1)
      1
      (+ (fib (- x 1)) (fib (- x 2)))))

(set! fib (memoise fib))

GaucheやscmだとN=10000でも大丈夫だし。 どこかおかしいに違いない。

と思ったらN=10000時にScheme 48がheap overflowで死亡。 N=8000くらいならなんとか。

うーむ。

Lisp/Scheme/want-to-learn-lisp

Category of Lisp
Category of Scheme

43things.comってソーシャルネットワークだよね。 はげましあいながらlispを学習する、と。

ほほえましい光景だなあ。

Erlang/memoise

Category of Erlang

erlangでメモ化(2005/09/03/Erlang/fixedpointの続き)。

Processを使ったメモ化、 がんばって作ったよ(`・ω・´)

$ cat memo_fib.erl
-module(memo_fib).
-export([lookup/2, append/3, memoisep/1, memoise/2, memo_fib/1, make_fib/0, test_fib/0]).

lookup (N, MM) ->
    case lists:keysearch(N, 1, MM) of
        {value, {_, T}} ->
            {value, T};
       false -> false
    end.

append (N, M, MM) ->
    lists:keymerge(1, [{N, M}], MM).

memoisep (MM) ->
    receive
        % debug
        {show} ->
            io:fwrite("~w~n", [MM]),
            NMM = MM;
        {lookup, P, N} ->
            case lookup(N, MM) of
                {value, T} ->
                    P ! {value, T};
                false ->
                    P ! false
            end,
            NMM = MM;
        {append, P, N, M} ->
            NMM = append(N, M, MM),
            P ! NMM
    end,
    memoisep(NMM).

memoise (P, F) ->
    fun (N) ->
            P ! {lookup, self(), N},
            receive
                {value, T} ->
                    % debug
                    % io:fwrite("cache hit ~w is ~w~n", [N, T]);
                    true; % dummy for nodebug
                false ->
                    T = F(N),
                    P ! {append, self(), N, T}
            end,
            T
    end.

memo_fib (P) ->
    memoise(P, fun (X) ->
                       if X =< 1 -> 1;
                          true   -> (memo_fib(P))(X - 1) + (memo_fib(P))(X - 2)
                       end
               end).

make_fib () ->
    P = spawn(memo_fib, memoisep, [[]]),
    fun (N) ->
            (memo_fib(P))(N)
    end.

test_fib () ->
    Fib = memo_fib:make_fib(),
    io:fwrite("Fib(1000) is ~w~n", [Fib(1000)]),
    halt().

$ erl
1> c(memo_fib).
{ok,memo_fib}
2> Fib = memo_fib:make_fib().
#Fun<memo_fib.x.xxxxxxxxx>
3> lists:map(Fib, [1, 2, 3, 4, 5]).
[1,2,3,5,8]

process以外のところはSICP Exercise 3.27を参考に書いたので、 比較するとおもしろいかも。

とりあえずベンチマーク。

$ time erl -noshell -s memo_fib test_fib
Fib(1000) is 70330367711422815821835254877183549770181269836358732742604905087154537118196933579742249494562611733487750449241765991088186363265450223647106012053374121273867339111198139373125598767690091902245245323403501
erl -noshell -s memo_fib test_fib  0.78s user 0.23s system 93% cpu 1.082 total

1秒程度で返ってくるけど、答えあってる? Fib(1500)以上はちょっとつらい。 メモリが足りない。 Fib(1)...Fib(N)のすべて(しかもNが十分に大きいとBigNumになってしまう)をキャッシュしてるわけだから、あたりまえか。

memo_fib/1と2005/09/03/Erlang/fixedpointのfib_maker/1の違いが、 今回のお話のキモなのかなあ(未だにわかってない人)。

ちょっとコードが長すぎるかなあ。もっと短かくなるんだろうなあ。 じゃないと、

現場からの報告は、「科学的な」研究よりは精度が劣らざるを得ないが、意味のあるものである可能性は高い。例えばEricssonでUlf Wigerがやった研究では、 ErlangはC++より4〜10倍簡潔で、それに比例して速く開発ができたと結論づけている:

Ericsson内部の開発プロジェクト間の比較によれば、ソフトウェア開発の全ての段階において使用言語(Erlang, PLEX, C, C++, Java)の如何にかかわらず、時間当たりの開発行数は似たような数値となった。言語間の差が出たのはソースコードの量だった。

簡潔さは力なり---Succinctness is Power---

は嘘になってしまうもんな。

それにしても、これは疲れた。慣れないことはすべきじゃないよね。

Audio/g-town-church-sampling-project

Category of Audio

G-Town Church Sampling Projectなるプロジェクトがあるらしい。

なんというか、えらいことになってる。

10M超のサウンドフォントがドカスカアップロード中。 しかも全部Creative Commons Sampling Plus 1.0 license

さっそくダウンロードしてみるべ。

Erlang/fixedpoint

Category of Erlang

おもしろい議論。 せっかくなのでerlangでやってみた。

$ cat fix.erl
-module(fix).
-export([fix/1, fib_maker/1]).

fix (G) ->
    (G)(fun (X) -> (fix(G))(X) end).

fib_maker(F) ->
    fun (X) ->
            if X =< 1 -> 1;
               true   -> (F)(X - 1) + (F)(X - 2)
            end
    end.

$ erl
1> c(fix).
{ok,fix}
2> Fib = fix:fix(fun (X) -> fix:fib_maker(X) end).
#Fun<fix.x.xxxxxxxx>
3> lists:map(Fib, [1, 2, 3, 4, 5]).
[1,2,3,5,8]

Scheme版とほぼ同じになって芸がないなあ。つか、erlangってば関数型言語のくせに高階関数扱いづれー(yet still erlang much better than C)。

memoizeが目的の場合erlangだとこの方法は取らない。多分。 callerがspawnさせて、calleeがメモするのがerlang流。多分。 でもその場合はfibを壊さないとだめか。本末転倒。

追記

Erlang/2005/09/04/memoiseでメモにチャレンジしてみました。

WiLiKi/移行作業その4

カテゴリに無理矢理対応(wiliki-blog.scm.diff)。

WikiNameに\d\d\d\d/\d\d/\d\dが含まれたらBlogとみなすように(乱暴)。

とりあえず、permalinkは"カテゴリ/\d\d\d\d/\d\d/\d\d/タイトル"でいこう。

新しいbookmarkletはこんなの。

javascript:(function(){function z(x){if(x < 10)return "0"+x;return x;}tm=new Date();t=window.prompt("titie?", "");tt=t.split(":");location.href='http://example.com/log/'+tt[0]+"/"+tm.getFullYear()+"/"+z(tm.getMonth()+1)+"/"+z(tm.getDate())+"/"+tt[1]+"?c=e";})()

『カテゴリ:タイトル』をダイアログへ入力すれば新規ページ作成。

Note:Programming/concurrency

せっかくだから、erlangの http://www.erlang.org/white_paper.html を読んでみる。

  • Concurrency: 分散処理だわな
  • Distribution: ネットワーク上のどこにでもノードを生成できるよ
  • Robustness: エラー処理重要
  • Soft real-time: リアルタイム処理下のガベージコレクションも考慮してるよ
  • Hot code upgrade: 動作中のプログラムを停止させることなく入れ替えできるよ
  • Incremental code loading: いつでも新たなコードを読み込みできるよ
  • External interfaces: Cの関数に/からメッセージパッシングできるよ

ターゲットとして組み込み系を意識しているのは明白だし、実際ATM交換機で動いているらしい。

Programming/concurrency

Category of Programming

CPUの話なのか言語の話なのかわかりにくいけど、 並列プログラミングってそんなに新しいパラダイムではないような。

erlangなんて1980年後半に現われた言語だけど、 すでに並列プログラミングが大きな焦点になってるし。

erlangという言語自体がEricsson(erlangはERicsson LANGuageの略)が電話交換機のために開発したものらしいので、 信号処理ってのはイベントが並行して起こることが多いのだろうなあ、とは思う。

関数型言語だと、参照透過性のおかげで破綻しにくいのだろうけど、 ようやく手続き型言語で問題になったという認識でいいのだろうか。

以下話はずれ続けるけど、 OSに限って言えば、原子性(atomicity)に関する議論はいろいろあるんじゃないかな。 Google:race conditionとか、なんでmktempがいかんのかとか、 たいていセキュリティがらみで出てくるのでちょっと議論がずれてしまうのがアレだ。 まあマルチタスクOSならデータをうっかり壊さないようにするためにも、 議論が必須な事項であると思う。

Note:nkfが無いのにgoshがある

  • ひらいさんからのつっこみ。

    gosh があるなら、gauche-cesconv もあるんじゃなかろーか、ってツッコミは野暮ですか、そうですか。

その通りでございます。ということで、gauche-cesconvを使いましょう。

  • というか、やっぱりschemeはワンライナーには向かんね。括弧の対応づけが面倒だし。
    • 編集中に対応する括弧をジャンプなりハイライトなりすればいいのか。そんなlogin shell無いかな。
    • eshell(Emacsのshellね)使えばいいのか。そんな私はteminal emulator開きまくりzsh派。screenなんて知らん(嘘)。

X/beautiful-subpixel-rendering

ノートでXを使っている人に朗報。

パッチを見ると、適応範囲がlibXftのみなので、失敗してもすぐ戻せるようだ。 ので、さっそく試してみた。

よくあることだが、 OpenBSDの公式配布のXftのバージョンが合わないのか、パッチは当たるのだが、 ビルドに失敗する。

で、パッチを見るに、 hmul, vmulがそれぞれ(hmul_1, hmul_2)と(vmul_1, vmul_2)に差し替えられているのだが、 上記パッチではどうも完全に置き換えられていないのが原因のようだ。 そこで残りを hmulを(hmul_1 * hmul_2) vmulを(vmul_1 * vmul_2) と手で修正してビルド完了。

インストール後、Xを再起動させてみたのだが、 なによりもboldが以前よりくっきりと美しくなった(このパッチの売りは細いフェイスの場合なのだろうけど)。

スクリーンショット取るの忘れたので紹介できない。残念。

まあおおかたこれで満足なのだが、 ただ、私の環境では、 いまのノートだと解像度がそれほど高くないので、 ~/.fonts.confは

 <match target="font" >
  <test compare="more" name="size" qual="any" >
   <double>9</double>
  </test>
  <test compare="less" name="size" qual="any" >
   <double>15</double>
  </test>
  <edit mode="assign" name="antialias" >
   <bool>false</bool>
  </edit>
 </match>

のように9〜15ptまでではアンチエイリアスを切るように設定しているので、 あまりうれしくはない。うれしさの度合はdpi次第かも。

nkfが無いのにgoshがある

via: http://tokuhirom.dnsalias.org/~tokuhirom/tokulog/1895.html

せっかくだからGaucheで。

$ gosh -E"use gauche.charconv" -e'(copy-port (open-input-conversion-port (standard-input-port) "*jp" :to-code "eucjp") (standard-output-port))'

ちょっと冗長。