Gauche:Bugs:log3
最新のもの:Gauche:Bugs
- quote、quasiquote(0.8.1)
- マニュアル(reduce)
- mingw-compat.hがインストールされない (0.8.1)
- src/Makefile.inのINSTALL_BINS (0.8.1)
- syntax-rules内のlet-keywords*(0.8.1)
- date->julian-dayがzone-offsetを解さない(0.8.1)
- マニュアルの誤植 (0.8.1)
- directory-listでfilter-add-path?を指定するとchildren?が無効に(0.8.1)
- マニュアルの間違い (0.8.1)
- C++予約語 template がgauche.hに入っている (0.8.1)
- マニュアルの不整合(bit-field)(0.8.1)
- rfc.822のrfc822-parse-dateが一月ずれる(0.8.1)
- コンパイラの警告(0.8.1-newgc)
- roundeven in number.c(0.8.1)
- rational?(0.8.1)
- (symbol-bound? 'syntax-rules) => #f (0.8.1)
- マニュアルのタイポ(0.8.1)
- gauche.arrayに未exportなクラス(0.8.1)
- getter-with-setterでsetterがロックされない(0.8.1)
- regexp-replace-allで文字列の最初を置換すると無限ループ(0.8.1)
- Cで書かれたクラスのwrite-object
- libgaucheのSONAME
- util.matchのorの挙動について
- Typo (CVS_HEAD)
- sys-glob (0.8)
- Scm_FindBinding (0.8)
- Typo in fetch.scm (0.8)
- マクロ内のcase(0.8)
- multibyte string の判定 (0.8)
- 複素数で,複数の引数がある場合の割り算(0.8)
- gauche-cesconv の help (0.8)
- カレントモジュールでの apropos (0.8)
- 割り算(0.8)
- quote内のvectorの展開(0.8)
- defineと内部define (0.7.4.2とか0.8とか)
- SRFI-13 の string-take-right, string-drop-right の例 (0.8)
- macroexpandを実行してもマクロがautoloadされない(0.7.4.1, 0.8)
quote、quasiquote(0.8.1)
結果が、長さ ちょうど2のリストになるような式で、そのリストの先頭に quoteかquasiquoteをシンボルとして入れようとすると、 おかしなことになってしまいます。(2004/11/26 22:27:11 PST)
(list 'quote 'quasiquote) ;; => 'quasiquote (list 'quasiquote 'quote) ;; => `quote (cons 'quote '(hoge)) ;; => 'hoge
- Shiro: 'hoge は (quote hoge) の略記、`hoge は (quasiquote hoge) の 略記です。出力時にもそのように変換されますが、あくまで表記上のもので、 内部的には(quote hoge)、(quasiquote hoge)のようなリストになっています。 というわけで別におかしくはありません。
- R5RSのP.9に
'(quote a) => (quote a) ''a => (quote a)
とあったので、このように"quote"を含んだ表記でかえってくるものと 思っていました。確かに、(car ''quote) ;; => quote
となり何の問題もなかったです。失礼いたしました。(2004/11/27 02:00:49 PST)
マニュアル(reduce)
GaucheRefj:reduceの使い方がよくわからなかったので、 SRFI 1のreduceの説明を 見てみたのですが、引数ridentityは「(f x ridentity) == ridentity」ではなく、 「(f x ridentity) == x」ではないでしょうか。
また、fの適用を省略するのは、「ひとつしか要素をもたない場合」ではなく、listが空の場合ではないでしょうか。(2004/11/20 04:24:29 PST)
- Shiro(2004/11/20 13:10:58 PST): ご指摘のとおりです。直しておきます。
mingw-compat.hがインストールされない (0.8.1)
MinGWではgauche.hからインクルードされますが、インストールされません。 src/Makefile.inのINSTALL_SUBHEADERSに追加するのだと思いますが。
それから、mingw-compat.hではgid_t, uid_tをtypedefしていますが、 MinGWにそれらが存在しないことを知っている他のライブラリではこれらを #defineしている場合があり、そちらを先に#includeしているとエラーになります。 そこで、typedefを #ifndef uid_t〜#endif, #ifndef gid_t〜#endif で囲んでもらえないでしょうか。
- Shiro(2004/11/21 16:37:42 PST): 直しときました。
src/Makefile.inのINSTALL_BINS (0.8.1)
MinGWでビルドできるようになってて嬉しいです。 一箇所、EXEEXTのつけ忘れを発見しました。 (2004/11/12 12:47:28 PST)
--- src/Makefile.in.orig Mon Sep 20 21:16:39 2004 +++ src/Makefile.in Sat Nov 13 05:34:39 2004 @@ -93,7 +93,7 @@ gauche/builtin-syms.h \ gauche/pthread.h gauche/uthread.h gauche/arch.h INSTALL_LIBS = libgauche.$(SOEXT) -INSTALL_BINS = gosh gauche-config gauche-install gauche-package \ +INSTALL_BINS = gosh$(EXEEXT) gauche-config gauche-install gauche-package \ gauche-cesconv INSTALL_SCMS = gauche-init.scm genstub cesconv
ところでつくったgoshを使って後の処理をしていますが、クロスコンパイルだと当然うごかないので困ってしまいます。ホスト環境(UNIX)のgoshを使うようにMakefileの変数を変えてやってしまいましたが、問題ないでしょうか? 問題なければ、できればホスト環境のgoshを代わりに使うようなconfigureオプションを追加してもらえると嬉しいです。
- Shiro(2004/11/12 14:00:17 PST): あっどうも。有難いです。 「ホスト環境のgoshを使うように」とは、変数GOSHを/usr/local/bin/goshとかに してやったということですか?
- そうです。変数GOSHを手で変更しました。 (2004/11/12 14:31:55 PST)
- Shiro: それだけでOKということは、make GOSH=/usr/local/bin/gosh で ビルドすれば通りますかね。それとも置き換えちゃまずいGOSHがありました? ぱっと考えると無さそうだけど。
- grepすると下のようになり、make GOSH=〜でそのままは通らなさそうです。
% egrep '^GOSH[ ]*=' **/Makefile* doc/Makefile.in:GOSH = ../src/gosh -q -I../src -I../lib -lgauche-init examples/spigot/Makefile.in:GOSH = @GOSH@ ext/Makefile.ext.in:GOSH = $(top_builddir)/src/gosh -ftest
心配だったのはビルド中にgoshからランタイム環境の情報を得て使用していたりするとクロスビルドではなんともならなかったりするかも、と思ったためなのですが、goshはビルド手順の制御に使われているだけと思っていいのでしょうか?
- Shiro: 色々付いてるオプションはビルド中のGaucheのSchemeライブラリを 参照させるためのものなので、同じバージョンのGaucheがホストにインストール されている限り、make GOSH=... でいけるんじゃないかと思います。 ランタイム環境の取得にはビルドツリー中のgauche-configを呼んでいるはず ですが、気をつけて見直しておきます。
- 失礼しました。実際に試したところ make GOSH=/usr/local/bin/goshで ビルドもインストールも成功しました。
syntax-rules内のlet-keywords*(0.8.1)
syntax-rules内でlet-keywords*がうまく動いてくれません。(2004/11/08 21:47:13 PST)
--- Gauche-0.8.1.orig/lib/gauche/procedure.scm 2004-08-03 06:50:47.000000000 +0900 +++ Gauche-0.8.1/lib/gauche/procedure.scm 2004-11-09 13:54:45.000000000 +0900 @@ -134,11 +134,11 @@ (var (unwrap-syntax (car var&default))) ((symbol? var))) (case (length var&default) - ((2) `(,var + ((2) `(,(car var&default) ,(make-keyword var) ,(cadr var&default))) - ((3) `(,var ,(unwrap-syntax (cadr var&default)) + ((3) `(,(car var&default) ,(unwrap-syntax (cadr var&default)) ,(caddr var&default))) (else #f))) (error "bad binding form in let-keywords*" var&default))) vars)))
- Shiro (2004/11/11 23:34:31 PST): 直しました。
date->julian-dayがzone-offsetを解さない(0.8.1)
下のコードがゼロになって欲しいところです。
(use srfi-19) (let1 jd (current-julian-day) (- jd (date->julian-day (julian-day->date jd))))
こんな感じでしょうか。(2004/10/27 13:28:39 PDT)
--- Gauche-0.8.1.orig/lib/srfi-19.scm 2004-08-03 06:50:47.000000000 +0900 +++ Gauche-0.8.1/lib/srfi-19.scm 2004-10-28 05:17:16.000000000 +0900 @@ -655,13 +655,15 @@ (hour (date-hour date)) (day (date-day date)) (month (date-month date)) - (year (date-year date)) ) + (year (date-year date)) + (offset (date-zone-offset date)) ) (+ (tm:encode-julian-day-number day month year) (- 1/2) (+ (/ (+ (* hour 60 60) (* minute 60) second - (/ nanosecond tm:nano)) + (/ nanosecond tm:nano) + (- offset)) tm:sid))))) (define (date->modified-julian-day date)
- Shiro(2004/11/01 13:54:30 PST): 直しました。
マニュアルの誤植 (0.8.1)
誤植をみつけたので報告します。文字列関連で"less than"を"以下"としてしまっているところ、sortの説明がおかしいところのふたつです。(2004/10/20 08:54:12 PDT)
--- Gauche-0.8.1.orig/doc/corelib.texi 2004-08-03 06:50:46.000000000 +0900 +++ Gauche-0.8.1/doc/corelib.texi 2004-10-21 00:38:15.000000000 +0900 @@ -2830,7 +2830,7 @@ @c JP (多分、不完全な)文字列@var{string}の@var{k番目}のバイトを返します。 戻り値は、0から255の範囲の整数です。@var{k}は0以上、 -@code{(string-size @var{string})}以下でなければなりません。 +@code{(string-size @var{string})}より小でなければなりません。 @c COMMON @end defun @@ -2847,7 +2847,7 @@ See the notes in @code{make-string} about performance consideration. @c JP [R5RS] @var{string}の@var{k}番目の文字を@var{char}で置き換えます。 -@var{k}は0以上、@code{(string-length @var{string})}以下でなければ +@var{k}は0以上、@code{(string-length @var{string})}より小でなければ なりません。戻り値は未定義です。 @var{string}が不完全文字列の場合、@var{char}の下位8ビットの整数値は、 @@ -2869,7 +2869,7 @@ @c JP @var{string}の@var{k}番目のバイトを整数@var{byte}で置き換えます。 @var{byte}は0から255の範囲(255を含む)でなければなりません。 -@var{k}は0以上、@code{(string-size @var{string})}以下である必要があります。 +@var{k}は0以上、@code{(string-size @var{string})}より小である必要があります。 @var{string}が完全文字列の場合、この操作により不完全文字列になります。 戻り値は未定義です。 @c COMMON @@ -8966,15 +8966,15 @@ in ascending order and returns the sorted sequence. @code{sort!} destructively reuses the original sequence. The sorting order is specified by @code{cmpfn}, which is -a procedure takes two elements of @var{list}, and returns @code{#t} +a procedure takes two elements of @var{seq}, and returns @code{#t} if the first argument strictly precedes the second. @c JP シーケンス@var{seq}(リストかベクタ)の要素を昇順にソートし、 ソートされたシーケンスを返します。 @code{sort!}は、オリジナルのシーケンスを破壊的に再利用します。 -ソート順は@code{cmpfn}で指定されます。@code{cmpfn}は2要素の@var{list}を +ソート順は@code{cmpfn}で指定されます。@code{cmpfn}は@var{seq}のふたつの要素を 引数に取り、最初の要素が厳密に2番目の要素より先行するものの場合は -@code{#f}を返す手続きです。 +@code{#t}を返す手続きです。 @c COMMON @example
- Shiro(2004/11/01 13:54:30 PST): 直しときます。
directory-listでfilter-add-path?を指定するとchildren?が無効に(0.8.1)
filter-add-path?を指定すると、children?を#tにしても返り値に"."と".."が含まれてしまいます。(2004/10/19 23:55:14 PDT)
(use file.util) (directory-list "/home" :children? #t :filter identity :filter-add-path? #t)
- Shiro(2004/11/01 13:54:30 PST): 直しました。
マニュアルの間違い (0.8.1)
GaucheRefj:define-classにおける:allocationオプションの説明と実装に食い違いがあります。
マニュアルには、「スロットアロケーションが virtualと指定されていれば、`:slot-ref' および `:slot-set!'オプションが同様に指定されていなければなりません。さもなければ、`define-class'は エラーを発生させます。」とあります。しかし実際には、:slot-set!オプションは指定する必要はなく、必須なのは:slot-refのみです。マニュアルの間違いではないでしょうか。
同様の記述は、同じページの下のほうの:slot-set!の説明にもあります。(2004/10/17 23:38:21 PDT)
- Shiro (2004/10/17 23:48:04 PDT): 昔はSTk由来で両方必須だったのを、途中でrefだけで いいように変えたんですが、マニュアルを直してなかったようです。 直しておきます。
C++予約語 template がgauche.hに入っている (0.8.1)
*** /Users/nel/Software/gauche/Gauche/src/gauche.h Wed Oct 13 14:35:14 2004 --- gauche.h Wed Oct 13 14:29:16 2004 *************** *** 2447,2453 **** #endif /*!HAVE_SELECT*/ /* other stuff */ ! SCM_EXTERN ScmObj Scm_SysMkstemp(ScmString *template); /*--------------------------------------------------- * LOAD AND DYNAMIC LINK --- 2447,2453 ---- #endif /*!HAVE_SELECT*/ /* other stuff */ ! SCM_EXTERN ScmObj Scm_SysMkstemp(ScmString *temp); /*--------------------------------------------------- * LOAD AND DYNAMIC LINK
- Shiro(2004/10/13 01:26:21 PDT): 直しました。
マニュアルの不整合(bit-field)(0.8.1)
GaucheRefj:bit-fieldの説明でのインデックスの数えかたが、前後の手続きの説明での数えかたと異なっています。bit-fieldの説明では最初のビットを1番目と数えていますが、logbit?などでは0番目としています。「整数nのstart+1ビット目からendビット目(両端含む)までを」は「整数nのstartビット目(含む)からendビット目(含まない)までを」としたほうがわかりやすいのではないでしょうか。(2004/10/04 11:38:40 PDT)
- Shiro(2004/10/06 02:07:02 PDT): 直しときました。
rfc.822のrfc822-parse-dateが一月ずれる(0.8.1)
コレが正しい?何か間違ってたらすいません(2004/09/30 14:23:03 PDT)
--- 822.scm.orig 2004-10-01 06:12:06.000000000 +0900 +++ 822.scm 2004-10-01 06:19:07.000000000 +0900 @@ -196,9 +196,10 @@ (list-index (cut string=? <> dow) '("Sun" "Mon" "Tue" "Wed" "Thu" "Fri" "Sat"))) (define (mon->number mon) - (list-index (cut string=? <> mon) - '("Jan" "Feb" "Mar" "Apr" "May" "Jun" - "Jul" "Aug" "Sep" "Oct" "Nov" "Dec"))) + (+ 1 + (list-index (cut string=? <> mon) + '("Jan" "Feb" "Mar" "Apr" "May" "Jun" + "Jul" "Aug" "Sep" "Oct" "Nov" "Dec")))) (define (year->number year) ;; see obs-year definition of RFC2822 (let ((y (string->number year))) (and y
- Shiro(2004/09/30 17:32:23 PDT): あっそうですね。<sys-tm>での月表記と 混同していたようです。<date>の方にあわせます。
コンパイラの警告(0.8.1-newgc)
guess.cをコンパイルすると、型の不一致によりgccが警告を出力します。具体的にどこが不一致なのか正直わからないのですが、以下のように素直に書くと警告は出ません。
--- ext/charconv/guess.c 14 Mar 2004 05:30:37 -0000 1.3 +++ ext/charconv/guess.c 20 Sep 2004 18:58:34 -0000 @@ -43,20 +43,20 @@ } guess_arc; typedef struct guess_dfa_rec { - signed char (*states)[][256]; + signed char (*states)[256]; guess_arc *arcs; int state; double score; } guess_dfa; #define DFA_INIT(st, ar) ? - { &st, ar, 0, 1.0 } + { st, ar, 0, 1.0 } #define DFA_NEXT(dfa, ch) ? do { ? int arc__; ? if (dfa.state >= 0) { ? - arc__ = (*dfa.states)[dfa.state][ch]; ? + arc__ = dfa.states[dfa.state][ch]; ? if (arc__ < 0) { ? dfa.state = -1; ? } else { ?
(2004/09/26 02:55:28 PDT) なぜ警告されるのかを調べてみました。 型の不一致の警告が出ているのは以下の行です(マクロは展開)。
guess_dfa eucj = { &guess_eucj_st, guess_eucj_ar, 0, 1.0 };
guess_eucj_ar以降の初期化子は警告の原因になっていないので、ここではguess_eucj_stのみに注目します。
まず初期化するほうのguess_eucj_stの型は、「signed charの配列256の配列4」です。(定義では、guess_eucj_st[][256]というように不完全な配列として定義されていますが、「不完全な配列型のオブジェクトの型は、(略)それを初期化することによって(略)、完全なものとなる」(K&R付録A8.6.2)ことにより、guess_eucj_stは長さの指定された完全な型になります。) したがって&guess_eucj_stの型は、「signed charの配列256の配列4へのポインタ」です。&をつけずにguess_eucj_stと書いたとき、それが配列の最初の要素へのポインタすなわち「signed charの配列256へのポインタ」になることとの違いに注意してください。
そして初期化されるほうですが、構造体guess_dfaの最初のメンバstatesは「signed char (*states)[][256]」と宣言されており、その型は「signed charの配列256の不完全な配列へのポインタ」です。
- signed charの配列256の配列4へのポインタ
- signed charの配列256の不完全な配列へのポインタ
この違いが警告の原因です。
初期値式の値はオブジェクトに代入するのに適当な型でなければならず、代入演算子では、「両被演算数が関数あるいはオブジェクトへのポインタで、このオブジェクトは右被演算数にconstあるいはvolatileがないこともある点を除けば、その型が同じ」(A7.17)でなければなりません。「型が同じ」であるためには、「配列のサイズ(略)も一致する必要がある」(A8.10)。したがって上記の違いは許されず、警告が出力されるというわけです。
guess_sjis_st, guess_utf8_stも同様です。
- Shiro(2004/11/01 14:39:06 PST): ありがとうございます。直しておきました。 そもそも何故最初にあのような型にしたのか思い出せないんですが、 素直に256の塊へのポインタとしておけば良かったわけですね。
roundeven in number.c(0.8.1)
困っているわけではありませんが、こうなのかなと思いました。(2004/09/17 06:41:11 PDT)
--- Gauche-0.8.1.orig/src/number.c 2004-08-03 06:50:47.000000000 +0900 +++ Gauche-0.8.1/src/number.c 2004-09-17 22:25:13.000000000 +0900 @@ -1655,12 +1655,12 @@ if (v > 0.0) { if (frac > 0.5) r += 1.0; else if (frac == 0.5) { - if (r/2.0 != 0.0) r += 1.0; + if (fmod(r, 2.0) != 0.0) r += 1.0; } } else { if (frac < -0.5) r -= 1.0; - else if (frac == 0.5) { - if (r/2.0 != 0.0) r -= 1.0; + else if (frac == -0.5) { + if (fmod(r, 2.0) != 0.0) r -= 1.0; } } return r;
- Shiro: そうですね。直しておきます。
rational?(0.8.1)
有理数を判定するところが、実数の判定になってしまっています。まだ有理数のサポートはなく、マニュアルに有理数の集合と整数の集合は同一とあるので、integer?の中身をコピペしてみました↓。(2004/09/11 20:34:26 PDT)
--- Gauche-0.8.1.orig/src/stdlib.stub 2004-08-03 06:50:47.000000000 +0900 +++ Gauche-0.8.1/src/stdlib.stub 2004-09-12 12:18:53.000000000 +0900 @@ -66,7 +66,9 @@ (define-cproc number? (obj) (return <boolean> "SCM_NUMBERP")) (define-cproc complex? (obj) (return <boolean> "SCM_NUMBERP")) (define-cproc real? (obj) (return <boolean> "SCM_REALP")) -(define-cproc rational? (obj) (return <boolean> "SCM_REALP")) +(define-cproc rational? (obj) + " if (!SCM_NUMBERP(obj)) SCM_RETURN(SCM_FALSE); + else SCM_RETURN(SCM_MAKE_BOOL(Scm_IntegerP(obj)));") (define-cproc integer? (obj) " if (!SCM_NUMBERP(obj)) SCM_RETURN(SCM_FALSE); else SCM_RETURN(SCM_MAKE_BOOL(Scm_IntegerP(obj)));")
- Shiro(2004/09/13 13:36:29 PDT): これは微妙なところです。
'real' の表現が有限長浮動小数点数である以上、'real' で表現可能な
値は有理数でも表現可能です (infinity, nanはとりあえず置いといて)。
R5RSの6.2.5節に次のような注記があります。
Note: In many implementations the rational? procedure will be the same as real?, and the complex? procedure will be the same as number?, but unusual implementations may be able to represent some irrational numbers exactly or may extend the number system to support some kind of non-complex numbers.
- なるほど。了解しました。GaucheRefj:数値に関する述語の「有理数の集合は整数の集合と同一です」とあるところは消去したほうがわかりやすいかと思います。ありがとうございました。(2004/09/13 18:26:43 PDT)
- Shiro(2004/09/13 20:11:29 PDT): 確かにマニュアルの記述は良くないですね。 直しておきます。
(symbol-bound? 'syntax-rules) => #f (0.8.1)
問題がおきているわけではありませんが、気になったもので。(2004/09/06 14:19:53 PDT)
と、書いたものの、R5RSではsyntax-rulesそのものがシンタックスであるとは書いていないのか。とすると、Gaucheでsyntax-rulesが#<syntax syntax-rules>と評価されなくてもいいわけですね。すみませんでした(あ、でも%syntax-rulesというのは評価できるなあ。)いったいsyntax-rulesって何なんでしょうか。(2004/09/06 18:03:11 PDT)
(symbol-bound? 'syntax-rules) ;; => #f
- Shiro (2004/09/13 13:36:29 PDT): これは、そういうものです。R5RSの範囲では (syntax-rules ...) だけの独立した意味は決められていないので、 caseやcond構文の'else'のようなキーワードとして扱うことも、実装者の裁量で 許されています。もっとも、(syntax-rules ...) が何らかのfirst class object を返すような実装も面白そうですが。
マニュアルのタイポ(0.8.1)
リファレンスマニュアル内cuteの例に括弧の対応がおかしくなっている箇所があったので報告しておきます(2004/09/05 20:46:15 PDT)。
- Shiro (2004/09/13 13:36:29 PDT): 直しときました。
gauche.arrayに未exportなクラス(0.8.1)
gauche.arrayを使おうとして、いくつかのクラスがexportされていないのに気づい たので報告します。あと、クラスの定義が重なっている部分があったのでそれもついでに 削っています。(2004/09/02 13:40:41 PDT)
- Shiro (2004/09/13 13:36:29 PDT): 直しときました。
getter-with-setterでsetterがロックされない(0.8.1)
マニュアルではgetter-with-setterはsetterをロックするとあるのですが、下のコードがエラーになってくれません。直すにはgauche-init.scm内のgetter-with-setterをCレベルまでもっていかなくてはいけないのでしょうか。(2004/08/25 04:19:57 PDT)
(define cdr2 (getter-with-setter cdr set-cdr!)) (set! (setter cdr2) set-car!)
- Shiro (2004/09/13 17:29:39 PDT): これは手抜きです。setterをロックする操作をCから Schemeに見せるか、getter-with-setter自体をCで書けば良いんですが。 マニュアルとの不整合は気になりますね。ちょっと考えてみます。
regexp-replace-allで文字列の最初を置換すると無限ループ(0.8.1)
そんなことするなよっていわれちゃいそうですが。無限ループにはいってしまいました。(2004/08/20 02:34:40 PDT)
(use gauche.regexp) (regexp-replace-all #/^/ "some string" "any string")
- Shiro (2004/09/13 13:36:29 PDT): こういうケースはエラーとするようにしました。
- エラーが出ることを確認しました。ありがとうございます。とても瑣末なことなのですが、関連したところでおかしな動きをみつけました。
(regexp-replace-all #/^1/ "111" "2")
のようにした場合、予期するものと異なる結果がかえってきます。(2004/09/13 19:09:02 PDT) - Shiro: そうか… regexp-replace-allが現在は「一致した文字列以降の 部分に関して再帰的にregexp-replace-allを適用する」となっているからですね。 今の動作のまま、セマンティクスを明記しておくのでも良いかと思うのですが、 この動作で何か困ることはあるでしょうか?
- 私もそのような修正で充分だと思います。Emacsで正規表現を学んだために、"^"は改行のあとにもマッチするのかと思っていました。その勘違いからregexp-replace-allに"^"を渡してしまっただけで、ちゃんとマニュアルを読んで使えば困ることはないと思います。
Cで書かれたクラスのwrite-object
例えば以下のようなwrite-objectを書いても、(write (current-time))は意図したようには動作せず、#<time-utc 1092983327.991697000>といった出力のままとなります。
(define-method write-object ((t <time>) port) (format port "#,(<time> ~s ~s ~s ~s ~s ~s)" :type (ref t 'type) :second (ref t 'second) :nanosecond (ref t 'nanosecond)))
当たり前ですが、(write-object (current-time) (current-output-port))とすれば意図通り#,(<time> :type time-utc :second 1092983274 :nanosecond 878720000)といった出力になります。 これはこういうものなのでしょうか。 ; 読み込み時コンストラクタも併せて書いて、<time>を読み書きしたかったのです。
Shiro (2004/08/20 02:10:53 PDT): 現状では、そういうものです。 writeに限らず、現在のgaucheでは、システム組み込みの型に関しては 動作が固定されており、ユーザ定義型に関してはgeneric functionを使って ディスパッチする、というものがいくつかあります。(hash vs object-hash, equal? vs object-equal? 等)。OO界にあわせるなら全てをgeneric functionに した方が綺麗なのですが(GOOはそういう方針だったと思います、確か)、 そうすると何をするにもメソッドディスパッチが入り、性能面だけでなく いろんなところに問題を引き起こすので。
ただ、この例のようにwriteをカスタマイズしたいという要求は よくあります。writeのユーザ定義メソッドを呼ぶ際に、再帰的に呼ばれる writerも渡して行くようにすればうまくいくかなと思っています。 名前もwrite-objectからobject-writeに変えたいし (前者はSTk由来なんですが、 今ではobject-xxxという名前の方で統一しつつあるので)。
libgaucheのSONAME
Debianのパッケージを作っていて見つけたのですが、libgauche.so.0.x.xにSONAMEがありません(Debianではusr/libにインストールされる.soにSONAMEがないと、パッケージチェッカに怒られてしまうのです)。DebianにおけるSONAMEはhttp://www.netfort.gr.jp/~dancer/column/libpkg-guide/libpkg-guide.html が参考になると思います。(2004/08/11 08:29:50 PDT)
- Shiro (2004/08/20 02:10:53 PDT): 直しました。
util.matchのorの挙動について
(A)も(B)'aが返ることを期待したのですが、(B)は'bが返ります。 これはどちらも'aを返すべきですよね? (2004/07/28 16:30:58 PDT)
(use util.match) ;;(A) (match '(:key 1 "hoge" 2 "fuga") [ ((? keyword?) (or (? string?) (? number?) ) ...) 'a] [ ((? keyword?) (? (lambda (x) (or (string? x) (number? x)))) ...) 'b] ) ;=> a ;;(B) (match '((:key 1 "hoge" 2 "fuga") (:key2 1 "hoge" 2 "fuga")) [(((? keyword?) (or (? string?) (? number?) ) ...) ...) 'a] [(((? keyword?) (? (lambda (x) (or (string? x) (number? x)))) ...) ...) 'b] ) ;=> b
- Shiro(2004/07/28 16:00:00 PDT): util.matchのバグでした。
--- lib/util/match.scm 14 May 2004 01:41:00 -0000 1.3 +++ lib/util/match.scm 28 Jul 2004 22:58:50 -0000 @@ -740,7 +740,8 @@ (cond ((eq? (car p) '_) (ks sf)) ((null? bound) - (let* ((ptst (next (car p) eta sf + (let* ((eta (gensym)) + (ptst (next (car p) eta sf (lambda (sf) #f) (lambda (sf) #t))) (tst (if (and (pair? ptst)
Typo (CVS_HEAD)
単なるタイポだと思いますが。(2004/07/27 21:03:06 PDT)
Index: lib/srfi-0.scm =================================================================== RCS file: /cvsroot/gauche/Gauche/lib/srfi-0.scm,v retrieving revision 1.21 diff -u -r1.21 srfi-0.scm --- lib/srfi-0.scm 26 Jul 2004 09:51:41 -0000 1.21 +++ lib/srfi-0.scm 28 Jul 2004 03:58:18 -0000 @@ -37,7 +37,7 @@ '((srfi-0) (srfi-1 srfi-1) (srfi-2 srfi-2) - (srfi-4 gauche.vector) + (srfi-4 gauche.uvector) (srfi-5 srfi-5) (srfi-6) (srfi-7) Index: src/load.c =================================================================== RCS file: /cvsroot/gauche/Gauche/src/load.c,v retrieving revision 1.90 diff -u -r1.90 load.c --- src/load.c 26 Jul 2004 09:51:41 -0000 1.90 +++ src/load.c 28 Jul 2004 03:58:19 -0000 @@ -1088,7 +1088,7 @@ SCM_APPEND1(init_cond_features, t, SCM_LIST1(SCM_SYM_GAUCHE_EUCJP)); #elif defined(GAUCHE_CHAR_ENCODING_SJIS) SCM_APPEND1(init_cond_features, t, SCM_LIST1(SCM_SYM_GAUCHE_SJIS)); -#elif defnied(GAUCHE_CHAR_ENCODING_UTF8) +#elif defined(GAUCHE_CHAR_ENCODING_UTF8) SCM_APPEND1(init_cond_features, t, SCM_LIST1(SCM_SYM_GAUCHE_UTF8)); #else SCM_APPEND1(init_cond_features, t, SCM_LIST1(SCM_SYM_GAUCHE_NONE));
- Shiro: ども。直しておきました。
sys-glob (0.8)
POSIXによると、gl_pathcとgl_pathvはglobが失敗したときでも意味をもち、それによりglobは部分的な結果を返すことができるとなっています。したがってエラー時にもglobfreeする必要がありますが、現在のGaucheはそれを行っていません。以下はそれを修正するパッチです。(2004/07/26 21:47:38 PDT)
--- src/system.c 21 Jul 2004 07:25:17 -0000 1.59 +++ src/system.c 27 Jul 2004 05:04:10 -0000 @@ -191,12 +191,13 @@ ScmObj head = SCM_NIL, tail = SCM_NIL; int i, r; SCM_SYSCALL(r, glob(Scm_GetStringConst(pattern), 0, NULL, &globbed)); + if (r) { + globfree(&globbed); #ifdef GLOB_NOMATCH - if (r == GLOB_NOMATCH) return SCM_NIL; -#else /*!GLOB_NOMATCH*/ - if (r == 0 && globbed.gl_pathc == 0) return SCM_NIL; -#endif /*!GLOB_NOMATCH*/ - if (r) Scm_Error("Couldn't glob %S", pattern); + if (r == GLOB_NOMATCH) return SCM_NIL; +#endif + Scm_Error("Couldn't glob %S", pattern); + } for (i = 0; i < globbed.gl_pathc; i++) { ScmObj path = SCM_MAKE_STR_COPYING(globbed.gl_pathv[i]); SCM_APPEND1(head, tail, path);
- Shiro(2004/07/27 03:24:31 PDT): ども。適用しました。
Scm_FindBinding (0.8)
実害はないですが、修正前のifは意図したものと違っていると思います。(2004/07/26 04:14:05 PDT)
--- src/module.c 22 May 2004 07:21:42 -0000 1.50 +++ src/module.c 26 Jul 2004 11:07:27 -0000 @@ -210,7 +210,7 @@ for (i=0; i<num_searched; i++) { if (SCM_EQ(SCM_CAR(mp), searched[i])) goto skip; } - if (i == num_searched) { + if (!SCM_NULLP(more_searched)) { if (!SCM_FALSEP(Scm_Memq(SCM_CAR(mp), more_searched))) { goto skip; }
- Shiro(2004/07/26 13:16:45 PDT): 直しました。
Typo in fetch.scm (0.8)
タイポをみつけました.assq-ref 内の 'ncftpget の部分です.2004/07/15 06:16:33 PDT
--- lib/gauche/package/fetch.scm.orig 2004-07-15 22:07:52.000000000 +0900 +++ lib/gauche/package/fetch.scm 2004-07-15 22:08:16.000000000 +0900 @@ -59,7 +59,7 @@ (let-keywords* opts ((config '())) (let* ((build-dir (assq-ref config 'build-dir ".")) (wget (assq-ref config 'wget *wget-program*)) - (ncftpget (assq-ref config 'ncfptget *ncftpget-program*)) + (ncftpget (assq-ref config 'ncftpget *ncftpget-program*)) (dest (build-path build-dir (sys-basename uri)))) (rxmatch-case uri (#/^https?:/ (#f)
- Shiro(2004/07/26 13:16:45 PDT): 直しました。
マクロ内のcase(0.8)
マクロ内にcaseがある場合に、シンボルの判定に失敗します
gosh> (define-syntax foo (syntax-rules () ((_ x) (case x ((a) #t) (else #f))))) #<syntax foo> gosh> (foo 'a) #f
とりあえずこれで動きました。--teranishi (2004/07/11 06:25:20 PDT)
--- Gauche-0.8.orig/src/compile.c Fri May 21 20:40:21 2004 +++ Gauche-0.8/src/compile.c Sun Jul 11 21:48:55 2004 @@ -1336,7 +1336,7 @@ Scm_Error("badly formed clause in case form: %S", clause); /* the value of the key is on top of the stack. */ SCM_APPEND1(testcode, testtail, SCM_VM_INSN(SCM_VM_DUP)); - SCM_APPEND1(testcode, testtail, test); + SCM_APPEND1(testcode, testtail, unwrap_identifier(test)); SCM_APPEND1(testcode, testtail, SCM_VM_INSN(SCM_VM_MEMV)); test = testcode; } else {
multibyte string の判定 (0.8)
内部エンコーディングを euc-jp にした場合に、 write が文字列を正しくエスケープできないことがあります。(2004/07/01 10:15:06 PDT)
$ gosh -V Gauche scheme interpreter, version 0.8 [euc-jp,pthreads] $ gosh gosh> (define str (with-output-to-string (lambda () (for-each (lambda (v) (write-byte v)) '(#xe3 #x81 #x82 #x22))))) gosh> str "?343?201?202"" gosh> (string-size str) 4 gosh> (string-length str) 2
Index: src/gauche/char_euc_jp.h =================================================================== RCS file: /cvsroot/gauche/Gauche/src/gauche/char_euc_jp.h,v retrieving revision 1.14 diff -u -3 -p -r1.14 char_euc_jp.h --- src/gauche/char_euc_jp.h 9 Jan 2004 11:03:58 -0000 1.14 +++ src/gauche/char_euc_jp.h 1 Jul 2004 16:39:30 -0000 @@ -69,12 +69,23 @@ #define SCM_CHAR_GET(cp, ch) ? do { ? if (((ch) = (unsigned char)*(cp)) >= 0x80) { ? - if ((ch) == 0x8f) { ? + if ((ch) == 0x8f && ? + (unsigned char)(cp)[1] >= 0xa1 && ? + (unsigned char)(cp)[1] <= 0xfe && ? + (unsigned char)(cp)[2] >= 0xa1 && ? + (unsigned char)(cp)[2] <= 0xfe) { ? (ch) = ((ch) << 16) ? + ((unsigned char)(cp)[1] << 8) ? + (unsigned char)(cp)[2]; ? - } else { ? + } else if(((ch) >= 0xa1 && (ch) <= 0xfe && ? + (unsigned char)(cp)[1] >= 0xa1 && ? + (unsigned char)(cp)[1] <= 0xfe) || ? + ((ch) == 0x8e && ? + (unsigned char)(cp)[1] >= 0xa1 && ? + (unsigned char)(cp)[1] <= 0xdf)) { ? (ch) = ((ch) << 8) + (unsigned char)(cp)[1]; ? + } else { ? + (ch) = SCM_CHAR_INVALID; ? } ? } ? } while (0)
- Shiro: (2004/07/31 23:27:16 PDT) ここまで完全ではないのですが、一応対応しました。 ちゃんと全てのバイトのレンジを見るのがThe Right Thingなのでしょうが…
複素数で,複数の引数がある場合の割り算(0.8)
複素数の割り算で引数が複数ある場合,途中で虚数部分の初期化に失敗しているようです.(2004/06/27 11:32:18 PDT)
(let ((a 3) (b 4+3i) (c 7.3)) (- (/ a b c) (/ (/ a b) c))) => -0.026838671085532312-0.01599236448164463i
--- src/number.c.orig 2004-06-28 03:03:51.000000000 +0900 +++ src/number.c 2004-06-28 03:11:22.000000000 +0900 @@ -1216,9 +1216,9 @@ double d, r, i; result_real = SCM_COMPLEX_REAL(arg0); result_imag = SCM_COMPLEX_IMAG(arg0); - div_imag = 0.0; DO_COMPLEX: for (;;) { + div_imag = 0.0; if (SCM_INTP(arg1)) { div_real = (double)SCM_INT_VALUE(arg1); } else if (SCM_BIGNUMP(arg1)) {
- Shiro (2004/06/27 16:39:02 PDT): 直しときました。
- nobsun (2004/07/27 04:35:31 PDT): 精度の問題でしょうか、私の環境では
make check で fail します。
Testing numbers ... failed. discrepancies found. Errors are: test complex division: expects 0.0 => got 1.3877787807814457e-17
- Shiro (2004/07/31 02:32:01 PDT): プラットフォームは何ですか?
- nobsun (2004/07/31 10:07:42 PDT) 大事な情報が抜けてました。
- ARMA2.2 aka Omoikane GNU/Linux: (Kernel 2.4.21, glibc 2.3.1, gcc 2.95.4)
- Shiro (2004/07/31 11:44:36 PDT): i386ですよね? gcc2.95ってのがアレなのかなあ。
- nobsun (2004/08/09 20:30:25 PDT) Think Pad X23 なんで i386 です。gcc3.2.3 でメイクしなおしたら、ちゃんとパスしました。gcc2.95.4 の所為ですねぇ。ううむ。
- nobsun (2004/07/27 04:35:31 PDT): 精度の問題でしょうか、私の環境では
make check で fail します。
gauche-cesconv の help (0.8)
gauche-cesconv --help が動きません。(2004/06/23 09:20:51 PDT)
--- src/gauche-cesconv.in.orig 2004-06-24 01:16:14.000000000 +0900 +++ src/gauche-cesconv.in 2004-06-24 01:09:02.000000000 +0900 @@ -28,7 +28,7 @@ (let-args (cdr args) ((ices "f|from-code=s" (gauche-character-encoding)) (oces "t|to-code=s" (gauche-character-encoding)) (outfile "o|output=s" #f) - (#f "h|help" (usage)) + (#f "h|help" => (pa$ usage)) . files) (file-filter (lambda (in out) (let ((inp (wrap-with-input-conversion in ices))
- Shiro (2004/06/27 16:39:02 PDT): 直しときました。
カレントモジュールでの apropos (0.8)
gauche.sequence は gauche.collection を extend しているので,
(use gauche.sequence) (symbol-bound? 'call-with-iterator) #t
となります.apropos は引数のモジュールを省略すると,カレントモジュールから見える変数を表示するはずなのですが,
(apropos 'call-with-iterator)
では何も表示されません.一応の対処↓(2004/06/22 00:22:41 PDT) ↓をちょっと修正。2004/06/23 07:50:52 PDT
--- lib/gauche/interactive.scm.orig 2004-06-22 15:04:41.000000000 +0900 +++ lib/gauche/interactive.scm 2004-06-22 16:03:25.000000000 +0900 @@ -95,7 +95,9 @@ (if stay-in-module (search module) (begin - (for-each search (module-imports module)) + (for-each (compose (for-each$ search) + module-precedence-list) + (module-imports module)) (for-each search (module-precedence-list module)))) (for-each display (sort result)) (values)
- Shiro (2004/06/27 16:39:02 PDT): 直しときました。
割り算(0.8)
(/ (exact->inexact (expt 10 10)) (expt 10 9) 1) 10.0
となりますが,次の様にするとエラーとなってしまいます.
(/ (expt 10 10) (expt 10 9) 1) ERROR: operation / is not defined between (10 . 0) and 1
(2004/06/11 13:38:19 PDT)
bignum同士の割り算で結果が整数、かつ残りの引数がある場合におかしくなっているんですね。これで直ります。(2004/06/16 02:57:09 PDT)
--- gauche.orig/src/number.c 2004-06-16 18:46:51.000000000 +0900 +++ gauche/src/number.c 2004-06-16 18:39:32.000000000 +0900 @@ -1171,7 +1171,7 @@ goto DO_FLONUM; } if (SCM_NULLP(args)) return SCM_CAR(divrem); - return Scm_Divide(divrem, SCM_CAR(args), SCM_CDR(args)); + return Scm_Divide(SCM_CAR(divrem), SCM_CAR(args), SCM_CDR(args)); } if (SCM_FLONUMP(arg1)) { exact = FALSE;
- Shiro (2004/06/17 17:33:21 PDT): 直しました。
quote内のvectorの展開(0.8)
quote内のvectorにidentifierが含まれると位置がずれます
gosh> (define-syntax foo (syntax-rules () ((_) '#(a b)))) #<syntax foo> gosh> (foo) #(b #<class <pair>>)
以下の修正でなおると思います。--teranishi (2004/05/28 15:58:56 PDT)
--- Gauche-0.8.orig/src/compile.c Fri May 21 20:40:21 2004 +++ Gauche-0.8/src/compile.c Sat May 29 07:44:07 2004 @@ -773,7 +773,7 @@ SCM_VECTOR_ELEMENT(newvec, j) = *pelt; } SCM_VECTOR_ELEMENT(newvec, i) = elt; - for (pelt++; j<len; j++, pelt++) { + for (; j<len; j++, pelt++) { SCM_VECTOR_ELEMENT(newvec, j) = unwrap_identifier(*pelt); } return newvec;
- Shiro (2004/06/17 17:33:21 PDT): 直しました。
defineと内部define (0.7.4.2とか0.8とか)
2004/05/25 02:41:54 PDT
(define (a) 1 (define b #f))
だとエラーにならないのに
(define (a) (+ 1) (define b #f))
だとエラーになるのは,最適化とかの絡みかしら. - kou
Shiro(2004/05/25 03:24:14 PDT): ああそうか。本当は上もエラーにすべきですね。 今は、値が使われないリテラルが最適化で捨てられているため、 その次のdefineが内部defineとされてしまってるんだと思います。
Shiro(2004/07/13 14:16:15 PDT): 直しました。
SRFI-13 の string-take-right, string-drop-right の例 (0.8)
2004/05/23 20:11:58 PDT
modsrfi.texi で
(string-take-right "abcde" 2) => "cde" (string-drop-right "abcde" 2) => "ab"
になっていますが
(string-take-right "abcde" 2) => "de" (string-drop-right "abcde" 2) => "abc"
ではないでしょうか。
- Shiro: あっそうです。ドキュメントの方のミスですね。
macroexpandを実行してもマクロがautoloadされない(0.7.4.1, 0.8)
gosh起動直後に (macroexpand '(push! x 1)) を実行しても展開されません。--teranishi (2004/05/19 03:43:18 PDT)
- Shiro: これはちょっと深い問題なので、しばらく直らないかも。 コンパイラは最初にリストの第一要素がマクロかどうか 調べて、それからmacroexpandを呼ぶわけですが、autoloadは マクロかどうかを調べる時点で解決されます。したがって、 システム組み込みのmacroexpandは通常autoloadを見ることが ないのです。 独立して呼ばれた時のみautoloadのチェックをすればいいかな…
- Shiro (2004/06/27 21:25:45 PDT): どうせmacro expanderはいずれ書き直さなきゃならないし、 あんまりここで悩んでも仕方無い気がしてきたので、とりあえずで 直してしまいました。macro.c,v 1.48