【问题标题】:Lisp symbols without package bindings没有包绑定的 Lisp 符号
【发布时间】:2011-08-03 11:29:06
【问题描述】:

我一直在做一些项目。它应该能够进行数值和符号计算。但是现在我陷入了一个问题,我真的不知道如何解决它。简而言之,假设我们在包装中

(in-package #:brand-new-package)

我们有符号数据库的地方

(defvar var-symbol-database (make-hash-table :test #'equal))

读取和设置函数

(defun var-symbol (name)
  (get-hash name var-symbol-database))
(defun set-var-symbol (name value)
  (setf (get-hash name var-symbol-database) value))

 (set-var-symbol 'temperature 300) ;K
 (set-var-symbol 'f 200) ;Hz
 (set-var-symbol 'k 1.3806504e-23) ;J K^-1

现在在另一个文件(但相同的包)中,我将尝试评估这个等式

  (eval '(+ 2 (var-symbol 'f)))

这行不通。问题是由于某种特殊原因,哈希表中键的值是。

    brand-new-package::f

虽然我会像这样解决定义函数的问题

  (set-var-symbol 1 '(var-symbol 'f)) ;Hz

但它被解释为

 (brand-new-package::var-symbol brand-new-package::f)

问题是程序可以创建许多不同的符号。它将计算电子电路方程。程序首先检查电容器、电阻器等设备对象。它由 MNA 创建电路表。

在此期间可以创建许多代表节点电压和电流的新符号

 (v1, v2, v3, i1, i2). 

我需要一些方法来保存方程中变量的计数和名称。因为它们将被传递给符号导数,即 (diff '(* (+ 40 v1) u2 ...) 'v1)) 我想出了一个想法,可能是错误的,让它们可以通过索引访问以将它们定义为列表

 '(v 1) '(v 2) '(v 3). 

为了使它们可评估,我添加了开始的 var-variable funcall。于是列表就变成了

 '(var-variable v 1) '(var-variable v 2) '(var-variable v 3) 

但正如我所写,系统将其更改为

 '(brand-new-package::var-variable brand-new-package::v 1) '(brand-new-package::var-variable brand-new-package::v 2) '(brand-new-package::var-variable brand-new-package::v 3)

如何允许用户通过键入 (var-symbol 'v 1) 来访问这些变量。我只能想象一种方式。使用字符串和导出函数(var-symbol)代替符号。然后它将以这种方式工作

  '(var-variable "v" 1)

但这有点令人困惑。

【问题讨论】:

  • PS:Common Lisp 的gethash 没有破折号。另外,如果所有键都是符号,则在制作哈希表时不需要:test #'equal
  • 我测试了它(在将代码更改为使用gethash 之后)并在评估方程时得到了预期的结果'202'。
  • 是的,当您在同一个文件中时,一切都很好。但是在您使用 asdf 并在插入符号的不同文件中定义数据库的情况下。还有另一个文件用于评估符号获取包介词。这是我没想到的。

标签: lisp package common-lisp symbols


【解决方案1】:

你在复制 Lisp 已经做的事情。符号已经在称为包的表中进行管理。一个符号可以有一个值。把它放进一个包里就是INTERN。找到它是 FIND-SYMBOL 或只是使用 Lisp READer。

如果您想要自己的符号索引表,哈希表就可以了。如果您不想处理这些符号的包,那么只需使用关键字符号。它们前面有一个冒号。 :温度就是一个例子。关键字符号自动在包 KEYWORD 中,它们对自己进行评估。

【讨论】:

    【解决方案2】:

    您所说的“问题”与预期的一样。 Common Lisp 符号brand-new-package::var-symbol 表示符号var-symbol 在包brand-new-package 中,这是当前包在 lisp 读取符号时。

    【讨论】:

    • 我的问题是,如果我将一些符号保存到哈希表中,我会有一些期望。符号名称不会更改。因为我把它当作哈希键使用。
    • 符号的名称没有改变。评估(symbol-name 'brand-new-package::var-symbol) => "VAR-SYMBOL"。当(in-package :brand-new-package) 时,不合格的var-symbolbrand-new-package::var-symbol 的符号相同。您可以通过评估 (eq 'var-symbol 'brand-new-package::var-symbol) => T 来验证这两个符号是否相同。
    • 当当前包*package*与符号的包相同时,打印符号不带包名。但如果符号不在当前包中,则符号与包名一起打印。因此,当当前包为 brand-new-package 时,符号 brand-new-package::var-symbol 打印为 var-symbol,但当当前包不同时,以它的包名作为前缀。
    • 非常感谢。现在我对 lisp 系统定义机制有了更多的了解。我测试了它,这是真的。我的问题在于 eval 函数。 stackoverflow.com/q/5639008/703103
    猜你喜欢
    • 1970-01-01
    • 2019-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-02
    • 2019-09-28
    • 2020-03-27
    • 1970-01-01
    相关资源
    最近更新 更多