katsujiro
菓子製造販売業の人です。
会社の業務Web scriptingにphpを使っていましたが、いろいろどうにも我慢できずにschemeを始めました。友人にそそのかされた感もありますが。
ここにはMLとかで質問するほどではない、感想とかなんやらを書いていこうと思います。
lambdaのスペルを間違えない程度のスキルです。宜しく御願いします。
- 思いつき日記
- (2006/03/16 17:14:43 PST) AMD64 FreeBSD6.0 でc-wrapperがcore dump
- (2006/02/14 07:29:23 PST) AMD64でFreeBSDでビルド成功
- (2006/02/14 01:02:34 PST) AMD64でFreeBSDでビルド失敗
- (2005/11/19 00:12:58 PST) generic-functionを拡張したい。
- (2005/10/21 07:23:13 PDT) 全角を半角に
- (2005/10/01 10:47:15 PDT) Memo
- (2005/09/12 20:03:01 PDT) regexpの実装
- (2005/09/12 20:03:01 PDT) 角カッコやめた
- (2005/09/06 08:09:11 PDT) bracketを使おう
- (2005/09/02 06:58:17 PDT) GHCは
- (2005/09/01 18:59:50 PDT) #`$"abc $x def"っていう書き方
- (2005/09/01 02:45:37 PDT) #`のunquote
- (2005/09/01 00:30:24 PDT) Schemeqlって
- (2005/08/27 19:36:45 PDT) and-let*の気持ち
- (2005/08/24 07:32:31 PDT) syntax-rulesにはまる
- 雑感
- Memo
思いつき日記
(2006/03/16 17:14:43 PST) AMD64 FreeBSD6.0 でc-wrapperがcore dump
koguroさんのc-wrapperをAMD64 FreeBSD6.0の環境で試してみました。
ビルドは環境変数で
CFLAGS=-fPIC
でなければできませんでした。(-fPICしろとリンカに言われる?)
で、-fPIC(と-g)を付けた状態で、ビルド・インストールしまして、examplesからhello.scmを実行しましたら、
# gosh hello.scm Segmentation fault (core dumped) # cat hellox.scm (use c-wrapper) (c-load-library "libc") (c-include "stdio.h") (define (main args) (let ((fp #?=(fopen "greeting.txt" "w"))) #?=(fprintf fp "Hello, %s?n" "world") #?=(fclose fp)) (printf "greeting.txt is created.?n") 0) # gosh hellox.scm #?="./hellox.scm":7:(fopen "greeting.txt" "w") #?- #<c-ptr:<c-struct:__sFILE> #u8(96 122 246 0 8 0 0 0)> #?="./hellox.scm":8:(fprintf fp "Hello, %s?n" "world") Segmentation fault (core dumped) # !gdb gdb `which gosh` gosh.core GNU gdb 6.1.1 [FreeBSD] Copyright 2004 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "amd64-marcel-freebsd"... Core was generated by `gosh'. Program terminated with signal 11, Segmentation fault. Reading symbols from /usr/local/lib/libgauche.so.0...done. Loaded symbols for /usr/local/lib/libgauche.so.0 Reading symbols from /lib/libcrypt.so.3...done. Loaded symbols for /lib/libcrypt.so.3 Reading symbols from /lib/libutil.so.5...done. Loaded symbols for /lib/libutil.so.5 Reading symbols from /lib/libm.so.4...done. Loaded symbols for /lib/libm.so.4 Reading symbols from /usr/lib/libpthread.so.2...done. Loaded symbols for /usr/lib/libpthread.so.2 Reading symbols from /lib/libc.so.6...done. Loaded symbols for /lib/libc.so.6 Reading symbols from /usr/local/lib/gauche/0.8.7_pre1/amd64-unknown-freebsd6.0/srfi-1-lib.so...done. Loaded symbols for /usr/local/lib/gauche/0.8.7_pre1/amd64-unknown-freebsd6.0/srfi-1-lib.so Reading symbols from /usr/local/lib/gauche/0.8.7_pre1/amd64-unknown-freebsd6.0/srfi-13-lib.so...done. Loaded symbols for /usr/local/lib/gauche/0.8.7_pre1/amd64-unknown-freebsd6.0/srfi-13-lib.so Reading symbols from /usr/local/lib/gauche/0.8.7_pre1/amd64-unknown-freebsd6.0/gauche-hook-lib.so...done. Loaded symbols for /usr/local/lib/gauche/0.8.7_pre1/amd64-unknown-freebsd6.0/gauche-hook-lib.so Reading symbols from /usr/local/lib/gauche/0.8.7_pre1/amd64-unknown-freebsd6.0/gauche-parameter-lib.so...done. Loaded symbols for /usr/local/lib/gauche/0.8.7_pre1/amd64-unknown-freebsd6.0/gauche-parameter-lib.so Reading symbols from /usr/local/lib/gauche/0.8.7_pre1/amd64-unknown-freebsd6.0/gauche-collection-lib.so...done. Loaded symbols for /usr/local/lib/gauche/0.8.7_pre1/amd64-unknown-freebsd6.0/gauche-collection-lib.so Reading symbols from /usr/local/lib/gauche/0.8.7_pre1/amd64-unknown-freebsd6.0/gauche-sequence-lib.so...done. Loaded symbols for /usr/local/lib/gauche/0.8.7_pre1/amd64-unknown-freebsd6.0/gauche-sequence-lib.so Reading symbols from /usr/local/lib/gauche/0.8.7_pre1/amd64-unknown-freebsd6.0/file-util-lib.so...done. Loaded symbols for /usr/local/lib/gauche/0.8.7_pre1/amd64-unknown-freebsd6.0/file-util-lib.so Reading symbols from /usr/local/lib/gauche/0.8.7_pre1/amd64-unknown-freebsd6.0/util-match-lib.so...done. Loaded symbols for /usr/local/lib/gauche/0.8.7_pre1/amd64-unknown-freebsd6.0/util-match-lib.so Reading symbols from /usr/local/lib/gauche/0.8.7_pre1/amd64-unknown-freebsd6.0/libgauche-uvector.so...done. Loaded symbols for /usr/local/lib/gauche/0.8.7_pre1/amd64-unknown-freebsd6.0/libgauche-uvector.so Reading symbols from /usr/local/lib/gauche/site/0.8.7_pre1/amd64-unknown-freebsd6.0/ffi.so...done. Loaded symbols for /usr/local/lib/gauche/site/0.8.7_pre1/amd64-unknown-freebsd6.0/ffi.so Reading symbols from /usr/local/lib/gauche/0.8.7_pre1/amd64-unknown-freebsd6.0/vport.so...done. Loaded symbols for /usr/local/lib/gauche/0.8.7_pre1/amd64-unknown-freebsd6.0/vport.so Reading symbols from /libexec/ld-elf.so.1...done. Loaded symbols for /libexec/ld-elf.so.1 #0 0xffff800800e19cbb in ?? () [New LWP 100130] (gdb) bt #0 0xffff800800e19cbb in ?? () #1 0x000000000050f000 in ?? () #2 0x0000000000000002 in ?? () #3 0x00007fffffffe6f0 in ?? () #4 0x0000000000000001 in ?? () #5 0x0000000000000008 in ?? () #6 0x00000008019c14ed in ffi_call (cif=0x7fffffffe6a8, fn=0x80083df23 <Scm_ModuleClass+3>, rvalue=0x7fffffffe6a8, avalue=0x8006d32b2) at ../../libffi/src/x86/ffi64.c:426 #7 0x00007fffffffe708 in ?? () #8 0x00007fffffffe6f0 in ?? () #9 0x00000008019c14ed in ffi_call (cif=Cannot access memory at address 0xffffffffffffff7a ) at ../../libffi/src/x86/ffi64.c:426 Previous frame inner to this frame (corrupt stack?) (gdb)
libffi自体がfreebsdのportsではコンパイルできないって事になっているし、何か根本的なもんだいが有るのかもしれないなぁと思っております。 とりあえず、経過報告まで。
- koguro(2006/03/17 05:44:25 PST):確認していただきありがとうございます。ただ、すみませんが現在のところlibffiが対応していないのか、それともc-wrapperのバグなのか原因はよく分かりません。ちなみにportsのlibffiは古いもの(1.20)で新しいのはgccの中(gcc-java)に含まれているのですが、portsのgccを見てもamd64環境ではWITHOUT_JAVA=yesとなっているようなので、もしかしたら新しいlibffiでもamd64のFreeBSDでは対応していないのかもしれません。 -katsujiro(2006/03/17 08:15:47 PST)お騒がせしてすみませんが、http://sourceware.org/ml/libffi-discuss/2006/msg00002.html を参考にlibffiを入れ替えたら、とりあえずhello.scmは動くようになりました。ご報告まで。
(2006/02/14 07:29:23 PST) AMD64でFreeBSDでビルド成功
下記の様に失敗していたわけですが、boehm-gc 6.6用のport-buildのパッチを gaucheのソースに入っているgc6.5のソースに適用してからビルドしたところ、 makeに成功。make testもすべて通りました。
$ cd Gauche-0.8.6/gc $ cat /usr/ports/devel/boehm-gc/files/patch* | patch $ cd .. $ make
っていうかんじで。
あー、ホッとした。
お騒がせしました。
(2006/02/14 01:02:34 PST) AMD64でFreeBSDでビルド失敗
AMD64のPCでFreeBSDビルドできないです。boehm gcが対応していないと言われます。 CVS HEADも0.8.6も試しました。boehm gcの同じところでだめでした。
まだ、詳しくは調べていないけど、gc6.6を持ってきてそのままリプレースしてごちょごちょやっても、boehm gcは通りますが、srfi1のコンパイルでcore dumpします。
もうすこし、いじってみます。
追記
gosh.coreの状況
for d in srfi auxsys threads uvector charconv binary net termios fcntl file util sxml syslog dbm mt-random digest vport; do (cd $d; make default); done ../..//src/gauche-config --fixup-extension srfi-1 gcc -DHAVE_CONFIG_H -I. -I../../src -I../../gc/include -g -O2 -fPIC -fomit-frame-pointer -c srfi-1_head.c ../..//src/gosh -ftest gencomp --ext-module srfi-1.scm -o srfi-1-lib ../../libsrc/srfi-1.scm *** Signal 11 Stop in /usr/local/src/gauche/Gauche-0.8.6/ext/srfi. *** Error code 1 Stop in /usr/local/src/gauche/Gauche-0.8.6/ext. *** Error code 1 Stop in /usr/local/src/gauche/Gauche-0.8.6. tatsuki# cd ext/srfi tatsuki# gdb ../../src/gosh gosh.core .... #0 0x00000008006b9600 in Scm_Assq (obj=0x557ea0, alist=0x5fb800) at list.c:496 496 SCM_FOR_EACH(cp,alist) { [New LWP 100176] (gdb) bt #0 0x00000008006b9600 in Scm_Assq (obj=0x557ea0, alist=0x5fb800) at list.c:496 #1 0x00000008006ae4f2 in Scm_VMSlotRef (obj=0x62c960, slot=0x557ea0, boundp=0) at class.c:1241 #2 0x000000080069cc70 in run_loop () at vm.c:2431 #3 0x00000008006a520e in user_eval_inner (program=0x800862140, codevec=0x63d8a0) at vm.c:2869 #4 0x000000080069a572 in Scm_VMEval (expr=0x63d8c0, e=0x6) at vm.c:2791 #5 0x000000080069c739 in run_loop () at vm.c:1615 #6 0x00000008006a520e in user_eval_inner (program=0x800862140, codevec=0x634fa0) at vm.c:2869 #7 0x00000008006dba62 in Scm_Load (cpath=0x557ea0 "?003�?203", flags=0) at load.c:428 #8 0x00000008006dc8aa in Scm_Require (feature=0x56d4b0) at load.c:876 #9 0x00000008006ef8fc in extlib__25require (SCM_FP=0x557ea0, SCM_ARGCNT=0, data_=0x5fb830) at extlib.c:4254 #10 0x00000008006a157b in run_loop () at vm.c:880 #11 0x00000008006a520e in user_eval_inner (program=0x800833440, codevec=0x634fc0) at vm.c:2869 #12 0x000000080069a572 in Scm_VMEval (expr=0x634fe0, e=0x6) at vm.c:2791 #13 0x00000008006db3e5 in load_body (args=0x557ea0, nargs=0, data=0x5eff50) at load.c:162 #14 0x00000008006a157b in run_loop () at vm.c:880 #15 0x00000008006a520e in user_eval_inner (program=0x800833440, codevec=0x5a8020) at vm.c:2869 #16 0x00000008006dba62 in Scm_Load (cpath=0x557ea0 "?003�?203", flags=0) at load.c:428 #17 0x00000000004022ff in main (argc=8, argv=0x7fffffffe918) at main.c:404
- Shiro(2006/02/14 04:42:43 PST): これを見る限りはGC絡みかな。生きているオブジェクトが 回収されて再利用されてしまってるっぽいです。#7のScm_Loadの第一引数 (Cの文字列のはず) と#1のVMSlotRefの第二引数 (ScmObjのはず) が同じアドレスになってますね。
- katsujiro(2006/02/14 06:29:09 PST): boehm-gcはfreebsdのportからパッチの当たった状態の物をもってきて入れ替えました。x86_64ということもあってナイーブなところがあるのでしょうか。とりあえず、現在は追いかける時間がないので…
(2005/11/19 00:12:58 PST) generic-functionを拡張したい。
gaucheのdocumentには
その特定化子リストがジェネリック関数の中のメソッドの一つに 一致するような name 上のメソッドを定義すると、 既存のメソッドは新しく定義されたメソッドに置き換えられます。
と有りますが、置き換えられる前のメソッド(というか、関数)を得たいと思うときは、どうすればよいのかなぁと考えてみる。
「既存のgfの特定の引数パターンのmethodを置き換えるときに、以前のもの得て、その前処理、後処理としたい」っていうようなケースを考えているのですが。
(define-method ++ ((s0 <string>) . rest) (apply string-append s0 rest)) (define-method ++ ((n0 <number>) . rest) (apply + n0 rest)) (print (++ "abc" "def")) ;;; "abcdef" (print (++ 1 2 3)) ;;; 6 ;;;ここまでが既存の定義として (define +++ ++) (define-generic ++) (define-method ++ ((s0 <string>) . rest) (apply +++ s0 s0 rest)) (define-method ++ (a . rest) (apply +++ a rest)) (print (++ "abc" "def")) ;;; 拡張後は"abcabcdef" (print (++ 1 2 3)) ;;; こちらは前の通り6
これで、一応既存の定義をオーバーライドして、以前の定義も使えるのですが、 前の定義を取り出せれば、オーバーヘッドが無くて良いのにと。
ところで、上の続きで
(define-method ++ rest (apply +++ rest)) (print (++ "abc" "def")) ;;; "abcdef" に戻った
っていうのが不思議です。
(2005/10/21 07:23:13 PDT) 全角を半角に
(define (build-zen2han . rest) (define x '((:alpha "A-Za-z" . "A-Za-z") (:num "0-9" . "0-9") (:sym "!”#$%&’()=〜|¥" . "!?"#$%&'()=~|??") (:space " " . " "))) (define (y acc) (fold (lambda (l knil) (cond ((assq l x) => (lambda (p) (string-append (acc p) knil))) (else knil))) "" rest)) (define trns (build-transliterator (y cadr) (y cddr))) (cut with-string-io <> trns))
全角を半角にする手続きを作ります。
っていうのを作ってみました。実行例。
gosh> (define trns (build-zen2han :alpha :num)) trns gosh> (trns "ABCDEFG123456!”#$%") "ABCDEFG123456!”#$%" gosh>
- 用意されていないキーワードが来たときに、無視するようにしてあるが、エラーをとばすべきなんだろうなぁ
- cond =>の先でcutを使いたかったけど、(cut string-append (acc <>) knil)ということはできないんですね。cutから見たトップレベルの<>しか認識していないようで。lib/srfi-16を見てみたけど、よくわかんないや。
- Shiro: cutがトップレベルしか見ないのは、ネストする可能性があるからです。 (cut foo (cut bar <>) <>) みたいな式で内側の<>が外側のcutにとられちゃうと まずい。さらに、(cut foo (baz <>) <>) と書いてあった時に 「bazが実はマクロで (baz <>) は (cut bar <>) に展開される」という 可能性を外側のcut自身は排除できないので、結局内側の<>には触れなくなります。
- katsujiro: cut万能!lambda不要!とか極端なことを考えておりましたが、cutも使いどころをわきまえてということですね。
(2005/10/01 10:47:15 PDT) Memo
すみません、メモ代わりに
(2005/09/12 20:03:01 PDT) regexpの実装
http://chasen.org/~taku/blog/archives/2005/09/post_812.html
TRIEとかAC法とかDFAとか、懐かしいなぁ。
Gaucheにバインド出来ればとおもったけど、C++のヘッダファイル…。 リンク自体はできないことはないだろうけど、どうでしょう。
- Shiro (2005/09/13 04:16:11 PDT) 一応、CVS HEAD の examples/mqueue-cpp にC++ライブラリ へのバインディングの例があります。
(2005/09/12 20:03:01 PDT) 角カッコやめた
vimのschemeモード(っていうか、lispモード)が[に対応してくれてないみたいで、vimのlispモードはハードコーディングしてあって、変更するのが面倒そうで。諦めました。
emacs系はもう、指が忘れて。
(2005/09/06 08:09:11 PDT) bracketを使おう
gaucheでも[ ]を()の替わりに使えることに気がついた。(どこかにドキュメントされてます?)ちゃんと括弧の種類の対応も見てますね。
さーて、どうやって使おうかしらといろいろ試すと、やっぱりなんか違和感があります。 PLT Schemeのライブラリのソースでよく見かけるんだけど、R6RSももうすぐ出てくることだし、もう、標準的な使い方は有るのでしょうか。
有る程度協調したい特殊な部分に使ってみる。例えば、letのバインドみたいなのを
(let ([a 'a][b 'b]) ...) (define-method m ([a <string>] [b <integer>]) ...)
って書き方。見やすいかなぁ。対応はわかりやすいとおもう。 ... 続く
(2005/09/02 06:58:17 PDT) GHCは
Scheme, Gaucheに関係ないけど、Gauche周りにはHaskellの話題も結構あって、GHCという単語が出てくるけど、GHCはGuarded Horn Clausesの略ではないので、毎回ときめいてがっかりするのです。私にとってのHaskellはgoferでした。
(2005/09/01 18:59:50 PDT) #`$"abc $x def"っていう書き方
unquoteを`に続く任意の文字に出来るようにsrc/read.cとsrc/gauche-init.scmとlib/gauche/interpolate.scmを書き換えてみました。ソースがわかりやすいので、書き換えるのも簡単で、動きました。現在動作検証中。なんか、perlみたいな感じで、scheme文化とは相容れない物かも知れません。
- Shiro(2005/09/01 19:15:45 PDT): Gauche的にはそういうのもいいんですが、 #` という表記が
syntactic quasiquote (low-level hygienic macroでquasiquoteのように動作するもの)
としていくつかのマクロ処理系で使われていて、それとバッティングする可能性があるんで
悩ましいところです。もしかするとstring interpolation自体の文法を変えるかもしれません。
- (2005/09/02 01:31:15 PDT)あう、多用しているので、変えるときには今までの文法も使えるようにスイッチを御願いします。
- Shiro(2005/09/02 15:47:55 PDT): 変えるとしても、多分数リリースは併用可能にすると思います。 私自身も使いまくっているので。
diff -rc -x CVS Gauche/lib/gauche/interpolate.scm Gauche.new/lib/gauche/interpolate.scm *** Gauche/lib/gauche/interpolate.scm Thu Apr 21 13:54:28 2005 --- Gauche.new/lib/gauche/interpolate.scm Fri Sep 2 10:59:47 2005 *************** *** 41,62 **** ) (select-module gauche.interpolate) ! (define (string-interpolate str) (if (string? str) ! (%string-interpolate str) (errorf "malformed string-interpolate: ~s" (list 'string-interpolate str))) ) ! (define (%string-interpolate str) (define (accum c acc) (cond ((eof-object? c) (list (get-output-string acc))) ! ((char=? c #?,) (let ((c2 (peek-char))) (cond ((eof-object? c2) (write-char c acc) (accum c2 acc)) ! ((char=? c2 #?,) (write-char (read-char) acc) (accum (read-char) acc)) ! ((char-set-contains? #[?x00-?x20?),?;?[???]?{?}?x7f] c2) (write-char c acc) (accum (read-char) acc)) (else (cons (get-output-string acc) (insert)))))) --- 41,62 ---- ) (select-module gauche.interpolate) ! (define (string-interpolate str . args) (if (string? str) ! (%string-interpolate str (get-optional args #?,)) (errorf "malformed string-interpolate: ~s" (list 'string-interpolate str))) ) ! (define (%string-interpolate str uq) (define (accum c acc) (cond ((eof-object? c) (list (get-output-string acc))) ! ((char=? c uq) (let ((c2 (peek-char))) (cond ((eof-object? c2) (write-char c acc) (accum c2 acc)) ! ((char=? c2 uq) (write-char (read-char) acc) (accum (read-char) acc)) ! ((char-set-contains? #[?x00-?x20?)?;?[???]?{?}?x7f] c2) (write-char c acc) (accum (read-char) acc)) (else (cons (get-output-string acc) (insert)))))) diff -rc -x CVS Gauche/src/gauche-init.scm Gauche.new/src/gauche-init.scm *** Gauche/src/gauche-init.scm Fri Sep 2 10:57:20 2005 --- Gauche.new/src/gauche-init.scm Fri Sep 2 14:30:15 2005 *************** *** 76,80 **** (define <exception> <condition>) ;; backward compatibility (define-reader-ctor 'string-interpolate ! (lambda (s) (string-interpolate s))) ;;lambda is required to delay loading --- 76,80 ---- (define <exception> <condition>) ;; backward compatibility (define-reader-ctor 'string-interpolate ! (lambda s (apply string-interpolate s))) ;;lambda is required to delay loading diff -rc -x CVS Gauche/src/read.c Gauche.new/src/read.c *** Gauche/src/read.c Fri Sep 2 10:57:20 2005 --- Gauche.new/src/read.c Fri Sep 2 10:42:48 2005 *************** *** 446,455 **** case '`': /* #`"..." is a special syntax of #,(string-interpolate "...") */ { ! ScmObj form = read_item(port, ctx); ! return process_sharp_comma(port, ! SCM_SYM_STRING_INTERPOLATE, ! SCM_LIST1(form), ctx, FALSE); } case '?': /* #? - debug directives */ --- 446,459 ---- case '`': /* #`"..." is a special syntax of #,(string-interpolate "...") */ { ! ScmObj form, opt; ! opt = (Scm_PeekcUnsafe(port) != '"') ! ? SCM_LIST1(SCM_MAKE_CHAR(Scm_GetcUnsafe(port))) ! : SCM_NIL; ! form = read_item(port, ctx); ! return process_sharp_comma(port, ! SCM_SYM_STRING_INTERPOLATE, ! Scm_Cons(form, opt), ctx, FALSE); } case '?': /* #? - debug directives */
(2005/09/01 02:45:37 PDT) #`のunquote
quisiquoteと同じく,(comma)になっているというのは納得の出来ることなのですが、SQLとかcsvとかを書いていると、,,,|var|みたいな記述が列んで随分醜くなってしまいます。 sedとかperlとかviみたいに#`$"$|var|, $(upper var2),"ってな書き方でunquoteの文字が帰られると良いなぁと思ったりしまして。 でもまあ、define-reader-ctorにそこまでの機能はないので、gauche.interpolateを書き換えて、
(define-module gauche.interpolate (export string-interpolate *string-interpolate-unquote-ctor*) ) (select-module gauche.interpolate) (define (string-interpolate str) (if (string? str) (%string-interpolate str) (errorf "malformed string-interpolate: ~s" (list 'string-interpolate str))) ) (define *string-interpolate-unquote-ctor* #?,) (define (%string-interpolate str) (define (accum c acc) (cond ((eof-object? c) (list (get-output-string acc))) ((char=? c *string-interpolate-unquote-ctor*) (let ((c2 (peek-char))) (cond ((eof-object? c2) (write-char c acc) (accum c2 acc)) ((char=? c2 *string-interpolate-unquote-ctor*) (write-char (read-char) acc) (accum (read-char) acc)) ((char-set-contains? #[?x00-?x20?),?;?[???]?{?}?x7f] c2) (write-char c acc) (accum (read-char) acc)) (else (cons (get-output-string acc) (insert)))))) (else (write-char c acc) (accum (read-char) acc)))) (define (insert) (let* ((item (with-error-handler (lambda (e) (error "unmatched parenthesis in interpolating string: ~s" str)) (lambda () (read)))) (rest (accum (read-char) (open-output-string)))) (cons `(x->string ,item) rest))) (cons 'string-append (with-input-from-string str (lambda () (accum (read-char) (open-output-string))))) )
こんな感じでダーティーハックしたりして、
(use gauche.interpolate) (set! *string-interpolate-unquote-ctor* #?$) (define x 10) (write #`"abc $x defg") (newline)
$ gosh test.scm "abc 10 defg" $
おお、動く動く。同じファイルの中で書き換えてもダメかと思ったけど、動きますね。 中程の「schemeの式の終了かどうかの条件判断」のあたりでおかしくなりそうだけど、かならず||で囲むことにして、目をつむっちゃって。 まあ、自分で使うだけなら十分ですね。
(2005/09/01 00:30:24 PDT) Schemeqlって
SQLは敷居の高めな言語だと思う。宣言的だったり、関数的だったり、手続き的だったりする。パフォーマンスとか考えるとなおさらだ。でも、SQLには随分慣れました。
Schemeqlのドキュメントを読んでみました。変にいじってわかりにくくしている感が読後に残ります。SQLが染みついているからか、かえって難しくしているように思えます。
gaucheでもschemeqlを使えるようになるパッチを作ってくださったみたいですが、#`でSQL文を構築する方が自分としてはすっきり来るのです。string-appendのパフォーマンスが気になるところですが。
ちょっと大きかったり、自動生成する場合には、tree->stringを便利に使わせてもらってます。
text.html-liteみたいな感じの物を作ればよいのかなとは思っているのですが、S式とSQLとの相性はhtml程はしっくり来ないですね。
(2005/08/27 19:36:45 PDT) and-let*の気持ち
and-letはインデントが深くならず大変便利ですね。知ってからもう、こればっかりです。
;本当は、letで済む束縛だけの部分をand-let*にしてしまうと、コストがかかるんでしょうけど。
;nestが深くなるのが面倒で。
ところで (and-let* (A B C ...) D) とか書いたときに、Dを評価するためにA,B,C...の条件をテストする(あるいは環境を整える)のが本来のand-let*の気持ちなのかなとは思うけど
最近、(and-let* ((a A) (b B) ((not C)) (d D) (e E) ((not F))) Z) という感じでa,bを用意してCを評価して、Cが失敗したらd,eを用意してFを評価し、これも失敗したらZという様な書き方をしてしまう。
多分、and-let*君は不本意なんだろうなと思うのですが。 後々、sourceを見返したときにわかりにくいだろうなとは思うのですが。
- Shiro(2005/08/27 21:58:18 PDT): D, Eの中でa, bを参照していないなら、
私はこういう書き方をよくやります。
(or (and-let* ((a A) (b B)) C) (and-let* ((d D) (e E)) F) Z)
- katsujiro(2005/09/01 00:30:24 PDT): なるほど。やっぱりsourceは意味のわかりやすい書き方をしなければいけないなぁ。
(2005/08/24 07:32:31 PDT) syntax-rulesにはまる
書き換え後の表現は1つでなければいけないということに気がつかず、 (syntax-rules () ((_ x y) (define x 1) (define y 2)))って感じで書いて、はまる。 (syntax-rules () ((_ x y) (begin (define x 1) (define y 2))))とbeginでくくってしまえば良いわけだけど、今までトップレベルのdefineに展開したこと無かったので、こういう書き方自体考えなかったです。
ついでに。与えられたシンボルをクオートするのにはquoteを、文字列にするのにはそれをさらにsymbol->stringで変換してやればOK。はじめてquoteを使った。今までRnRSで見かけてきたのに、使ったこと無かったので、新鮮な気持ち。
雑感
dbi/dbd.pg
(Shiro: Gauche:DBI/DBDへ移動します。)
(use pg)
http://maruska.dyndns.org/comp/activity/scheme/gauche/pg/
のpgモジュールを使っていますが、dbi/dbdが主流なのでしょうか、あまり使われているのを見かけませんね。
pq_fnameとか使いたいので使っているという程度ですが。
- 0.8.6のdbiは随分いろいろ拡張されていて、使いやすそうですね。dbd-pgがCVSになくてまだ試せてませんが。(2005/09/02 01:31:15 PDT)
- Shiro(2005/09/02 15:47:55 PDT): dbd.pgはKahuaプロジェクトの方でやっています。 さきほどlibpqのほとんどのAPIに対応したものをcommitしました。 http://www.kahua.org/cgi-bin/viewcvs.cgi/kahua/Gauche-dbd-pg/ もっとも、0.8.6のAPIにまだ変動の可能性があり、それにつれてこちらのコードも 変わるので、試す場合は御注意下さい。
PHPは
- phpも使い込んだと言うほどではないですが、php5になって、ライブラリ周りもOOPっぽくなってきて、いろいろ面倒になって嫌気が差したと言うことはあります。(2005/08/22 20:20:59 PDT)
- mod_phpもcgiでも起動が早いのは魅力的なんですが。(2005/08/22 20:20:59 PDT)
- つい連想記憶を使ってしまうのですが、最適ではなかったと思います。扱われているデータの型がはっきりしないのも、便利なようで不便。勝手な型変換はバグの温床。(2005/08/22 20:20:59 PDT)
使っていて
- phpでやってたみたいにPOSTもGETも両方使いたくて、cgi-mainの中でparameterizeでMETHODをGETにしてGETパラメータを読み出して使うということもしていましたが、結局cgi-main自体を変更して使っているということがあります。モジュールをextend出来るのは便利ですね。(2005/08/22 20:19:09 PDT)
- moduleを書くときに、いきなり(export-all)してしまっています。一人でやってますし、だれかに見せようとして書いているわけではないので、それで不便はないのですが、(export-all except やっぱり見せたくないシンボル)みたいな書き方が出来ると便利よねと思ったりします。(2005/08/22 20:19:09 PDT)
Memo
gauche.logger
log-openは<log-drain>を返します。しかし、呼び出した時点で"現在の"ログドレインも、変更されます。
log-openを呼び出す以外に"現在の"ログ出力デフォルトを変更する方法はありません。 with-*とかcall-*みたいな形は?
まあ結局、自前のwrapperを噛ませることでとりあえず運用ですか。
- Shiro(2005/08/22 11:38:08 PDT): そうかぁ。デフォルトのログ出力はアプリケーションの
開始時に一度だけセットして、途中で切替えて使うような用途は考えていませんでした。
複数のログを出したければ自分で<log-drain>を作って明示的にlog-formatに
渡してもらう、というのがもともとの意図。ただ、外部ライブラリでデフォルト出力の
log-formatが使われてる場合にそこだけ行き先を振り替えたい、という要望は
あるかもしれんですね。
デフォルトのログ出力先をparameterにしてexportしときます。
そうすればparameterizeで切替えられるし。
- katsujiro(2005/08/22 20:19:09 PDT): やぁさっそくありがとうございます。parameterizeできれば、十分です。