Subject: Re: bug#26624: 26.0.50; Generalized variable `buffer-local-value' does't restore local flag

From: Michael Heerdegen <[email-masked]>
Date: Sun, 18 Jun 2017 06:17:15 +0200

Philipp Stephani <[email-masked]> writes:

> It's possible to fix this (see attached patch), but at the expense of
> breaking other valid use cases such as (cl-incf (buffer-local-value
> ...)). Not sure whether the bug can be fixed at all without breaking
> other stuff.

I have no solution, but some thoughts.

The more I think about it, the more I come to the conclusion that
`buffer-local-value' does not have a well defined according place.

The function `buffer-local-value' is not injective: it maps different
states to the same value because it can't express whether the VARIABLE's
binding is buffer-local or not.  But we need this information because we
need to undo creating a buffer local binding in the setter when closing
the `letf'.

And the setter, accepting only a value for the binding, isn't
surjective, because the argument doesn't hold any information of
buffer-localness.  Moreover, we want the setter to always create a
buffer-local binding in one situation (setf), but this isn't true for
the setter we need to use for `cl-letf'.

We could widen the semantics of `cl-letf' to do what we want in this
case, but I'm not sure if it's worth the trouble.  Not if there are more
cases like this.

BTW, a completely different point of view would be to argument like
this: the manual describes generalized variables as "one of the many
places in Lisp memory where values can be stored".  If variable X has no
buffer local binding in some buffer B, that place in Lisp memory is the
one that holds the global binding of X.  That means that the place expression

  (buffer-local-binding X B)

is equivalent to the place expression X.

OTOH, If X has a buffer local binding in B, we can use X as getter
expression and `setq' as setter, so the place expression
(buffer-local-binding X B) is also equivalent to X.  So it is always
equivalent to just X and of no use.

Michael.