在常见的lisp中更改默认阅读器

cl-*_*y11 2 common-lisp stream reader-macro reader

我写了一些可以取代read普通lisp 功能的函数

(defun my-read (stream &rest args)
  (declare (ignore args))
  (funcall (my-get-macro-character (read-char stream))))
Run Code Online (Sandbox Code Playgroud)

有没有办法将此功能用作默认阅读器?

Jos*_*lor 5

你不能重新定义内置函数1,但是你可以定义一个阴影cl:read的包并定义一个新函数my:read,这样当你使用那个包时,它看起来像是默认的read函数.例如,像这样:

CL-USER> (defpackage #:my-package 
           (:use "COMMON-LISP")
           (:shadow #:read)
           (:export #:read))
;=> #<PACKAGE "MY-PACKAGE">

CL-USER> (defun my-package:read (&rest args)
           (declare (ignore args))
           42)
;=> MY-PACKAGE:READ

CL-USER> (defpackage #:another-package
           (:use #:my-package "COMMON-LISP")
           (:shadowing-import-from #:my-package #:read))
;=> #<PACKAGE "ANOTHER-PACKAGE">

CL-USER> (in-package #:another-package)
;=> #<PACKAGE "ANOTHER-PACKAGE">

ANOTHER-PACKAGE> (read)
;=> 42
Run Code Online (Sandbox Code Playgroud)
  1. 实际上,正如Rainer Joswig在评论中指出的那样,即使它是未定义的行为(参见11.1.2.1.2对符合程序的COMMON-LISP包的约束),通常还有一些方法可以重新定义一些Common Lisp函数,例如,在SBCL中,您可以使用unlock-package,如重新定义内置函数所示.CLISP有包锁.其他实现可以具有类似的功能.

  • 请注意,该标准不允许重新定义标准函数,但许多/大多数实际实现具有特定于实现的方法. (3认同)