出口 / Unintern和符号访问

发布于 2025-02-09 06:20:54 字数 977 浏览 1 评论 0原文

在下面的示例中,我会遇到一个错误:

These symbols are not accessible in the COMMON-LISP-USER package:
  (FOO::BAR)

但是,

LS-USER> (describe 'foo::bar)
FOO::BAR
  [symbol]
; No value

这就是我到达那里的方式:

CL-USER> (make-package "FOO" :use '())
#<PACKAGE "FOO">
CL-USER> (intern "BAR" *)
FOO::BAR
NIL
CL-USER> (export (find-symbol "BAR" (find-package "FOO")))

现在我知道错误的含义,我对此感到好奇是:“此行为正确根据规格?”。我正在使用SBCL。

我明白了为什么无法通过foo:bar(未导出)访问它。但是,由于导出同时给出了符号和软件包,所以为什么它无法访问此符号并导出它?我看到了unintern的类似内容。

仔细阅读说“ 导出使一个或多个可以在 package ...中访问的符号”。它不认为必须在当前软件包中访问(*软件包*)。

在我看来,导出具有执行导出所需的所有信息,但是似乎有效的唯一方法是使用(export'foo :: bar(find-pakeAke bar(find-pake of foo''))> 。也许这是一个指定的区域,这正是SBCL选择的?

In the following example, I'm getting an error:

These symbols are not accessible in the COMMON-LISP-USER package:
  (FOO::BAR)

yet,

LS-USER> (describe 'foo::bar)
FOO::BAR
  [symbol]
; No value

Here's what how I got there:

CL-USER> (make-package "FOO" :use '())
#<PACKAGE "FOO">
CL-USER> (intern "BAR" *)
FOO::BAR
NIL
CL-USER> (export (find-symbol "BAR" (find-package "FOO")))

Now I understand what the error means and what I'm curious about is: "Is this behaviour correct according to the spec?". I'm using SBCL.

I can see why it's not accessible via foo:bar (it's not exported). However since export is given both the symbol and the package, why can't it access this symbol and export it? I'm seeing similar things with unintern.

A close read says "export makes one or more symbols that are accessible in package ...". It doesnt' say it has to be accessible in the current package (*package*).

It seems to me that export has all the information it needs to perform the export, but the only way this seems to work is with (export 'foo::bar (find-package "FOO")). Perhaps it's an underspecified area and this is just what SBCL has choosen to do?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

筱果果 2025-02-16 06:20:54

这是完全正确的行为:其他任何事情都不合格。 (导出s)将尝试从当前软件包中导出s指定的符号(export的可选第二个参数的默认值),在您的情况下,这是cl-user。为此,这些符号必须在当前软件包中可以访问。 :

  • 如果
    • 它要么将当前软件包作为其家庭包
    • 或已从其他软件包中导入其中,
  • 或者由于使用其他软件包的当前软件包而可以通过继承访问。

在最后的情况下,它将首先进口然后导出。

在您的情况下,这些事情都不是正确的。您要指定的符号,即foo :: bar由于符号指定自己,在cl-user包中根本不可访问。

参见 sped

This is entirely correct behaviour: anything else would be nonconformant. (export s) will try to export the symbols designated by s from the current package (the default for the optional second argument of export), which is CL-USER in your case. To do that those symbols must already be accessible in the current package. A symbol is accessible in the current package if:

  • either it is directly present because
    • it either has the current package as its home package
    • or it has been imported into it from some other package,
  • or it is accessible by inheritance due to the current package using some other package.

In the final case it will first be imported and then exported.

None of these things is true in your case. The symbol you are designating, which is FOO::BAR since symbols designate themselves, is not accessible in the CL-USER package at all.

See the spec

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文