Properly load-file for interactive Common Lisp development

lee*_*ski 3 emacs common-lisp slime read-eval-print-loop

I would like to know, what is the common approach to common-lisp interactive development in emacs (i use sly, but i think the slime instructions should be the same)

say i have this file:

(eval-when (:compile-toplevel :load-toplevel :execute)
  (ql:quickload :closer-mop))

(in-package :cl-user)

(defpackage :shapes
  (:use :closer-common-lisp-user)
  (:export #:rectangle))

(in-package :shapes)

(defclass rectangle ()
  ((height :initform 0.0 :initarg :height)
   (width :initform 0.0 :initarg :width)))
Run Code Online (Sandbox Code Playgroud)

which is quite simple. Evaluating it experssion by expression seems to be ok, while loading the whole file (C-c C-l) gives me the following error:

The variable SHAPES:RECTANGLE is unbound.
   [Condition of type UNBOUND-VARIABLE]
Run Code Online (Sandbox Code Playgroud)

stripping it down to

(in-package :cl-user)

(defpackage #:shapes
  (:use #:cl-user)
  (:export #:rectangle))

(in-package #:shapes)

(defclass rectangle ()
  ((height :initform 0.0 :initarg :height)
   (width :initform 0.0 :initarg :width)))
Run Code Online (Sandbox Code Playgroud)

doesn't make any change.

compile-and-load (Cc Ck) 也不起作用,留给我的是:

; in: DEFCLASS RECTANGLE
;     (SHAPES::DEFCLASS SHAPES:RECTANGLE NIL
;      ((SHAPES::HEIGHT :INITFORM 0.0 :INITARG :HEIGHT)
;       (SHAPES::WIDTH :INITFORM 0.0 :INITARG :WIDTH)))
; 
; caught COMMON-LISP:STYLE-WARNING:
;   undefined function: SHAPES::DEFCLASS
Run Code Online (Sandbox Code Playgroud)

我看到defclass无法正确解决 from cl-user:defclass,但看不到修复它的方法。

我想知道我错过了什么?在 emacs 中进行交互开发的常见流程是什么?

小智 6

这里的潜在问题是您混淆了在 CL 中使用包的两种方式。一个包通常用于以下两个目的之一或两者:

  1. 它可以导出许多符号,为功能提供某种接口;
  2. 它可以是一个包,其中使用了其他包或从中导入符号,但不导出任何符号(除非它也是类型 1 包)。

这些类型的包之间没有正式的区别,但经常有非正式的区别。上面第二种类型*-USERCL-USER包通常被称为规范的例子是包。他们经常(但不总是)作为临时工作的地方。

所以你正在做的是定义一个包,它的使用列表就是这样一个用户包。您可以通过简单地查看此包的外部符号来看到这是行不通的。从你的第二个例子:

> (do-external-symbols (s (find-package "CL-USER"))
    (print s))
nil
Run Code Online (Sandbox Code Playgroud)

换句话说,根本不CL-USER导出任何符号。这意味着您的SHAPES包最初根本无法访问任何符号,尤其是不会出现任何CL 符号。

好吧,该语言定义了一个规范的“类型 1”包,即CL:该包的全部目的是导出定义 Common Lisp 语言的符号,并且仅导出那些符号。所以SHAPES你的第二个例子中包的定义应该是

(defpackage #:shapes
  (:use #:cl)
  (:export #:rectangle))
Run Code Online (Sandbox Code Playgroud)

(请注意,这SHAPES是一个类型 1 的包:它以 的形式提供一些功能,SHAPES:RECTANGLE因此可能打算供其他包使用。)

Closer to MOP 提供了两个镜像标准CLCL-USER包的包:

  • CLOSER-COMMON-LISP就像CL除了各种符号替换为Closer to MOP定义的符号外,可能还有额外的MOP符号;
  • CLOSER-COMMON-LISP-USER就像CL-USER:它是一个用于一般用途的包,用户CLOSER-COMMON-LISP但根本不导出任何符号。

  • @leetwinski:是的。抱歉,如果我的答案太长,因为我怀疑您不需要那么复杂的东西:我想尝试留下一些将来可能有用的东西。 (2认同)