シンボル名が変更されてしまった場合の対応方法 - lisp-cookbook-ja/common-lisp GitHub Wiki

sbclでは1.0.56から1.0.57へ変化する際、処理系を終了する関数が sb-ext:quitからsb-ext:exitに変更されました。 処理系のバージョンの違いが挙動に影響しないようにしたくはあるけれども、 シンボルの存在チェックを実行時に毎度行なうのは馬鹿らしくもあります。 コンパイル時にシンボルの存在によって出力するコードを変更する方法はないのでしょうか?

;;; from swank-backend.lisp
(defun with-symbol (name package)
  "Generate a form suitable for testing with #+."
  (if (and (find-package package)
           (find-symbol (string name) package))
      '(:and)
      '(:or)))
;; from swank-sbcl.lisp
(defimplementation quit-lisp ()
  #+#.(swank-backend:with-symbol 'exit 'sb-ext)
  (sb-ext:exit)
  #-#.(swank-backend:with-symbol 'exit 'sb-ext)
  (progn
    #+sb-thread
    (dolist (thread (remove (current-thread) (all-threads)))
      (ignore-errors (sb-thread:terminate-thread thread)))
    (sb-ext:quit)))

ということで実際にswankで対応している部分を抜きだしてきました。 読み込みの際にシンボルの有無によって(:and) (:or)が返る関数の結果を直接 #+や#-に食わせることで 処理するコードを切り替えることに成功しています。 こうしておくことで、場合分けの実行時のロスはなくすことができます。