Gauche:Bugs:log4
最新のもの:Gauche:Bugs
- ユニフォームベクタの数値演算(CVS_HEAD)
- dbm-db-copy <gdbm> (0.8.3)
- 二重の名前付きlet (0.8.4_pre1)
- null-list?とシンタックス (0.8.4_pre1)
- (2005/04/04 19:33:17 JST) SLIB 使用時に format 関数の定義が SRFI-29 互換に意図せずに変わる。(0.8.3)
- (2005/04/02 09:10:44 PST)リファレンスマニュアル:define-method の説明
- (CVS HEAD(2005/02/20 18:06:20 PST) guardにおける述語としてのクラス
- (CVS HEAD)(2005/02/09 15:52:31 PST) 小数の演算
- 内部define-valuesがうまく動かない (0.8.3)
- string interpolation表記にread/writeの一貫性がない (0.8.3)
- (append! 1) がエラーになる (0.8.3)
- with-error-handlerとwith-output-to-stringのcurrent-output-portの遷移(?)がおかしい (0.8, 0.8.3)
- 明示的にgauche.condutilを読み込まないと<system-error>などが述語として使えないことがある (0.8.3)
- (let ()) (CVS版)
- gauche.uvector がコンパイルエラー (0.8.2、0.8.3)
- Emacs式のcodingを行頭に設定しておくとcoding-aware portがエラーを出す (0.8.2)
- require 後の READ-ERROR (0.8.2)
ユニフォームベクタの数値演算(CVS_HEAD)
2005/05/07 17:33:38 PDT u8vector-xor! が第1引数のu8vectorを再利用してくれないので気づきました。
Index: ext/uvector/uvlib.stub.tmpl =================================================================== RCS file: /cvsroot/gauche/Gauche/ext/uvector/uvlib.stub.tmpl,v retrieving revision 1.4 diff -u -r1.4 uvlib.stub.tmpl --- ext/uvector/uvlib.stub.tmpl 11 Nov 2004 12:14:43 -0000 1.4 +++ ext/uvector/uvlib.stub.tmpl 8 May 2005 00:27:28 -0000 @@ -162,7 +162,7 @@ "SCM_RETURN(Scm_${T}Vector${Opname}(v0, v1, clamp_arg(clamp)));") (define-cproc ${t}vector-${opname}! (v0::<${t}vector> v1 &optional clamp) - "SCM_RETURN(Scm_${T}Vector${Opname}(v0, v1, clamp_arg(clamp)));") + "SCM_RETURN(Scm_${T}Vector${Opname}X(v0, v1, clamp_arg(clamp)));") ///)) ;; end of tmpl-numop ///(define *tmpl-bitop* '( @@ -170,7 +170,7 @@ "SCM_RETURN(Scm_${T}Vector${Opname}(v0, v1));") (define-cproc ${t}vector-${opname}! (v0::<${t}vector> v1) - "SCM_RETURN(Scm_${T}Vector${Opname}(v0, v1));") + "SCM_RETURN(Scm_${T}Vector${Opname}X(v0, v1));") ///)) ;; end of tmpl-bitop ///(define *tmpl-dotop* '(
でしょうか。
- Shiro(2005/05/10 19:48:08 PDT): 修正しました。
dbm-db-copy <gdbm> (0.8.3)
千代郎2005/05/02 01:58:47 PDT:dbm.gdbmがうまく使えるかどうか試していたところ、上記の関数でエラーになるので、lib/dbm/gdbm.scm を見ました。
(define-method dbm-db-copy ((class <gdbm-meta>) from to . keys) (%with-gdbm-locking (lambda () (apply copy-file from to :safe #t keys))))
これは、正しくは、
(define-method dbm-db-copy ((class <gdbm-meta>) from to . keys) (%with-gdbm-locking from (lambda () (apply copy-file from to :safe #t keys))))
でしょうか?(このように変更すると動きました)。dbm-db-renameも同様です。
- Shiro(2005/05/10 19:48:08 PDT): 修正しました。
二重の名前付きlet (0.8.4_pre1)
二重の名前付きletでループをさせたときの動きが、0.8.3と異なっています。 0.8.3での結果を期待していたのですが、バグなのでしょうか。
(define wv (make-weak-vector 5)) (define len (weak-vector-length wv)) (let lp ((n 10) (str (number->string 10))) (let lp2 ((m n)) (when (< m (+ 10 len)) (weak-vector-set! wv (remainder m len) str) (gc) (print wv) (if (odd? m) (lp (+ 1 m) #`",n") (lp2 (+ 1 m))))))
上(わかりにくい例ですみません)を評価した結果が、↓となります。(2005/04/22 10:37:42 PDT)
;; 0.8.3 => #,(<weak-vector> 5 10 #f #f #f #f) #,(<weak-vector> 5 10 10 #f #f #f) #,(<weak-vector> 5 #f #f 10 #f #f) #,(<weak-vector> 5 #f #f 10 10 #f) #,(<weak-vector> 5 #f #f #f #f 12) ;; 0.8.4_pre1 => #,(<weak-vector> 5 10 #f #f #f #f) #,(<weak-vector> 5 10 10 #f #f #f) #,(<weak-vector> 5 10 10 10 #f #f) #,(<weak-vector> 5 10 10 10 10 #f) #,(<weak-vector> 5 10 10 10 10 12)
- Shiro: おお、最初何のことかわからなかったのですが、lpの引数のstr への参照が残ってしまっているってことですね。確認したところ、確かにローカル 関数呼び出しを最適化した際、tail positionでのローカル関数呼び出しでフレームが 一つ余分にスタックに残ってしまっているようです。考えてみます。
- Shiro(2005/05/10 19:48:08 PDT): CVS HEADで直っています。
null-list?とシンタックス (0.8.4_pre1)
エラーを出したあとにsegmentation faultで落ちます。 -fno-inline-globalsをつければ問題ありませんでした。(2005/04/17 06:09:48 PDT)
(if (null-list? 1) #t #f) (and (null-list? 1) #t) (and #t (null-list? 1)) ;; これはエラーのみ (and (null-list? 1)) ;; これもエラーのみ
- Shiro(2005/04/18 15:24:22 PDT): パッチっす。
--- src/gauche.h 12 Apr 2005 01:42:26 -0000 1.406 +++ src/gauche.h 18 Apr 2005 22:23:44 -0000 @@ -687,7 +687,7 @@ #define SCM_SET_CDR(obj, value) (SCM_CDR(obj) = (value)) #define SCM_EXTENDED_PAIR_P(obj) ? - (SCM_PAIRP(obj)&&GC_size(obj)>=sizeof(ScmExtendedPair)) + (SCM_PAIRP(obj)&&GC_base(obj)&&GC_size(obj)>=sizeof(ScmExtendedPair)) #define SCM_EXTENDED_PAIR(obj) ((ScmExtendedPair*)(obj))
(2005/04/04 19:33:17 JST) SLIB 使用時に format 関数の定義が SRFI-29 互換に意図せずに変わる。(0.8.3)
yokota: 以前にShiroさんにメールでも報告しましたが、以外と分かりづらい 問題なのでこちらにも記述します。
Gauche では SLIB を使用する時にその設定ファイルから SRFI を全て読み込もうと します。そのために SRFI-29 の format 関数で標準の format 関数が上書き されてしまいます。この2つの format 関数には機能的な差があるので標準の format 関数に依存した記述を行っていると SLIB を読み込んだ後にプログラムが 正しく動かなくなります。
対処法としては SLIB の初期設定ファイルで SRFI の読み込む記述を止め、 個別に必要な SRFI を読み込むのが良いのでしょうが、それは数が多くなって 面倒なので自分のプログラムでは以下のような記述で一旦標準の format を 保存しておき、後でそれを書き戻す方法を取りました。
(define native-format format) (use slib) (require 'foo) (define format native-format)
今後の正式な対処法としては SLIB の初期設定時に SRFI を読み込まないようにするか、 "srfi-29.scm" から "srfi-29/format.scm" を読み込む設定を削除し、 SRFI-29 を読み込む時に "srfi-29/bundle.scm" のみを読み込むようにすれば良いかと 思います。
Shiro(2005/04/18 15:24:22 PDT): これは悩み中です。Gaucheにはgettextがあるので、 (use srfi-29)するのはsrfi-29を利用した既存のコードを走らせたい場合が 多いと思うんですよ。そうすると(use srfi-29)で、もしくは(cond-expand (srfi-29 ...)) した時点でformatがcompliantになっていないとまずいでしょう。 Gaucheのslib.scmで*features*からsrfiを除くことで、srfiの一斉読み込みを 回避する、という方法が良いかと思うのですが、 他の部分に支障が出ることはあるでしょうか。
Shiro(2005/05/10 19:48:08 PDT): 結局、slib.scmでsrfiを指定しないことにしました。 srfiを使いたい場合は個別にuseして下さい。
(2005/04/02 09:10:44 PST)リファレンスマニュアル:define-method の説明
ytaki: 単なる typo ですが.
Index: object.texi =================================================================== RCS file: /cvsroot/gauche/Gauche/doc/object.texi,v retrieving revision 1.35 diff -u -r1.35 object.texi --- object.texi 6 Nov 2004 12:31:27 -0000 1.35 +++ object.texi 2 Apr 2005 16:39:33 -0000 @@ -2945,7 +2945,7 @@ またはジェネリック関数以外に束縛されているなら、新しいジェネリック関数が 生成され、@var{name} に束縛されて、新しいメソッドがそれに追加されます。 -@var{space} はこのメソッドに対応する引数とその型を指定します。これは +@var{specs} はこのメソッドに対応する引数とその型を指定します。これは lambda 形式の引数リストに似ていますが、それぞれの引数の型を指定できる ところが違います。 @c COMMON
- Shiro(2005/05/10 19:48:08 PDT): 修正しました。
(CVS HEAD(2005/02/20 18:06:20 PST) guardにおける述語としてのクラス
カレントディレクトリで、touch fugaしてあるとして、
gosh> (guard (e ((<system-error> e) "readlink error")) (sys-readlink "fuga")) *** ERROR: invalid application: (#<class <system-error>> #<system-error "readlink failed: Invalid argum ...">) Stack Trace: _______________________________________ 0 (<system-error> e) At line 1 of "(stdin)" gosh> (guard (e ((<system-error> e) "system-error")) (raise (make-condition <system-error> 'message "fuga"))) "system-error" gosh>
前者もエラーを補足してくれそうに思うのですが... クラスを述語として使わず、condition-has-type?を使えばいずれも期待通りの動作になります。また、例えば直前に(make-condition <error>)を評価していれば期待通りの動作になります。ということは、autoloadの問題でしょうか? condutil.scmがloadされてないのかな?
- Shiro: はい。autoloadの問題です。(下の方で報告されてますね)。 ブランチの方では修正済みなんですが、 ブランチは今出ているバージョンのGaucheではビルドできないので、 必要ならば次のコードをlib/gauche/object.scmの後ろの方に足して下さい。
;; A trick to let a condition type behave its own predicate (define-method object-apply ((type <condition-meta>) obj) (condition-has-type? obj type))
- わわ、見落としていました。大変失礼しました。
(CVS HEAD)(2005/02/09 15:52:31 PST) 小数の演算
gosh> (+ 1.2 2.3) 3.5 gosh> (+ 1.3 2.3) 3.5999999999999996 gosh> (+ 1.4 2.3) 3.6999999999999997 gosh> (+ 1.5 2.3) 3.8
Shiro: それはこういうしくみです。
Gaucheは、実数に関して (1)read時には、与えられた10進表記に最も 近いIEEE倍精度浮動小数点数を用い、 (2)write時には、「それを書き出した10進表記を再び 読み込んだ際に全く同じIEEE倍精度浮動小数点数が再現される10進表記のうち、 最も短いもの」を用います。
1.3に最も近いIEEE倍精度浮動小数点数 | 5854679515581645 × 2^-52 |
2.3に最も近いIEEE倍精度浮動小数点数 | 10358279142952140 × 2^-52 |
両者の和 | 16212958658533785 × 2^-52 |
ここで 16212958658533785 (#x39999999999999) を表現するのには54bit必要で、 IEEE倍精度浮動小数点数の仮数部は53bitしかないので最下位ビットが丸められます。 これは偶数方向に丸めることになっているので、演算結果は 16212958658533784 × 2^-52 となります。
3.6に最も近いIEEE倍精度浮動小数点数は 16212958658533786 × 2^-52 なので、 答えを3.6としてしまうのは誤りです。具体的には、計算の途中結果をファイル等に 書き出して、それを読み込んで計算を続行するような場合に、途中結果がドリフト してしまうことになります。
3.5999999999999996は読み込んだ際に 16212958658533784 × 2^-52 と、 内部表現を正しく再現します。
浮動小数点数の読み込みと表示に関しては 次の2論文や、Gauche:数値の入出力, Gauche:拡張浮動小数点演算の謎を 参照して下さい。
- Robert G. Burger and R. Kent Dybvig, "Priting Floating-Point Numbers Quickly and Accurately", PLDI '96, pp.108--116, 1996.
- Will Clinger, "How to Read Floating Point Numbers Accurately", in the ACM SIGPLAN '90, pp.92--101.
有理数をちゃんと実装している処理系なら、丸め誤差のない、正確な 計算をすることができます (e.g. (+ 13/10 23/10) => 33/10 )。 Gaucheは(まだ)有理数を実装していません。
内部define-valuesがうまく動かない (0.8.3)
(define (hoge) (define-values (a) (values 1)) a) gosh> (hoge) *** ERROR: unbound variable: a
以下のような動作がただしそうです。
gosh> (hoge) 1
- うちでは動いています。(Debian Linux - Sarge, i386) Setu? 2005/01/25 23:05:34 PST
(define (hoge) (define-values (a) (values 1)) a) hoge gosh> (hoge) 1 $ gosh -V Gauche scheme interpreter, version 0.8.3 [euc-jp,pthreads]
- ねるWiki:ねる (2005/01/26 18:16:30 PST) あれ、ぼくなんかおおぼけかましてますかね.... 以下の環境で確認したところだめでした。
Gauche scheme interpreter, version 0.8.3 [utf-8,pthreads] (Mac OS X 10.3) Gauche scheme interpreter, version 0.8.3 [euc-jp] (NetBSD 2.0)
ちなみにgauche/defvalues.scmのdefine-syntaxをcurrent-moduleにコピペしてもってくるとちゃんとうごきます。
- Shiro: コンパイラのバグで、マクロ展開の結果生成されるbegin中の internal defineのスコープがおかしくなっているようです。 開発中のバージョンでは直っています。
string interpolation表記にread/writeの一貫性がない (0.8.3)
gosh> (write (read-from-string "#`?",|name|?"")) (string-append "" (#<generic x->string (5)> name) "")
以下のようになってほしい。
gosh> (write (read-from-string "#`?",|name|?"")) #",|name}"
Shiro (2005/01/23 19:00:42 PST): そうか… #`"...." はリーダーマクロで (string-append ほにゃらら) に展開されるので、これは仕方ないと 言えば仕方ない話なんです。(quote x) をreadしたのが 'x とwrite されてしまうのと同じで。(処理系によっては 'x をreadしたのを writeすると (quote x) になるものもあります。要するに、表記は 違っても同じものなので一貫性は保たれていると考えます)。
問題になるのは #<generic x->string> のところですね。read back 出来ないですから。これはhygienityのためで、例えば こんなコードを実行したときに:
(let ((x->string list)) #`"abc,|name|def")
おかしな結果になるのを防いでいます。
でもソースコードを処理するフィルタを書くときなんかは困りますね… グローバルな束縛を参照する特殊な構文を使う方がいいんだろうか。
ねるWiki:ねる (2005/01/23 20:31:20 PST) はい、せめてx->stringがsymbolだったらなぁと思ったのですが、hygienityのためだったのですね。グローバル参照(もしくは特定モジュールを強制的に参照?)する構文があると、この手のリーダーマクロ書くのに便利そうですね。
- ' , ,@ とかからの関連で言えば #`",|name|" => (string-interpolation ",|name|") ってなって、 string-interpolation が上の変換をするマクロなら良かったってことか。 ただ、Gauche の場合文字列は全部コピーで作っててコストの高い処理だから ",|name|" なんて文字列を作りたくないんで C レベルの read 処理時点で 分解して読んでると。cut-sea
Shiro: あれ。cut-seaさんの指摘は鋭いかも。 正確には、 #`"...." はリーダーマクロでsrfi-10構文 #,(string-interpolate "....") に展開され、リード時コンストラクタのstring-interpolateが (string-append ....) へと展開しています (定義はlib/gauche/interpolate.scm)。 でもなぜそうやったかというと、あんまり考えてなかったような。 string-interpolateをマクロにする場合、syntax-rulesでは書けないので hygienityで問題が出る可能性がありますが、そのうち低レベルhygienicマクロを 導入する予定なので、そうしたら普通のマクロで問題無い気がします。(2005/01/23 21:52:13 PST)
Shiro (2005/05/23 23:54:41 PDT): とりあえず、0.8.4ではシンボルx->stringをそのまま 挿入するように変更します。Hygienityについてはまた考えます。
(append! 1) がエラーになる (0.8.3)
teranishi: (append! 1) を実行するとエラーになります。 しかし、(use srfi-1) してから実行するとエラーになりません。 (2005/01/20 03:01:37 PST)
gosh> (append! 1) *** ERROR: pair required: 1 Stack Trace: _______________________________________ gosh> (use srfi-1) (#<module srfi-1> #<module gauche.interactive>) gosh> (append! 1) 1
- Shiro (2005/01/24 18:34:14 PST): 直しました (extlib.stub,v 1.231)。
with-error-handlerとwith-output-to-stringのcurrent-output-portの遷移(?)がおかしい (0.8, 0.8.3)
nekoie: 以下を実行すると、"cannot displayed"の部分は、with-output-to-stringの出力portに出力されているような気がします。エラーハンドラ側に来たら、元のcurrent-output-portに戻して欲しいです。(2005/01/01 16:21:06 PST)
(with-error-handler (lambda (e) #?=(current-output-port) (display "cannot displayed")) (lambda () (with-output-to-string (lambda () (error "hoge")))))
- Shiro: srfi-34, srfi-18の仕様で、「exception handlerは
exceptionが起きた場所のdynamic environmentで呼ばれる」ことが規定
されています。current-output-portもdynamic environmentの一部なので、
ここは変えないのが正しいという解釈です。
一つの理由として、もしエラーハンドラ内でcurrent-output-portを戻して
しまうと、エラー発生時のcurrent-output-portを得ることが不可能であるのに
対し、現在の仕様ではエラー発生時のcurrent-output-portも得られるし、
with-error-handler評価時のcurrent-output-portも(自分で保存すれば良いので)
得られる、ということがあげられます。
- nekoie: 理解しました。ありがとうございます。
明示的にgauche.condutilを読み込まないと<system-error>などが述語として使えないことがある (0.8.3)
koguro: goshを起動した直後に<system-error>などを述語として使おうとすると以下のようにエラーとなります。
gosh> (<system-error> 1) *** ERROR: invalid application: (#<class <system-error>> 1)
明示的に(use gauche.condutil)を呼べばよいのですが、コンディションクラスでもautoloadしてくれるとうれしいです。(2004/12/24 07:42:24 PST)
- Shiro: あっそうか。guardやdefine-condition-type等のsrfi-34, srfi-35の APIを使わないとobject-apply methodが定義されないわけですね。 <system-error>等のコンディションクラスは既に組み込みなので、それが autoloadをトリガするのは難しいです。object-applyの定義だけgauche.objectに 移そうかな。
(let ()) (CVS版)
0.8.3では、
(let ()) => #<undef>
でしたが、現在のCVS版ではsegmentation faultで落ちてしまいます。(2004/12/19 17:56:35 PST)
- Shiro: letの<body>は必須なので、(let ()) は不正なフォームとして コンパイルエラーにすべきでしょうね。コンパイラ回りは0.8.4でちょっと 変わる予定です。
gauche.uvector がコンパイルエラー (0.8.2、0.8.3)
ext/uvector/uvector.c が、Gentoo、Debain (sarge)ともに下記のエラーになってコンパイルできません。
i386-linux-gcc -DHAVE_CONFIG_H -I. -I../../src -I../../gc/include -g -O2 -fPIC -c uvector.c uvector.c: In function `s32vector_mul': uvector.c:357: error: can't find a register in class `GENERAL_REGS' while reloading `asm' make: *** [uvector.o] Error 1
また、該当行をコメントにしても、
i386-linux-gcc -DHAVE_CONFIG_H -I. -I../../src -I../../gc/include -g -O2 -fPIC -c uvector.c uvector.c: In function `u32vector_mul': uvector.c:398: error: can't find a register in class `GENERAL_REGS' while reloading `asm' make: *** [uvector.o] Error 1
となります。 src/gauche/arith_i386.h の SMULOV と UMULOV をコメントアウトするか、s32vector_mul と u32vector_mul の "inline" を削除するとコンパイルできました。gcc はともに 3.3.4、binutils は Gentoo が 2.15.90.0.1.1、Debian が 2.15 です。(2004/12/04 00:39:35 PST)
- Shiro: gccのレジスタ最適化アルゴリズムの変更によって、レジスタが 足りなくなっちゃったせいかな。output operandのレジスタクラスを 共に"g"にするとどうなりますか? "r"(y) を "g"(y) に変更するってことです。
- src/gauche/arith_i386.h の177行目と、200行目を「:"g" (x), "r" (y)」から「:"g" (x), "g" (y)」にするという理解で正しいのならば、同じエラーになりました。それと、正確ではなかった所を訂正させてください。s32vector_mul と u32vectro_mul ではなく、s32_mul_safe と u32_mul_safe から "inline" を削除するとでした。(2004/12/04 02:03:54 PST)
- Shiro (2004/12/04 02:33:55 PST): あ、そういう意図でした。ふーむ。 手元でgccのバージョンを上げて試してみます。まだ3.3.2なので。
- 解決しました。Gentoo の方は、make する際に OPTFLAGS を上書きしたことによって、-fomit-frame-pointer がなくなったためで、Debian の方は、aclocal.m4 に以下の様に変更するとコンパイルできるようになりました。(2004/12/07 04:29:28 PST)
--- gauche-0.8.3.orig/aclocal.m4 +++ gauche-0.8.3/aclocal.m4 @@ -96,7 +96,7 @@ case "$host" in i686-*) I686OPT="-DUSE_I686_PREFETCH";; esac -if test $CC = "gcc"; then +if test `echo $CC | sed 's/^.*-//` = "gcc"; then case "$target" in *mingw*) ;; *) GCCOPT="-fomit-frame-pointer";;
- えんどう(2004/12/21 00:52:03 PST)もしかして以下でしょうか?
if test `echo $CC | sed 's/?(.*?)-.*/?1/'` = "gcc"; then
Emacs式のcodingを行頭に設定しておくとcoding-aware portがエラーを出す (0.8.2)
ねるWiki:ねる (2004/12/01 22:51:42 PST) euc-jp-unixのように「-unix」や「-dos」がついたcoding名を設定しておくと 下記のエラーになります. 適当に-unixあたりを落として読んでほしいです.
*** ERROR: conversion from code euc-jp-unix to code UTF-8 is not supported
- Shiro: うぐゎ。そういう落し穴がありましたか。 「"-(unix|dos|mac)$" を無視する」という対応はちょっと汚いんで、逆にGaucheの方に "-(unix|dos|mac)$" つきのエンコーディング名も別名として認識させるのが良さそうに 思います。ext/charconv/jconv.c のconv_supportsで認識する別名の一覧が 定義されているので、そこに足しちゃうのが一番シンプルな解決かな。 (別名の比較の際には '-' と '_' の違いは無視されます)。(2004/12/01 23:51:33 PST)
- Shiro: あっだめだ。euc-kr-unixとかbig5-dosとかいくらでもバリエーションが 出てくるから。うーん、現実的なのはやっぱり"-(unix|dos|mac)$"無視って方向かなあ。 (2004/12/02 00:01:49 PST)
- Shiro: 0.8.3で対応しました。
require 後の READ-ERROR (0.8.2)
teranishi: 以下のファイル(test.scm)をロードしようとすると
(require "util/list") ()
以下のエラーが発生します。(Windows2000SP4,cygwin)(2004/12/01 21:13:51 PST)
$ gosh test.scm *** READ-ERROR: Read error at "./test.scm":line 3: EOF inside a list (starting f rom line 2) Stack Trace: _______________________________________
- Shiro (2004/12/01 21:54:24 PST): むむ。行末がCRLFだと再現するようです。 ignore-coding #t にしてloadすると大丈夫なので、codingマジックコメントの 先読み機能が行末CRLFの時にミスってるっぽいですね。 とりあえずの回避策として、先頭2行にコメントか空行を入れてみて下さい (codingマジックコメントの先読みは2行までしか行われないので)。
- Shiro: この問題をfixした0.8.3をリリースしました。