Next: Up: Previous:

現処理系における主な制限

まずは現処理系における制限を列挙する.
型パラメータを持つ型の未実装
多くのプログラミング言語では定義する型に型パラメータを含ませることがで きる. 例えばMLでは,
datatype 'a tree = 
    LEAF of 'a
  | NODE of ('a tree * 'a tree)
と書くことで, 型パラメータを'aをとる型treeを定義したことにな り, プログラムで以降, int tree, real treeなどの型が使え るようになる. また, それら全てのtree型に有効な関数を書くことができる. 例えば,
fun is_leaf (LEAF x) = true
  | is_leaf (NODE (left, right)) = false
は, 全ての'a tree型に対して有効である.

同様の機構は, Eiffelなどの多くのオブジェクト指向言語でもサポートされて いる.

ABCL/fの構文ではdeftypeおよびdefclassにおいて型パ ラメータを指定する場所が用意されている. 例えば本来は上述のtree は,

(deftype tree (a)
  (leaf a)
  (node (tree a) (tree a)))
と書けるはずである. 同様に, defclassにおいても,
(defclass tree (a) 
  ...)
のように書けるはずである. しかし現在の処理系ではこれらはサポートされて いない. いいかえれば, deftypeおよびdefclassの型パラメー タ部分は常に空(つまり())でなくてはならない. これに違反したプロ グラムに対して, コンパイラは以下のようにエラーメッセージを出す.
Expand Error:  deftype type parameters ignored
(deftype tree (a) (leaf a) (node (tree a) (tree a)))

defvar, defconstantの不完全な実装
guro初期化式には複雑な式は書けない(Cの初期化と同様の制限). たとえば,
(defvar *x* (+ 3 4))
などは許されるが,
(defvar *x* (foo 3))
などは許されない. 現在, これに違反したプログラムも, warningを出すのみで, ABCL/fからC++への変換は成功してしまう. し かし生成されたC++プログラムをオブジェクトファイルにする際にC++コンパイ ラによって, エラーとなる. たとえば,
(defun foo (x)
  (declare (fixnum x) (reply-type fixnum))
  x)

(defvar *x* (foo 3))
というファイルをコンパイルすると, ABCL/fからC++への変換時には,
lute:1010% make x.o
abclfc -f sun -debugger :off  x.ff x.cc
ABCLF_ROOT = /home/users/tau/proj/abclf
; Loading #p"/tmp_mnt/home/camille2/tau/proj/abclf/lib/init.abclfc".
Converting defun foo
Converting defvar *x*

Warning:  Initializing defvar/defconstant by compound expression is not fully 
implemented.  You may get C++ compiler error.
		...
のようなwarningが出るのみで, のちにC++コンパイラによって,
x.cc:1035: braced-group within expression allowed only inside a function
というエラーメッセージが出される.

Becomeの回数はコンパイル時に検査されない
Becomeは, defmethod!の中で正確に一度だけ実行されなくては ならない. 例えば以下のようなプログラムは不正なプログラムである.
(defmethod! counter add2 (x)
  (declare (fixnum x) (reply-type fixnum))
  (become val :val (+ val x))
  (become val :val (+ val x)))
しかし現在のコンパイラはこのことを検出しない. また, よりおきがちな誤り として, 以下のようなものもあり得る.
(defmethod! counter add-if-large (x)
  (declare (fixnum x) (reply-type fixnum))
  (if (> x 10)
      (become val :val (+ val x))
      val))
これは, xが10より大きい場合にのみcounterの値を更新することを意 図したものだが, そうでない場合にbecomeが一度も実行されないので 誤りである. 上のプログラムは,
(defmethod! counter add-if-large (x)
  (declare (fixnum x) (reply-type fixnum))
  (if (> x 10)
      (become val :val (+ val x))
      (become val)))
と書かなくてはならない.

上のような意味で誤った実行をしてしまった場合, 現処理系は実行時エラーを 生成する. エラーはbecomeを一度も実行せずにmethodを終了した時点, ある いは, 2度目のbecomeを実行しようとした時点で生成される.



Mitsubishi Research Institute,Inc.
Thu Feb 27 21:01:00 JST 1997