BOUNDP检查PROGV中的自由变量吗?

huangapple go评论43阅读模式
英文:

BOUNDP checks free variables in PROGV?

问题

In the given code, there seems to be an issue with the expected behavior of (boundp 'b)). According to the CLHS, it should return NIL for b in this context, but you expected it to return T. This might not necessarily be a bug in SBCL, but rather a misunderstanding of the Common Lisp specification.

英文:

Suppose both a and b are unbound (i.e. (notany #'boundp '(a b)) => T), then this works as expected:

(progv '(a b) '(1)
  (boundp 'a)) ; => T

Then PROGV entry in CLHS states:

> If too few values are supplied, the remaining symbols are bound and then made to have no value.

which contradicts what I see in REPL:

(progv '(a b) '(1)
  (boundp 'b)) ; => NIL

I'll expect (boundp 'b) to return T.

Question: Did I misunderstand the wordings in CLHS? Or is it a bug in SBCL?

Environment:
SBCL 2.2.10, Linux x86_64

Thanks!

答案1

得分: 6

I think the wording in the standard is poor, but what is intended to happen is that

(progv '(a b) '(1) ...)

is equivalent to

(progv '(a b) '(1 nil)
  (makunbound 'b)
  ...)

This is very different than simply not binding b at all as you can see by considering this:

(progv '(b) '(3)
  (progv '(b) '()
    ... b unbound here ...)
  (symbol-value 'b))

which evaluates to 3. The issue is that makunbound removes the value of the dynamic binding of the symbol that is currently in scope. In a shallow binding implementation that's the same thing as simply marking the value cell of the symbol as having no value, because the outer value will be restored in due course. But in a deeply bound implementation the binding must still exist in the stack of bindings, but its value must be marked as 'unbound' somehow.

Perhaps the problem, really, is that boundp and makunbound at least are arguably misnamed: boundp really tells you if the current dynamic binding of a symbol has a value, not if one exists at all, and makunbound removes the value from the current dynamic binding. But these names were inherited by CL. There is no way of telling (and probably should be no way) whether there is a current non-global dynamic binding for a symbol or not.

Finally, this behavior of progv is useful because it means you can say

(progv '(a b c) '()
  ... now I know a, b, c are unbound ...)

which means you can avoid the problem that somebody might have polluted the environment in ways you can't control.

英文:

I think the wording in the standard is poor, but what is intended to happen is that

(progv '(a b) '(1) ...)

is equivalent to

(progv '(a b) '(1 nil)
  (makunbound 'b)
  ...)

This is very different than simply not binding b at all as you can see by considering this:

(progv '(b) '(3)
  (progv '(b) '()
    ... b unbound here ...)
  (symbol-value 'b))

which evaluates to 3. The issue is that makunbound removes the value of the dynamic binding of the symbol that is currently in scope. In a shallow binding implementation that's the same thing as simply marking the value cell of the symbol as having no value, because the outer value will be restored in due course. But in a deeply bound implementation the binding must still exist in the stack of bindings, but its value must be marked as 'unbound' somehow.

Perhaps the problem, really, is that boundp and makunbound at least are arguably misnamed: boundp really tells you if the current dynamic binding of a symbol has a value, not if one exists at all, and makunbound removes the value from the current dynamic binding. But these names were inherited by CL. There is no way of telling (and probably should be no way) whether there is a current non-global dynamic binding for a symbol or not.

Finally, this behaviour of progv is useful because it means you can say

(progv '(a b c) '()
  ... now I know a, b, c are unbound ...)

which means you can avoid the problem that somebody might have polluted the environment in ways you can't control.

答案2

得分: 1

它首先声明了一个绑定,但后来赋予了没有值(意味着甚至不是NIL作为一个值 - 这是我认为你期望的 - 我也是,因为这在lambda列表中会是行为)。所以然后b在绑定后必须是未绑定的(就像(makunbound 'b))。只有在被取消绑定之后,变量b才没有值。

英文:

It states first bound but then made having no value (means not even NIL as a value - what I think you expect - me too, because that would be the behavior in lambda lists e.g.). So then b must be unbound after binding (like (makunbound 'b)). Only after being unbound, variable b would have no value.

huangapple
  • 本文由 发表于 2023年5月7日 14:38:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/76192527.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定