首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >LISP cond回答无包

LISP cond回答无包
EN

Stack Overflow用户
提问于 2019-09-18 16:12:42
回答 2查看 185关注 0票数 2

很难找到一个合适的标题,因为我不明白为什么我有以下问题。

当我require我的包时,我想根据一些包指定一个特定的函数。其思想是按以下方式设置一个变量:

代码语言:javascript
复制
(cond ((find-package 'foo) (setf *special-function* #'foo:foo-function))
      ((find-package 'bar) (setf *special-function* #'bar:bar-function))
      (t (warn "The package FOO or BAR is required to enable the special function.")))

然后,对这段代码的计算返回:

带CCL的There is no package named "FOO"

带SBCL的Package FOO does not exist

我想这样做的主要原因是,它存在不同的包,它们提供了相同的功能,并且我希望让用户可以自由地通过加载包FOO或BAR (根据条件子句中的顺序具有首选项)作出自己的选择。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-09-18 18:48:25

考虑以下形式的执行/评估:

代码语言:javascript
复制
(if (find-package 'foo)
    (foo:foo-function))

Lisp

  1. 读取代码
  2. ,然后计算代码.

您的错误发生在第1阶段:读取。当包不存在时,无法读取表单。

一个典型的解决方法是这样:

代码语言:javascript
复制
(if (find-package 'foo)
    (funcall (find-symbol "FOO-FUNCTION" "FOO")))

然后,我们在运行时查找该符号。注意,函数名和包名默认为大写。

在你的情况下,你需要打电话给

代码语言:javascript
复制
(symbol-function (find-symbol "FOO-FUNCTION" "FOO"))

以获得函数对象。请注意,虽然有时它是首选的只是得到的符号。

funcallapply可以调用作为函数对象或符号的全局函数:

代码语言:javascript
复制
(funcall 'sin 2.1d0)

代码语言:javascript
复制
(funcall #'sin 2.1d0)

因此,当需要稍后调用时,符号提供了另一个间接来源,并指向当前定义,其中函数对象也可以是函数的旧版本。

票数 3
EN

Stack Overflow用户

发布于 2019-09-18 20:07:22

这看起来几乎是您想要为不同实现中不同名称下可用的功能定义一个包装函数。

因为,as Rainer wrote,我们需要区分在读取时已经存在的情况,我们可以使用读取器条件。方便地,所有实现都将其名称推入*features*,这样我们就可以这样做:

代码语言:javascript
复制
(defun special-function (&rest args)
  #+sbcl (apply #'foo:foo-function args)
  #+ccl (apply #'bar:bar-function args)
  #-(or sbcl ccl) (error "not implemented))

如果您希望允许不同的库填充您的功能,您可以在加载系统之前依赖用户加载其中的一个库,如果这些库将自己的符号推送到*features*,或者您可以定义添加可选依赖项的小包装器系统:

示例:您的(asdf)系统名为yoursys,然后您可以定义另一个系统yoursys/foo-backendyoursys/bar-backend,这两个系统都会将您的special-function设置为各自的实现,并依赖于所需的库。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57996926

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档