【问题标题】:Properly load-file for interactive Common Lisp development为交互式 Common Lisp 开发正确加载文件
【发布时间】:2021-02-24 17:54:12
【问题描述】:

想知道,emacs中common-lisp交互开发的常用方法是什么(我用的是sly,不过我觉得slime指令应该是一样的)

说我有这个文件:

(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)))

这很简单。 通过表达式评估它似乎没问题,而加载整个文件(C-c C-l)给我以下错误:

The variable SHAPES:RECTANGLE is unbound.
   [Condition of type UNBOUND-VARIABLE]

将其分解为

(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)))

不做任何改变。

compile-and-load (C-c C-k) 也不起作用,只剩下:

; 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

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

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

【问题讨论】:

  • closer-common-lisp-user 包不导出内置的 Lisp 函数。你也需要:use #'common-lisp
  • 也许有一个包 CLOSER-COMMON-LISP 代替
  • 哇。您的两个答案都是正确的(不足为奇)。您能否将它们移至实际答案

标签: emacs common-lisp read-eval-print-loop slime


【解决方案1】:

这里的根本问题是您混淆了在 CL 中使用包的两种方式。一个包通常有两个目的之一或两个目的:

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

这些类型的包之间没有正式的区别,但经常有非正式的区别。上述第二种类型的包通常称为*-USER,典型示例是CL-USER 包。它们经常(但不总是)作为临时工作的场所。

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

> (do-external-symbols (s (find-package "CL-USER"))
    (print s))
nil

换句话说,CL-USER没有导出任何符号。这意味着您的 SHAPES 包最初根本无法访问任何符号,特别是 没有 CL 符号将出现。

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

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

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

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

  • CLOSER-COMMON-LISPCL 一样,只是各种符号被更接近 MOP 定义的符号代替,可能还有额外的 MOP 符号;
  • CLOSER-COMMON-LISP-USER 就像 CL-USER:它是一个用于一般用途的包,用户 CLOSER-COMMON-LISP 但它根本不导出任何符号。

【讨论】:

  • 对。整个问题是基于我的误解 user *-user packages reexport values。谢谢!
  • @leetwinski:是的。抱歉,如果我的回答过长,因为我怀疑您不需要任何复杂的东西:我想尝试留下一些将来可能有用的东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多