Dylan/open-dylan-1.0beta1
gwydion dylan
からOpen Dylan 1.0beta1が出てる。
いまのところバイナリ配布のみのようだ。
Dylanはicfp05
でも頑張ってる(でもやっぱりHaskellっょぃ)。
私自身もDylanを使ったコードは書いたことないのだけど、 ずっと前からOpenBSDでは2nd bootできない。多分トランポリン周りだろうな。
- と思ったらboehm-gcのあたりで死んでるな。なんだろ。
gwydion dylan
からOpen Dylan 1.0beta1が出てる。
いまのところバイナリ配布のみのようだ。
Dylanはicfp05
でも頑張ってる(でもやっぱりHaskellっょぃ)。
私自身もDylanを使ったコードは書いたことないのだけど、 ずっと前からOpenBSDでは2nd bootできない。多分トランポリン周りだろうな。
とうとう解読まで到達。
以前の話のタネになったのが今年の2月。SHA-1が破られた、とかいってたころ。
流れが速過ぎる。
そういえば最近mp3エンコしてないな。aoTuVばっかり。
gauche.uvectorをサポートした。 <c-pointer>からs8vectorへ変換したり、その逆をしたりすることができるようになった。
ということで、Scheme/Gauche/2005/09/25/Gauche-lazy-ffiの、
- ヒープをダンプする手続きを書くこと(名前はpointer-to-vectorかなあ)
は解決。きっちりテストしてないけど大丈夫でしょう。多分。
をGauche-lazy-ffiで書き直したコードを付けた。ま、楽勝でしょ。
巷では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で、という手もありか。
人間が認識できて、機械に認識できないことがある、 という仮定がそもそも微妙な気がする。
参考:
とりあえず自前でポインタ型を作った: 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。
もうちょっといじってみた: files:Gauche-lazy-ffi-20050922.tar.gz
せっかくだからページを作ろう。Scheme/Gauche/Gauche-lazy-ffi
なんちゃってffiのつくりかけ: files:Gauche-lazy-ffi-20050921.tar.gz
要libffi
。
eggs:lazy-ffiみたいなのを目指したのだけど似ても似つかないものに。
なところが偽物。
(define libm (lazy-ffi:open "libm.so.2.0")) (lazy-ffi:function libm "sin" lazy:double 1.0) =>0.8414709848078965
単にScmObjをlibffiに渡しているだけなので、 偽物から脱却するには、 自前のヒープとそれをやりとりするためのインターフェースを作成しないと駄目か。
Gaucheでファイル入出力だけを禁止する方法。めもめも。
Chickenだとeggs:sandboxなんてものあるのな。
てか変なコードの実行が心配だったら、それだけじゃなくて、 OSの保護機構を使うとか仮想化するとか新しいテスト専用マシンを作るとか、 これらを同時に使って対策するとかしたほうがいいような。
ソフトウェアでなんとかするにしても、chroot(8)なりjail(8)なりqemuなりknoppixなり、 これって結局面倒臭さと安全性の度合とのトレードオフなのだけど、いろいろあるよね。
そういえばquack
。
手元のものは古かったので、
ダウンロードしてChangeLog読んだ。
;; * Pretty-lambda fontification. (GNU Emacs 21 only.)
おお。EmacsWiki:PrettyLambdaが入ってる。
スクリーンショット再掲。
実はしばらく使っていたのだけど、lambda→λは慣れると平気。 むしろエディタ上で無駄なスペースが圧縮されてよい感じ。
半端なところからコピペしたらソースコードが壊れる問題は直っているのかしら。 この問題がなかったら常用できるのにな。
以前の書き込み。
: PrettyLambdaの紹介
: 括弧消しまくり
え、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
そういえばscheme48
のインタプリタはエラーで中断/再開できるのだった。
goshでもできたっけ?
あー、それにslimeでごにょごにょしようとするなら、 インタプリタ側でtcp/ipのportを開いて待ってやらないといけないのか。
swank-scheme48以下のschemeコードを流し読んでみたけど、げー。けっこう複雑ね。 セッション管理もreplも全部自前だし。全コードで4000行越えてるし。 もはやslimeとは別物感あり。
slime
をひさびさにcvs updateしてみた。
- swank-scheme48/: New backend.
キタ━━━━(゜∀゜)━━━━ッ!!
いや、まてよ。 ということはこいつをいじればgoshなりcsiなりもslimeで動かせるのかな?
quack
以外の選択肢が突如浮かび上がってきた予感。
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-cvs:src/libexec/ld.soのcommitが悪さをしているらしい。
- Rework symbol lookup to more closely match sun's documentation, now treats dlopens as load groups. ok kurt@
- 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のソース読むか。
ぐはっ。Emacsが壊れた。
キーを叩く毎にcpu loadがいっぱいいっぱいになる。なんじゃこりゃ。
いろいろ思い当るふしがあるので(馬鹿でかい~/.emacsとか、ちょっとまえにfsckしたとか、ひさびさに# make buildしたとか)、 原因究明は難しい。というか恐しく面倒。
これじゃあS式入力できねえずら。困った。メールも読めないねえ。
ひらいさんとのやりとり
の後で、
うーん、いまいちエラー処理がかっこ悪いような気がします。
が出た時点でお茶吹いた。
エラー処理がちょっとおさまり悪いですかねぇ。
え、え〜と……
これだけでは何なので、
せっかくだからutil.matchを使って書いてみた。 かなり邪道っぽいコードになった。
せっかくだからreplに(pはしないけど)。
せっかくだから使える命令はforth風。
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)
WiLiKi:Gauche:PrettyPrintに昔書いたコードをぺたり。 オリジナルの方を貼るのは恥ずかしいので(末尾再帰ですらない。hehe)、 WiLiKi:hiraさんの改良版の方をば。
そういえば、WiLiKi:hiraさん最近見かけないのですが、
どうしたんでしょうか。日記
も更新が止まってるし。
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言語のように正規表現でウヴォアー、 ってができないのでちと痛い。
ルービックキューブといえば………
これでしょう。
群論の話ももちろん出ます。さわりだけですが。 群論を使えばN次元のキューブが自動で解ける話など、当時は、へー、と思ったものです。
N次元のキューブとしては、
Magic Cube 4D
で4次元のキューブが遊べます。
おすすめ。
ホフスタッターといえばGEBですが、これもおもしろい。
あとは、マインズ・アイ
も抜きには語れないでしょう。
DOSの上でSCMをTurbo C++(2nd Edition)でコンパイルして遊んでいた記憶がある。 いつの話だろう。 もっと疑問なのはどうやってS式をインデントしていたのか、ということだ。
そのころに比べてもさっぱり上達してないのがorz
そこにあったから。
Cかなあ。あとは8086アセンブラ。 開発環境がPC9801上のDOSしかなかったので、 たいていの言語はビルドするのもかなわなかった。 UNIX文化への憧れはここらへんにあったのかもね。
どのくらいかなあ。少なくともプロダクションコードは書いたことないな。
研究には、主にSTkとGaucheとSCMを使ってる。
STkはGUIとお絵描きのためだと割り切れば今でもわりと使える。 Postscriptで出力できるのが便利(論文に直接貼れる)。 Tcl/Tkは途中で飽きたけどこっちはおもしろい。 デバッグメッセージがわかりづらいのが難。
Gaucheは文字列処理のためかなあ。 OpenBSDで動くようになったのがつい最近(3.4のころ)なので、 ちょっとくやしい思いをした。
SCMはリスト処理がとにかく速いのでシミュレーションに使用。
高分子鎖を生成してGeomview
に喰わせたり。
根底に流れるミニマリズムがよい。
覚えるべきことが少ない。 でも、工夫しないと何もできないことの裏返しなのかも。
erlangは次に該当。
やっぱerlangはXXなのかー。
野暮かもしれないけど横から勝手につっこみ(というかスポイラーというか)。 LLDN参加してないけど。
な
: どうなったんだろ
> (define -_- #f) > (define-macro ~_~ (lambda vars `(set! ,@vars))) > (define *_* +) > (define |^_^| 1) > (define +_+ 2) > (~_~ -_- (*_* |^_^| +_+)) > -_- -> 3
: プロンプトじゃなかった。わりぃ。
とか。阿部のAAはやだなあ。
を読むと楽しめるねた。
もしやと思ってWikipediaを調べると同様の記述があった(Wikipedia-ja:ライフゲーム
)。
計算が終了するのに何年かかる?
も面白かったなあ。安野光雅氏の絵も楽しい。
(via: http://www.radiumsoftware.com/0508.html#050830 )
に含まれるサンプルpit/beer.i
はボトルを数えることすら難しいことを我々に教えてくれる
かなあ。観た記憶がない。
まだ開発が続いているbo2k
。
新たに強力なプラグインが追加された。
元はwww.rootkit.com
のFU rootkit
というもので、Windowsのカーネルにはりついて、
これは任意のファイルとプロセスを隠せるようにするドライバらしい(もちろんドライバ自身もユーザプロセスから見えなくなる)。
まあrootkitの動作としてはありきたりかもしれないけど、 bo2kに入るとなるとかなりアレだ。
同じく、たなかさんのねた: 逆ポーランド電卓
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
パターンマッチ万歳。
ねるWiki:NelDiary:2005-09-06にて原作者さまから反応が。
この割りきり方は、非常にセンスがよいなぁ、と感心しきり。
ずぼらなだけです。はい。
少しインスパイアーされたので、また、改造しよう。
おお、期待してます。
あ、でも、つぎはいろいろやってみたいので、kahua-webにするかも...
まあそんなことおっしゃらずに……
それにしても、ウェブアプリケーションサーバ(以下アプリケーションサーバ)かあ。 ここはレンタルサーバだからアプリケーションサーバは無理だろうなあ。 Apacheと共存とか(mod_proxyを使う?)、 アプリケーションサーバの再起動とかどうするねん。
まあ、アプリケーションサーバが使えたとしても、 kahua-webやUnCommonWebみたいなのは使わないだろうな。 私にとってウェブページで何かを公開するということは、 辺境探索の足跡みたいなものなので(こういう発想がオールドタイプ)。
もしアプリケーションサーバが可能なら、
くらいは試してみたい(yawsは手元の環境で起動中。埋め込みerlang萌え)。 どちらもモヒカンどころか北京原人が出そうなくらい辺境。
Zopeは絶対使わない候補。でもイントラネットではこっそりPloneを立ち上げていたり。
せっかくだから専用のページなぞつくってみる: WiLiKi/Blog
仮想端末でエスケープシーケンスの打ち方がわからないので(恥、 EmacsでC-qC-[を使って一時ファイルを作成。 OpenBSD-man:sourceで更新。
おお。緑色になった。昔のマイコンみたい。 そういえば私もDOSのころは環境変数PROMPTをいじってカラフルにしていた覚えが。
入力行狭っ。と思ったら、カーソルが被さったときは消えてくれるのですね。 RPS1なんて知りませんでした。メモメモ。
時間はどうなんでしょう。私の場合、 壁紙を1時間おきに変えるようにしているため、 仮想端末を透過させていると大体の時間がわかるので、 プロンプトには設定してません。
dateにしてもttyにしてもコマンドラインで叩けば出るので、 あとはコマンドプロンプトに設定するかどうかは単に使用頻度だけなんですよね。
こういうやりとりをしたのだけど、 おまえらどんなプロンプトにしていますか?
私は上のように、
ホスト名,tty番号,終了ステータス$
にしてる。
デフォルトでフルパスを設定してあるログインシェルがあるけど、 あれってうざったいだけで役に立たないと思う。 パスが深くなったらどうするの、とか。
というか、いくら鳥頭の私でも、 カレントディレクトリくらいは覚えていられるので不要(サーバ屋さんなら知らないけど)。 忘れたらpwdを鬼のように打鍵。
そういえば、いつもTERM=xterm-256colorだけど、 プロンプトは色づけしてないな。 ルートはいつも
#
だし(/bin/ksh)。
うむ。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くらいならなんとか。
うーむ。
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)の如何にかかわらず、時間当たりの開発行数は似たような数値となった。言語間の差が出たのはソースコードの量だった。
は嘘になってしまうもんな。
それにしても、これは疲れた。慣れないことはすべきじゃないよね。
G-Town Church Sampling Projectなるプロジェクトがあるらしい。
なんというか、えらいことになってる。
10M超のサウンドフォントがドカスカアップロード中。
しかも全部Creative Commons Sampling Plus 1.0 license
。
さっそくダウンロードしてみるべ。
おもしろい議論。 せっかくなので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-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";})()
『カテゴリ:タイトル』をダイアログへ入力すれば新規ページ作成。
せっかくだから、erlangの http://www.erlang.org/white_paper.html を読んでみる。
ターゲットとして組み込み系を意識しているのは明白だし、実際ATM交換機
で動いているらしい。
CPUの話なのか言語の話なのかわかりにくいけど、 並列プログラミングってそんなに新しいパラダイムではないような。
erlang
なんて1980年後半に現われた言語
だけど、
すでに並列プログラミングが大きな焦点になってるし。
erlangという言語自体がEricsson(erlangはERicsson LANGuageの略)が電話交換機のために開発したものらしいので、 信号処理ってのはイベントが並行して起こることが多いのだろうなあ、とは思う。
関数型言語だと、参照透過性のおかげで破綻しにくいのだろうけど、 ようやく手続き型言語で問題になったという認識でいいのだろうか。
以下話はずれ続けるけど、 OSに限って言えば、原子性(atomicity)に関する議論はいろいろあるんじゃないかな。 Google:race conditionとか、なんでmktempがいかんのかとか、 たいていセキュリティがらみで出てくるのでちょっと議論がずれてしまうのがアレだ。 まあマルチタスクOSならデータをうっかり壊さないようにするためにも、 議論が必須な事項であると思う。
さんからのつっこみ。
gosh があるなら、gauche-cesconv もあるんじゃなかろーか、ってツッコミは野暮ですか、そうですか。
その通りでございます。ということで、gauche-cesconvを使いましょう。
ノートで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次第かも。
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))'
ちょっと冗長。