Common Lisp:如何在读取函数中选择符号所属的包

Common Lisp: How to choose the package a symbol belongs to in the read function

这道题看似很简单,但我还是common lisp的初学者。 我尝试加载如下文件。没有包的符号 'year 'month等可以在每个文件中进行比较

;;; file db.lisp
((year 2010
    (month 5
        (1 100 "A")
        (2  -5 "B"))
    (balance 10)
    (month 6
        (1  -7 "C")
        (2  -8 "D")))
(load-from-csv-format-1 "db2011.csv")
(load-from-csv-format-2 "db2012.csv"))

我设法将现有的 lisp 代码转换为以下内容

(defpackage :db
    (:use :common-lisp :db.csv-format-1))
(in-package :db)

(defun read-db ()
  (let ((db (with-open-file (stream "db.lisp")
             (read stream))))
...
(case (car x)
    (year (expand-year x))
    (load-from-csv-format-1 (load-format-csv-format-1-impl (second x)))
    (load-from-csv-format-2 (load-format-csv-format-1-impl (second x)))
...

现在所有符号都属于包 :db。这对我来说有一个缺点,因为 所有对 read-db 的调用都必须在 :db 内完成。如果我现在要分开 不同包中的所有不同 csv 格式,它不再起作用,因为 例如'balance以下属于db.csv-format-1包无法比较 针对 db::balance 符号。

(defpackage :db.csv-format-1
    (:use :common-lisp)
    (:export :load-from-csv-format-1-impl))
(in-package :db.csv.format-1)
(defun load-format-csv-format-1-impl (path)
    (list 'balance 20))

所以我的问题是,这在 lisp 中是如何正确完成的?可以指定以某种方式阅读, 在哪个包中创建符号,然后以某种方式在此之外访问这些符号 包裹?

read interns 读入的内容 包 *package* 这样你就可以 这样做:

(defun read-db ()
  (let* ((*package* (find-package #:db))
        ((db (with-open-file (stream "db.lisp")
               (read stream)))))
   ...))

PS。作为初学者,您可能会喜欢阅读 Resources for learning Lisp.

中推荐的一些书籍