shibuya.lisp#4 から oreore_lisp
おいらは、毎日、近くのスーパーへ水を汲みに行くのが日課となっている。残念ながら 養老の滝でも不老長寿の水じゃなくて、純水と言うのが残念である。 昔、韓国に駐留してた時は、下宿先の近くに湧き出る、不老長寿の水をよく飲んだものである。
で、このスーパーの水汲み場が結構混雑していて、時間帯によっては行列が出来ている。 とある日、行列に並んでいたら、私の後ろにベビーカーを引いた若いお母さんが。
ベビーカーに乗った子供を見るとは無しに見ると、どうやら、おいらを興味深そうに見ている。 こりゃ、ちょっと挨拶してあげるかな。えっと、坊や?お嬢ちゃん? どっちだろう。服装とか では区別出来そうになかった。
こういう時は、とりあえず お嬢ちゃん と声を掛けるのが大人の対応ってもんだ。で、声を 掛けてみた。「お嬢ちゃん、幾つ?」すると、もみじのような指が2本出てきた。同時に、 恥ずかしいのか、ぱっと横を向いてしまった。でも、やっぱりおいらの事が気になるみたいで チラチラと見ている。
お母さんは、「はにかみ王子で、困ってしまいます」と、その場を取り繕ってくれた。 ありゃ、こりゃ失礼しました。そのお母さんが言う事にゃ、余り外にも出る事がなく、いろいろ な人を見る事も、ましてや知らない人に声を掛けられる事もないので、戸惑っているんでしょう との事。 いろんな人に接して、早く免疫を付けてくださいな。
そういえば、私の住む長屋の子供は、免疫が出来たみたいで、おいらを見ると、「おじちゃん」 と言って、寄ってくるようになったよ。
Gauche-0.9_rc2 time
前回は、AM-Schemeの怪しいmacroを見た。果たして、あのようなマクロで良かったのだろうか? 幾ら考えても分からないので、我らがgaucheでは、どうなっているか、ちと覗いてみる。
解禁まじかのボージョレヌーボーならぬ、今年の新米ならぬ、Gauche-0.9_rc2のソースが手元で 展開されているので、肴にする。
えーと、timeは何処か探してみると、Gauche-0.9_rc2/lib/gauche/time.scmがズバリのものだ。
(define-syntax time (syntax-rules () ((_ expr . exprs) (let*-values (((stimes) (sys-times)) ((sreal-sec sreal-msec) (sys-gettimeofday)) (r (begin expr . exprs)) ((etimes) (sys-times)) ((ereal-sec ereal-msec) (sys-gettimeofday))) (format (current-error-port) ";~,,,,75:s\n; real ~a\n; user ~a\n; sys ~a\n" '(time expr . exprs) (format-delta-time (- (+ ereal-sec (/. ereal-msec 1000000)) (+ sreal-sec (/. sreal-msec 1000000)))) (format-delta-time (/. (- (list-ref etimes 0) (list-ref stimes 0)) (list-ref stimes 4))) (format-delta-time (/. (- (list-ref etimes 1) (list-ref stimes 1)) (list-ref stimes 4)))) (apply values r))) ((_) (syntax-error "usage: (time expr expr2 ...); or you meant sys-time?")) ))
どうやら、新方式のマクロで定義されてるな。でも、言わんとしてる事は分かる。(let*-values ... )内 で、計測して、format 節で、結果の実行時間を表示、最後に、与えた式の結果を表示かな。 ちと、実例をば。
[sakae@nil ~]$ rlwrap mine/bin/gosh gosh> (define (fib n) (if (< n 2) n (+ (fib (- n 1)) (fib (- n 2))))) fib gosh> (time (fib 20)) ;(time (fib 20)) ; real 0.003 ; user 0.000 ; sys 0.000 6765
コードを感じられると、嬉しいものだ。書けと言われると、一発では賭けないけど。 上で出てきた、sys-times、sys-gettimeofdayは、想像つくけど、一応確かめてみる。
gosh> (sys-times) (10 39 0 0 128) gosh> (sys-gettimeofday) 1257739559 720698
sys-timesっていろいろ帰ってくるけど、何を表しているん? gauche-refjしたら、POSIXと言われて 、man 3 times したら。
struct tms { clock_t tms_utime; clock_t tms_stime; clock_t tms_cutime; clock_t tms_cstime; }; この構造の要素は、次のように定義されます: tms_utime ユーザインストラクションの実行に対して請求される CPU タイム。 tms_stime その処理のためのシステムによる実行に対して請求される CPU タイム。 tms_cutime 子プロセスの tms_utime s および tms_cutime s の和。 tms_cstime 子プロセスの tms_stimes および tms_cstimes の和。 すべての時間は、 CLK_TCK 秒で表されます。
って、言われたけど、最後の要素は、FreeBSDでは定義されてない。こりゃ、潜れって事ですかね。 面倒そうなので止めるけど、その使われ方からすると、実時間に直す為の基数だな。そういう 事にしておこう。
で、残る、sys-gettimeofday は、多値で帰ってくるのね。1257739559ってEPOC秒。
[sakae@nil ~]$ date -r 1257739559 Mon Nov 9 13:05:59 JST 2009
date の -r オプションって、FreeBSDだけだったかな? Linuxerは、rubyで軽く、
[sakae@nil ~]$ cat cvtime #!/usr/local/bin/ruby t = ARGV.shift || Time.now puts Time.at t.to_i [sakae@nil ~]$ ./cvtime 1257739559 Mon Nov 09 13:05:59 +0900 2009
嗚呼、久しぶりにrubyコードを書いた象! たった、2行だけど。
また、投書を頂いた象
親切な読者の方から、また投書を頂いた。いつもありがとうございます。本来なら、はてな? あたりで流行りのブログにでもすれば、お手を煩わせる事が無い事は、承知してますが、なに分 、古い人間でして、お許しください。
まず、こんなマクロを定義してみて下さい。 (macro id (lambda (body) `',body))
実際にやってみると
> (macro id (lambda (body) `',body)) id > (id hoge) (id hoge)
なんか、皮剥きが足りないようですね。
つまり、 body に入っているのは (id a) という形のリストなのです。 記事中で定義しているマクロ time の場合だと (time (fib 10)) と 書けば、それは (let ((st (gtod))) (time (fib 10)) (- (gtod) st)) と展開されてしまいます。 どうしてエラーメッセージが Unbound variable f なのかはよくわかりませんが。
エラーになるのは、再帰が起こって、メモリーを食い潰し、gc()やっても 間に合わなくなって、暴走。resetが怒ったというパターンですね。 長年付き合っていると、AM-Schemeの性格が読めてきました。(笑)
> (gc-verbose #t) #t > (time "foo") gc...done. 217368 bytes are free. gc...done. 215672 bytes are free. Error: Unbound variable level [return to toplevel]
と言う事で、AM-Schemeは、my-stackに積んで、少し冷却する事にします。変わりに 未だ、興奮さめやらぬ shibuya.lisp#4 の教材で遊んでみる事にします。遊び 飽きたら、my-stackからpopしてconinueしたいと思いますが、その間に gc()が 入って、stackが破壊されてたら、笑ってお許し下さい。
shibuya.lisp#4の教材から
shibuya.lisp#4のために、吉田さんことyuumi3 さんが 用意された教材がある。 テキストサンプルコード内に、yuumi3が書かれた oreore_lispと言うTiny Lispがあるので これで、しばし遊んでみる。
[sakae@nil ~/oreore_lisp]$ wc * 12 26 169 Makefile 24 90 529 base.lisp 859 2657 22987 oreore_lisp.c 895 2773 23685 total
本当にちっちゃい。本体は、859行となっているが、後半部分は、テストコードになっている ので、実質、620行ぐらいだ。ちと、改造とかもしたくなるに違い無い。
ならば、以前にやった git 一人 するかなと思ったのだけど、ちと大袈裟過ぎる事に 気づいてしまったのだ。だから、、、
RCS の登場
RCSに登場してもらおう。RCSって何よ。また、爺のざれ言かと言うなかれ。
RCS -> CVS -> SVN -> GIT
っつう事で、Lispに例えるなら、Lisp 1.5 みたいなもんだな。
man rcsintro とやると、簡単な説明が出てきます。
[sakae@nil ~/oreore_lisp]$ mkdir RCS [sakae@nil ~/oreore_lisp]$ ci Makefile RCS/Makefile,v <-- Makefile enter description, terminated with single '.' or end of file: NOTE: This is NOT the log message! >> Original >> . initial revision: 1.1 done [sakae@nil ~/oreore_lisp]$ ci base.lisp : [sakae@nil ~/oreore_lisp]$ ci oreore_lisp.c : [sakae@nil ~/oreore_lisp]$ ls RCS/
倉庫としてRCSを用意し、管理したいファイルを、ci コマンドを使って登録します。登録時に 説明文を求められるので、指示に従います。そうすると初期Verとして、1.1が与えられて、倉庫に 格納されてしまいます。以下管理したいファイルを同様に登録します。今3つのファイルを 登録しちゃいましたので、元dirは空になりました。
さて、編集をする目的で倉庫からファイルを取り出します。
[sakae@nil ~/oreore_lisp]$ co -l Makefile RCS/Makefile,v --> Makefile revision 1.1 (locked) done [sakae@nil ~/oreore_lisp]$ co -l base.lisp RCS/base.lisp,v --> base.lisp revision 1.1 (locked) done [sakae@nil ~/oreore_lisp]$ co -l oreore_lisp.c RCS/oreore_lisp.c,v --> oreore_lisp.c revision 1.1 (locked) done [sakae@nil ~/oreore_lisp]$ ls Makefile RCS/ base.lisp oreore_lisp.c
これで、編集用にロック付きで取り出されました。ロックがかかったファイルは、他の人は 編集できません。
さて、Makefileをちょっといじって、作成されるオブジェクト名を変更しました。 どういう変更をしたかと言うと
[sakae@nil ~/oreore_lisp]$ rcsdiff Makefile =================================================================== RCS file: RCS/Makefile,v retrieving revision 1.1 diff -r1.1 Makefile 7,9c7,9 < $(CC) -g -o $@ $(SRCS) -l$(LIBS) < test: oreore_lisp < ./oreore_lisp test --- > $(CC) -g -o yuumi3 $(SRCS) -l$(LIBS) > test: yuumi3 > ./yuumi3 test 12c12 < rm -f oreore_lisp --- > rm -f yuumi3
yuumi3の名前にしました。って、慣れないと、読むの大変ですね。
[sakae@nil ~/oreore_lisp]$ ci Makefile RCS/Makefile,v <-- Makefile new revision: 1.2; previous revision: 1.1 enter log message, terminated with single '.' or end of file: >> Change object name >> . done [sakae@nil ~/oreore_lisp]$ ls RCS/ base.lisp oreore_lisp.c yuumi3*
変更が終わったので、また倉庫に仕舞いました。後は、この繰り返しですね。 そんじゃ、遊び方を考えてみますね。