🎩
Gauche: eq?, eqv?, equal? の実装コードを探す
Scheme の等価性の判定については、eq?
, eqv?
, equal?
の 3 つの述語があります。
それぞれがどのように比較を行うかについては、リファレンスマニュアルに書かれてあります。
ここでは Gauche の eq?
, eqv?
, equal?
がどのようなコードで実装されているか見ていきましょう。
eq?, eqv?, equal? の実装コードを探そう
REPL から describe コマンドを実行し、eq?
についての情報を出力してみます。
gosh> ,d eq?
#<subr (eq? obj1 obj2)> is an instance of class <procedure>
Defined at "libbool.scm":47
slots:
required : 2
optional : #f
optcount : 0
locked : #f
currying : #f
constant : #t
info : (eq? obj1 obj2)
setter : #f
eq?
は、libbool.scm
の 47 行目で定義されていることが分かりました。
さっそくソースを覗いてみると、次の定義が見つかります。
libbool.scm
(define-cproc eq? (obj1 obj2) ::<boolean> :fast-flonum :constant
(inliner EQ) SCM_EQ)
ふーむ。確かに eq?
の定義のようではありますが、普段書いている Scheme コードとは雰囲気が違いますね。どうやら Scheme の世界から Gauche の実装言語(C 言語)への入り口に立っているようです。
おそらく、C 言語で書かれた eq?
の実装がきっとどこかにあるはずです。
すぐ隣に eqv?
, equal?
も定義されているので、それも見ておきましょう。
libbool.scm
(define-cproc eqv? (obj1 obj2) ::<boolean> :fast-flonum :constant
(inliner EQV) Scm_EqvP)
(define-cproc equal? (obj1 obj2) ::<boolean> :fast-flonum Scm_EqualP)
いかにも定義らしい SCM_EQ
, Scm_EqvP
, Scm_EqualP
で grep してみましょう。
すると、gauche.h に見つかります。
gauche.h
#define SCM_EQ(x, y) ((x) == (y))
SCM_EXTERN int Scm_EqP(ScmObj x, ScmObj y);
SCM_EXTERN int Scm_EqvP(ScmObj x, ScmObj y);
SCM_EXTERN int Scm_EqualP(ScmObj x, ScmObj y);
さらに Scm_EqP
で grep すると boolean.h に実装が見つかります。ついに実装までたどり着くことが出来ました。
boolean.h
int Scm_EqP(ScmObj x, ScmObj y)
{
return SCM_EQ(x, y);
}
int Scm_EqvP(ScmObj x, ScmObj y)
{
/* 略 */
}
int Scm_EqualP(ScmObj x, ScmObj y)
{
/* 略 */
}
eq?
, eqv?
, equal?
の実体は、それぞれ C 言語の Scm_EqP
, Scm_EqvP
, Scm_EqualP
の関数ということが分かりました。
Discussion