GNU bug report logs -
#40671
[DOC] modify literal objects
Previous Next
To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 40671 in the body.
You can then email your comments to 40671 AT debbugs.gnu.org in the normal way.
Toggle the display of automated, internal messages from the tracker.
Report forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Thu, 16 Apr 2020 20:40:02 GMT)
Full text and
rfc822 format available.
Acknowledgement sent
to
Kevin Vigouroux <ke.vigouroux <at> laposte.net>
:
New bug report received and forwarded. Copy sent to
bug-gnu-emacs <at> gnu.org
.
(Thu, 16 Apr 2020 20:40:02 GMT)
Full text and
rfc822 format available.
Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):
Hello!
The Emacs Lisp manual often gives the impression that the user can
modify literal lists (e.g. 5.6.1 Altering List Elements with `setcar`).
LISP> (setq x '(1 2))
(1 2)
LISP> (setcar x 4)
LISP> x
(4 2)
However, it is also mentioned that one should not modify the literal
objects because of the byte compilation (c.f. 2.7 Equality Predicate).
Can we modify literal objects?
See Also:
https://emacs.stackexchange.com/questions/45820/when-to-use-quote-for-lists-modifying-quoted-lists-in-elisp
https://emacs.stackexchange.com/questions/57806/which-lisp-objects-are-byte-compiled
Best regards,
Kevin Vigouroux.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Fri, 17 Apr 2020 16:11:02 GMT)
Full text and
rfc822 format available.
Message #8 received at 40671 <at> debbugs.gnu.org (full text, mbox):
>Can we modify literal objects?
No, and the manual should do a much better job at explaining this. At the very least it should not promulgate
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Fri, 17 Apr 2020 16:38:01 GMT)
Full text and
rfc822 format available.
Message #11 received at 40671 <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
tags 40671 patch
stop
[Sorry about the truncated message.]
> Can we modify literal objects?
No, and the manual should do a much better job at explaining this. At the very least it should not promulgate bad ideas by including mutation of literals in example code. Patch attached, suggested for emacs-27.
We should not even try to show what happens when the user breaks the rule, because it is undefined.
[0001-Don-t-mutate-literals-in-manual-examples-bug-40671.patch (application/octet-stream, attachment)]
Added tag(s) patch.
Request was from
Mattias Engdegård <mattiase <at> acm.org>
to
control <at> debbugs.gnu.org
.
(Fri, 17 Apr 2020 16:38:02 GMT)
Full text and
rfc822 format available.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Fri, 17 Apr 2020 17:28:01 GMT)
Full text and
rfc822 format available.
Message #16 received at 40671 <at> debbugs.gnu.org (full text, mbox):
> From: Mattias Engdegård <mattiase <at> acm.org>
> Date: Fri, 17 Apr 2020 18:37:23 +0200
> Cc: Kevin Vigouroux <ke.vigouroux <at> laposte.net>
>
> > Can we modify literal objects?
>
> No, and the manual should do a much better job at explaining this. At the very least it should not promulgate bad ideas by including mutation of literals in example code. Patch attached, suggested for emacs-27.
I don't see any explanation of the issue in the patch, did I miss
something?
What I see summarily replaces literal lists and cons cells with a
calls to functions, and I'm not sure this is a step in the right
direction. It definitely complicates the examples, which is not
necessarily TRT, methodologically, for such introductory sections.
Reply sent
to
Paul Eggert <eggert <at> cs.ucla.edu>
:
You have taken responsibility.
(Sat, 18 Apr 2020 20:11:02 GMT)
Full text and
rfc822 format available.
Notification sent
to
Kevin Vigouroux <ke.vigouroux <at> laposte.net>
:
bug acknowledged by developer.
(Sat, 18 Apr 2020 20:11:02 GMT)
Full text and
rfc822 format available.
Message #21 received at 40671-done <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
Mattias, thanks for going through the Emacs manual and looking for mistakes in
this area. I know it was a pain to do that, since I did something similar in
parallel and it was painful for me. I used your patch to crosscheck with my
draft (finding omissions on both sides) and installed the resulting patch
(attached) into the emacs-27 branch.
This patch should address the points that Eli raised. That is, it adds
explanations of the issue (both in the intro and the reference manual, since the
issue also infects the intro), and it attempts to change examples only when the
changes are needed to avoid undefined behavior in Emacs Lisp. I also kept the
changes from '< to #'< that were in your patch since that's good style.
[0001-Document-constant-vs-mutable-objects-better.patch (text/x-patch, attachment)]
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sat, 18 Apr 2020 21:55:02 GMT)
Full text and
rfc822 format available.
Message #24 received at 40671-done <at> debbugs.gnu.org (full text, mbox):
OK, here's a nitpick, FWIW.
___
You say things such as this:
"should be applied only to @dfn{mutable} lists,
that is, lists constructed via @code{cons},
@code{list} or similar operations."
That's not a usual meaning of "mutable". Your
"that is" makes clear what you mean, sort of, I
suppose. That part is clear enough, but it's
not a good "definition" of "mutable".
It's about code that always creates new list
structure, versus code that might create new
list structure only sometimes (e.g. the first
time it's encountered).
A quoted list, which you call "constant", is in
fact mutable in some contexts.
An immutable list would be one you couldn't ever
change - it would truly be a constant. That can
be true for the result of byte-compiling a quoted
list.
But it's not true in general for interpreted
code. E.g., this example in (elisp) `Setcdr':
(setq x '(1 2 3)) ⇒ (1 2 3)
(setcdr x '(4)) ⇒ (4)
x ⇒ (1 4)
What you're really trying to convey presumably
is not that one CANNOT ever modify such a list,
but that one SHOULD NOT modify such a list (e.g.
because of what can happen to it with the byte
compiler). That's something different, and I
don't think the message comes across well.
Similarly:
"However, the other arguments (all but the last)
must be mutable lists."
"MUST" means you CANNOT do otherwise. Trying to
do so might result in an error being raised, for
example. And that's not always the case. Hence
the gotcha, hence the need for a guideline: Don't
do it; just say no.
That text with "must" is immediately followed by:
"A common pitfall is to use a quoted constant list..."
And _that's_ the point. But together with your
text saying you CANNOT modify it anyway, things
get confusing. Modifying a quoted list is
problematic, a gotcha, a pitfall, something to
avoid.
You SHOULD NOT do it precisely because you CAN
do it sometimes. If you couldn't, e.g., if you
were prevented from doing it by always raising
an error, then there would be no gotcha, no
reason to tell you not to do it.
Anyway, you get the idea.
BTW, "a quoted constant list" is a bit poorly
worded, as well. (Yes, that text was already
there.) The problem is using a quoted list
sexp, which can have the effect of producing
a constant list. It's not about quoting a
list that is somehow already a constant.
Quoting can _produce_ a constant.
---
FWIW, Common Lisp doesn't talk about mutable
or immutable lists (or other objects):
"The consequences are undefined if literal
objects (including quoted objects) are
destructively modified."
Undefined. They CAN sometimes be destructively
modified.
And a proposal says to:
"clarify that it is an error to destructively
modify objects which are self-evaluating
forms or which appear inside of a QUOTE
special form."
And it talks of:
"modifying quoted data structures"
Such wording makes clear which things we're
talking about.
Cltl says only:
"implicit sharing of compiled data structures
may result in unpredictable behavior if
destructive operations are performed. However,
CLtL does not explicitly allow or disallow
destructive operations on constants."
Unpredictable behavior. It doesn't say it's
always impossible to modify such things. It
says, in effect, don't try.
That's what we should say for Emacs Lisp, since
we do NOT "disallow modification of constants
consistently in all situations."
For Emacs Lisp this is a gotcha, so we need a
SHOULD. If it were enforced as a MUST then we
wouldn't need such a caveat.
This was proposed for CL:
"Disallowing modification of constants
consistently in all situations, rather than
just in compiled code, is proposed because in
some compiled-only situations it may be
difficult to distinguish between "compiled"
and "interpreted" code."
Whether "disallow" means raise an error in all
such cases (which was proposed for Cltl) or
just warn users not to do it and say the behavior
is "undefined" (what Cltl did, and what Emacs
should do), is a separate question.
The point about trying to modify a quoted list,
for Emacs Lisp, is this:
Don't do it. Don't assume that you get new
list structure each time it looks like a quoted
list will be evaluated anew. It might be
evaluated only once, and the result used as a
constant thereafter.
http://clhs.lisp.se/Issues/iss083_w.htm
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 19 Apr 2020 02:27:01 GMT)
Full text and
rfc822 format available.
Message #27 received at 40671 <at> debbugs.gnu.org (full text, mbox):
[[[ To any NSA and FBI agents reading my email: please consider ]]]
[[[ whether defending the US Constitution against all enemies, ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]
Thanks to both of you for working on updating the Emacs Lisp Intro.
Its author, Bob Chassell, became incapacitated many years before his
death, so it has not had the needed attention for quite some time. I
would be surprised if it didn't have other problems due to the changes
that we have made in Emacs Lisp since 20 years ago.
Would anyone like to pick some chapter and read it looking for
anything that needs updating? Not only things that are now incorrect,
but anything that is not clear to beginners.
--
Dr Richard Stallman
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 19 Apr 2020 02:40:02 GMT)
Full text and
rfc822 format available.
Message #30 received at 40671-done <at> debbugs.gnu.org (full text, mbox):
On Sat, 18 Apr 2020 at 17:55, Drew Adams <drew.adams <at> oracle.com> wrote:
> An immutable list would be one you couldn't ever
> change - it would truly be a constant. That can
> be true for the result of byte-compiling a quoted
> list.
As far as I know, byte compilation has no special effect on
mutability. Dumping does, or used to, I think that no longer happens
with the pdumper.
.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 19 Apr 2020 13:58:02 GMT)
Full text and
rfc822 format available.
Message #33 received at 40671 <at> debbugs.gnu.org (full text, mbox):
> Cc: 40671-done <at> debbugs.gnu.org, Kevin Vigouroux <ke.vigouroux <at> laposte.net>,
> Eli Zaretskii <eliz <at> gnu.org>
> From: Paul Eggert <eggert <at> cs.ucla.edu>
> Date: Sat, 18 Apr 2020 13:10:30 -0700
>
> Mattias, thanks for going through the Emacs manual and looking for mistakes in
> this area. I know it was a pain to do that, since I did something similar in
> parallel and it was painful for me. I used your patch to crosscheck with my
> draft (finding omissions on both sides) and installed the resulting patch
> (attached) into the emacs-27 branch.
>
> This patch should address the points that Eli raised.
How do you know the patch addresses my concerns, when you didn't even
let me read and comment on it? What is this rush to go ahead and push
changes when there's clearly some controversy that hasn't yet been
resolved? Can I somehow convince you not to do that in the future?
> That is, it adds explanations of the issue (both in the intro and
> the reference manual, since the issue also infects the intro), and
> it attempts to change examples only when the changes are needed to
> avoid undefined behavior in Emacs Lisp.
As Štěpán points out, not all of the examples need these changes.
Please revert the changes that aren't needed.
More generally, it is IMO not enough to explain the issue in one
place, and then use non-literal constructs everywhere as if the reader
magically knows or remembers something that is written in a very far
place of the manual. The effect is to obfuscate the manual without
any explanation right there and then -- which is IMNSHO a very bad
thing, methodologically, because it leaves the readers wondering what
they are missing.
For example, the node "Sets and Lists" now sometimes uses literal
lists and sometimes non-literal ones -- without any explanation why.
Likewise in "Association Lists" and "Sequence Functions".
This is a step backward. We are making our manual a riddle that the
reader will have to solve. That is not how good manuals are written.
> @example
> @group
> -(delq 'a '(a b c)) @equiv{} (cdr '(a b c))
> +(equal
> + (delq 'a (list 'a 'b 'c))
> + (cdr (list 'a 'b 'c)))
> @end group
And here you simply changed the meaning of the example: @equiv{} is
not the same as 'equal'.
Bottom line: the extra explanations about the danger of using literal
lists in some situations are a good addition to the manual, but most
of the replacements elsewhere of literal lists with non-literal ones
are not -- unless we also add in each case some text which explains
why we use 'list', 'cons', 'vector', etc, instead of literal
constants.
Please fix these deficiencies.
Thanks in advance.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 19 Apr 2020 17:01:01 GMT)
Full text and
rfc822 format available.
Message #36 received at 40671 <at> debbugs.gnu.org (full text, mbox):
19 apr. 2020 kl. 15.56 skrev Eli Zaretskii <eliz <at> gnu.org>:
> This is a step backward. We are making our manual a riddle that the
> reader will have to solve. That is not how good manuals are written.
Eli, maybe that is stretching it a bit? Paul's (and my) changes are far from perfect but they did aim to do no harm. Surely we all prefer correct to simple and wrong. Mistakes must and will be fixed, naturally.
Your point about not surprising the user about inconsistencies in examples is entirely fair, and we should definitely explain these issues more clearly and in the right order. However, it doesn't mean that the status quo ante was better: not only did the manual set bad examples in many places, it even managed to warn sternly about non-constant arguments to nconc right after an example which did precisely that.
What about we add a separate section about literals of all types, why they should be treated as immutable even though mutation currently isn't detected or disallowed at runtime, and recommended ways of coping with it (constructor functions, copy-sequence)? It would serve as a point of reference for all sections describing destructive operations. There is also a need for some cautionary text in the backquote section.
I'd volunteer to write it all but won't do the work just to have it shot down on general principles. It's not like I'm expecting a blank cheque, but we'd need to agree on the approach first.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 19 Apr 2020 19:23:02 GMT)
Full text and
rfc822 format available.
Message #39 received at 40671 <at> debbugs.gnu.org (full text, mbox):
> From: Mattias Engdegård <mattiase <at> acm.org>
> Date: Sun, 19 Apr 2020 18:59:55 +0200
> Cc: Paul Eggert <eggert <at> cs.ucla.edu>, 40671 <at> debbugs.gnu.org,
> ke.vigouroux <at> laposte.net
>
> 19 apr. 2020 kl. 15.56 skrev Eli Zaretskii <eliz <at> gnu.org>:
>
> > This is a step backward. We are making our manual a riddle that the
> > reader will have to solve. That is not how good manuals are written.
>
> Eli, maybe that is stretching it a bit? Paul's (and my) changes are far from perfect but they did aim to do no harm. Surely we all prefer correct to simple and wrong. Mistakes must and will be fixed, naturally.
The problem is that the changes were pushed before they could be
reviewed and commented. No one said anything about meaning to do
harm, but mistakes do happen, and a good way to avoid mistakes is to
let peer review take its course. Rushing a commit doesn't allow to
make the changes better by considering aspects that the original
committer was unaware of, or where he/she is biased or lacks some
knowledge or experience that others can contribute.
> Your point about not surprising the user about inconsistencies in examples is entirely fair, and we should definitely explain these issues more clearly and in the right order. However, it doesn't mean that the status quo ante was better: not only did the manual set bad examples in many places, it even managed to warn sternly about non-constant arguments to nconc right after an example which did precisely that.
I stand by what I wrote: the status quo ante was better.
A manual is not a mathematical paper, where everything should be
rigorous all the way from the first page to the last. A good manual
introduces the material gradually, and makes simplifications to avoid
dumping too much stuff on the reader at once. So yes, it is entirely
legitimate to show simplified examples, and at some later point say
that those simple examples have pitfalls, and explain those pitfalls.
There's absolutely no requirement to be 110% correct everywhere in the
manual, because that will make the manual hard to read and understand,
and eventually will shoot us in the foot.
This is, of course, my opinion. Your opinions might be different, and
maybe you could convince me in some of the cases. But for this to
happen, we need to talk, and you (or Paul) need to present the
arguments that aim at changing my mind (or change your own). Is it
too much to ask to let the discussion proceed? If these matters are
important, then we should give their discussion our best shot, so that
the net result is absolutely the best we could come up with -- and
that means it should incorporate the different views and experiences
of most or all the participants.
> What about we add a separate section about literals of all types, why they should be treated as immutable even though mutation currently isn't detected or disallowed at runtime, and recommended ways of coping with it (constructor functions, copy-sequence)? It would serve as a point of reference for all sections describing destructive operations. There is also a need for some cautionary text in the backquote section.
>
> I'd volunteer to write it all but won't do the work just to have it shot down on general principles. It's not like I'm expecting a blank cheque, but we'd need to agree on the approach first.
I don't think I understand the proposal enough to answer the question.
Wed already have a section about these matters, and the additions that
Paul made there are more or less uncontroversial, I think, and
generally consider a Good Thing. What do you suggest in addition to
that?
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 19 Apr 2020 20:40:02 GMT)
Full text and
rfc822 format available.
Message #42 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 4/18/20 2:54 PM, Drew Adams wrote:
> "should be applied only to @dfn{mutable} lists,
> that is, lists constructed via @code{cons},
> @code{list} or similar operations."
>
> That's not a usual meaning of "mutable". Your
> "that is" makes clear what you mean, sort of, I
> suppose. That part is clear enough, but it's
> not a good "definition" of "mutable".
>
> It's about code that always creates new list
> structure, versus code that might create new
> list structure only sometimes (e.g. the first
> time it's encountered).
I think we're mostly in agreement here, it's just that it can be difficult to
state things clearly in a reference manual. Let me try to explain a bit further.
As far as Elisp is concerned, it's OK to apply destructive operations to list
structures that are created only sometimes (e.g., the first time it's
encountered), so long as these structures have been created dynamically by the
program. That is, the key notion is not whether the program is implementing
hash-consing on its own (where it's a bad idea to modify already-existing
structures but is valid as far as Elisp is concerned); the key notion here is
whether the program is diving into the Lisp interpreter's data structures and
attempting to change those data structures on the fly (the program shouldn't do
that, as the results are unpredictable and Emacs might crash).
> A quoted list, which you call "constant", is in
> fact mutable in some contexts.
Yes, but we cannot easily document where and when those contexts might be, and
it would be a disservice to our users if we tried to document what happens
exactly, partly because of the complexity and partly because the byte-compiler
might change in the future. Instead, we should simply say that one should not
modify the data structures that quoted lists return.
> An immutable list would be one you couldn't ever
> change - it would truly be a constant. That can
> be true for the result of byte-compiling a quoted
> list.
We can talk about the distinction between a "true constant" and a "constant" in
an introductory section, but in the rest of the manual it's simpler to merely
distinguish between constant objects (which the program should not change) and
mutable objects (which the program can change). That is, in most of the manual
there's no reason to distinguish between the two: modifying a constant is
trouble, and programs shouldn't do it. In the introductory section we can talk
about what happens if programs try to modify a constant anyway.
> "However, the other arguments (all but the last)
> must be mutable lists."
>
> "MUST" means you CANNOT do otherwise.
I changed it to "should".
> BTW, "a quoted constant list" is a bit poorly
> worded, as well.
I changed that to "constant list".
> FWIW, Common Lisp doesn't talk about mutable
> or immutable lists (or other objects):
>
> "The consequences are undefined if literal
> objects (including quoted objects) are
> destructively modified."
>
> Undefined. They CAN sometimes be destructively
> modified.
Yes, that's the idea I'm trying to capture here as well, with the changes I
installed today.
Thanks for your comments.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 19 Apr 2020 20:46:02 GMT)
Full text and
rfc822 format available.
Message #45 received at 40671 <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
On 4/19/20 6:56 AM, Eli Zaretskii wrote:
> How do you know the patch addresses my concerns
I don't know that; I merely wrote that the patch should address the points you
raised earlier. The goal was to improve documentation that was obviously
deficient in this area - there's no serious dispute about that. The changes I
installed were intended to be an improvement and have been found so by others -
if you disagree, please feel free to revert or improve them. Obviously the
documentation is not perfect in this area and further improvements would be welcome.
> As Štěpán points out, not all of the examples need these changes.
I installed further changes that should address Štěpán's comments.
> For example, the node "Sets and Lists" now sometimes uses literal
> lists and sometimes non-literal ones -- without any explanation why.
> Likewise in "Association Lists" and "Sequence Functions".
This was in response to your request to not change examples if the examples
didn't strictly need the changes. Although I preferred Mattias's original
proposal because it switched to the (list ...) style more uniformly, the patch I
installed mixed the '(...) and (list ...) styles because I thought that was what
you were asking for.
I installed the attached patch, which attempts to address this issue by adding
comments that try to explain why (list ...) is needed sometimes. However, in
hindsight perhaps we should go back to the style used in Mattias's proposal, as
it's simpler and more consistent and doesn't distract the reader from the focus
of the documentation. Going back to Mattias's style would let us remove some of
the comments that the attached patch inserts.
>> @example
>> @group
>> -(delq 'a '(a b c)) @equiv{} (cdr '(a b c))
>> +(equal
>> + (delq 'a (list 'a 'b 'c))
>> + (cdr (list 'a 'b 'c)))
>> @end group
>
> And here you simply changed the meaning of the example: @equiv{} is
> not the same as 'equal'.
Ah, I missed on that one. Thanks for pointing it out. I reverted that change in
the attached patch.
As you note, it's not essential that the list be modifiable in this particular
example. That being said, the documentation should not suggest that it's OK to
use a destructive operation like delq on a constant, so further improvements
would be helpful here if someone can find the time.
[0001-Improve-mutability-doc.patch (text/x-patch, attachment)]
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 19 Apr 2020 21:02:01 GMT)
Full text and
rfc822 format available.
Message #48 received at 40671 <at> debbugs.gnu.org (full text, mbox):
> distinguish between constant objects (which the
> program should not change) and mutable objects
> (which the program can change).
That's just not what "constant" means. And I
suspect that your _uses_ of _not_ "mutable" will
still be for things that we really want to say
you probably _should not_ change, and not that
you _cannot_ change them.
You are once again confusing things for readers,
I think.
Something you probably _should not_ change is
not necessarily a constant. (And the converse
isn't strong enough - you simply _cannot_ change
a constant.)
And places where you will likely say there's no
reason you _shouldn't_ change something will
likely give the impression that this is because
it is "mutable", and give the impression that
there's no reason you shouldn't change anything
that you _can_ change. This can give the
impression that if you _can_ change something
(the real meaning of "mutable") then there's no
reason you shouldn't change it. That's the
wrong message.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 19 Apr 2020 21:03:01 GMT)
Full text and
rfc822 format available.
Message #51 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 4/19/20 9:59 AM, Mattias Engdegård wrote:
> What about we add a separate section about literals of all types, why they should be treated as immutable even though mutation currently isn't detected or disallowed at runtime, and recommended ways of coping with it (constructor functions, copy-sequence)? It would serve as a point of reference for all sections describing destructive operations.
In my recent patches to the emacs-27 branch I added a section "Constants and
Mutability" that discusses many of these issues. It's a fundamental topic so I
put the new section into doc/lispref/objects.texi, and cross-referenced it from
the destructive-operation sections.
I didn't think of recommending ways of coping with it, and that's a good
suggestion. I'm not sure that the coping-mechanism discussion belongs in
objects.texi, though, as it's pragmatic rather than fundamental.
> There is also a need for some cautionary text in the backquote section.
Yes, my recent patches added a brief note there.
> I'd volunteer to write it all but won't do the work just to have it shot down on general principles.
I know the feeling.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 19 Apr 2020 21:12:02 GMT)
Full text and
rfc822 format available.
Message #54 received at 40671 <at> debbugs.gnu.org (full text, mbox):
> In my recent patches to the emacs-27 branch I added a section
> "Constants and Mutability" that discusses many of these issues.
See my previous reply. It's not about (what you called)
constants and mutability. Misleading, and unclear, IMO.
> I didn't think of recommending ways of coping with it
I don't think that's needed. That is, I don't think
there's any such "coping".
What's needed is to make clear to users _what_ happens,
and its effects; that's all. With that info, they can
do whatever's appropriate for them in any given context.
But it's good to show an example of a gotcha, to help
make clear _what_ can happen and why.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 19 Apr 2020 21:17:01 GMT)
Full text and
rfc822 format available.
Message #57 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 4/19/20 2:01 PM, Drew Adams wrote:
>> distinguish between constant objects (which the
>> program should not change) and mutable objects
>> (which the program can change).
> That's just not what "constant" means.
What does "constant" mean to you? It's not clear.
> And I
> suspect that your _uses_ of _not_ "mutable" will
> still be for things that we really want to say
> you probably _should not_ change, and not that
> you _cannot_ change them.
Your suspicion is correct. In the current emacs-27 documentation, "mutable"
means you can change the object, "constant" means you should not change it. It's
intended to be documentation that is simple and consistent and tells programmers
what they can do without worrying (change a mutable object), and what they
shouldn't do (try to change a constant).
Of course the documentation could have a more-complex discussion of the various
ways that an object could be "constant". The object could be in read-only memory
enforced by the hardware and operating system, or there could be a run-time
check by the Emacs interpreter, or there could be no check at all and you can
change the constant with the program behaving erratically afterwards, or there
are other possibilities. If you'd like to add text along those lines to the new
section "Constants and Mutability" please feel free to suggest something. The
point is to make that section useful for Emacs Lisp programmers, after all.
> This can give the
> impression that if you _can_ change something
> (the real meaning of "mutable") then there's no
> reason you shouldn't change it.
I'm not following. Even if I've created an object with the 'cons' function there
may be very good pragmatic reasons for me to not invoke setcar and setcdr on it,
as otherwise my program's actions will be scrambled. However, from the Emacs
lisp point of view such a cons is still mutable.
If you propose specific text for the manual, no doubt your point will become
clearer.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 19 Apr 2020 21:59:01 GMT)
Full text and
rfc822 format available.
Message #60 received at 40671 <at> debbugs.gnu.org (full text, mbox):
Hello Paul,
I had a quick look at your changes. I agree that it would have been
better to discuss before you start to install what you think you like.
Some things add more confusion. Before your changes the manual used the
term "literal" objects, now you added a different wording "constant"
vs. "mutable" that describes more or less the same thing.
Then some things you added are just wrong, at least in the generality
you word them. As Drew said, `quote' doesn't always return constant
objects, the special form just returns the OBJECT, whatever it is, when
it is evaluated.
Or:
| Vectors written with square brackets are constants and should not be
| modified via @code{aset} or other destructive operations.
(let ((l (list 1 2 3)))
(let ((my-vector `[,@l]))
my-vector))
What does this sentence tell me about the vector I constructed?
We should really be super careful with these changes.
Michael.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 19 Apr 2020 22:25:01 GMT)
Full text and
rfc822 format available.
Message #63 received at 40671 <at> debbugs.gnu.org (full text, mbox):
> >> distinguish between constant objects (which the
> >> program should not change) and mutable objects
> >> (which the program can change).
> >
> > That's just not what "constant" means.
>
> What does "constant" mean to you? It's not clear.
Something that remains constant. You simply can't
change it - impossible.
The doc for `defconst' makes clear that it does _not_
define a constant, for example. In what way is what
it defines a variable and not a constant? The fact
that you _can_ change it. If you can change something
then it's not a constant.
The problem is that you're using "constant", NOT for
something that CANNOT be changed, but for something
that you SHOULD NOT try to change. Not the same thing.
> > And I suspect that your _uses_ of _not_ "mutable"
> > will still be for things that we really want to say
> > you probably _should not_ change, and not that
> > you _cannot_ change them.
>
> Your suspicion is correct.
So my suspicion is correct: you're misusing "not
mutable" to mean, not something that can't be
changed but something that probably shouldn't be
changed. See above: not mutable = constant.
> In the current emacs-27 documentation, "mutable"
> means you can change the object,
That contradicts your statement of my suspicion
being correct. If "mutable" means you can change
it (which is truly what it means) then "not mutable"
means you can't change it. It doesn't mean only
that you probably shouldn't change it.
It's the same point. mutable = changeable,
not mutable = constant (not changeable).
You're using "should not" in place of "cannot".
Which means you're also using "no reason not to"
in place of "can".
And the gotcha is precisely that in some cases
where you _can_, you probably _should not_.
> "constant" means you should not change it.
Again, a misuse. "Constant" means truly not mutable,
i.e., you _cannot_ change it.
The message you're giving is backward, or at least
unclear.
Don't say "constant". Say "don't try to change it".
Not because you can't change it (not because it's
constant), but because the code won't necessarily
do what you expect - it might change as you think,
or it might not. That's really the point, I think.
> It's intended to be documentation that is simple
> and consistent
IMO, it's neither. Simple is to just say that you
_cannot depend on_ `quote' (and some other constructs,
no doubt) returning a new object, especially in code
that looks like it would be evaluated multiple times.
And since you can't depend on this, don't. That's
the simple message: "don't do that, because it might
not do what you expect" (when byte-compiled, in
particular).
It might (IMO) be helpful to explain that for
interpreted Elisp source code what you see is what
you get (is that always true?), but the same is not
true for byte-compiled code. And `(quote (A B))'
is a good example.
We probably already say something like that (?) in
other contexts: byte-compiled code may change order
of evaluation or the number of times a subexpression
gets evaluated - for optimization. You can't count
on byte-code acting just like as source code from
which it's compiled would suggest.
> what they shouldn't do (try to change a constant)
No one tries to change a constant. The problem -
the gotcha - is that it's not always obvious when
your code is trying to change a constant. In
particular (but not only), beware of quoted lists.
> Of course the documentation could have a more-complex
> discussion of the various ways that an object could
> be "constant".
And somewhere in the doc that might be helpful, but
only if the particular cases documented are cases we
intend to keep as such. It can happen that we instead
decide to keep that in the dark ("just" implementation),
and we just document that whether XYZ is such a case is
"undefined" - so don't count on it acting as a constant
or not as a constant.
> The object could be in read-only memory enforced by
> the hardware and operating system,
As I said earlier, there's no need to say something's
a constant if it's actually enforced as a constant,
in the sense that an error is raised if you try to
modify it.
The only cases that are problematic are those where
you can think your code modifies something (anew)
when in fact it might not. That's the case we're
talking about wrt quoted list structure.
> > And places where you will likely say there's no
> > reason you _shouldn't_ change something will
> > likely give the impression that this is because
> > it is "mutable", and give the impression that
> > there's no reason you shouldn't change anything
> > that you _can_ change. This can give the
> > impression that if you _can_ change something
> > (the real meaning of "mutable") then there's no
> > reason you shouldn't change it.
>
> I'm not following.
By mischaracterizing not mutable as "should not be
changed" (instead of "cannot be changed"), you can
give the false impression that the opposite is true:
if something is mutable then there's no reason you
shouldn't change it.
Not that the latter follows logically from the former,
but by twisting the meaning of "mutable" all bets in
understanding are off.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 19 Apr 2020 22:42:01 GMT)
Full text and
rfc822 format available.
Message #66 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 4/19/20 2:57 PM, Michael Heerdegen wrote:
> I had a quick look at your changes. I agree that it would have been
> better to discuss before you start to install what you think you like.
Yes, in hindsight I suppose you're right. If you like I can revert the changes now.
> Before your changes the manual used the
> term "literal" objects, now you added a different wording "constant"
> vs. "mutable" that describes more or less the same thing.
Thanks, I hadn't recalled that use of "literal object" (in the Equality
Predicates) section. Although the two notions are related they're not identical.
For example, the reason one shouldn't modify byte-code objects is not the
sharing issue mentioned in Equality Predicates: it's because doing so can make
Emacs crash.
That being said, it would be helpful discuss the two notions in a unified way
rather than separately, as is the case now.
> Then some things you added are just wrong, at least in the generality
> you word them. As Drew said, `quote' doesn't always return constant
> objects, the special form just returns the OBJECT, whatever it is, when
> it is evaluated.
It depends on what one means by "constant" objects. If we uniformly changed that
word to "literal" would that remove the objection? For example, although
byte-code objects aren't normally what one would think of as being "literal", we
could simply define them to be "literal".
> | Vectors written with square brackets are constants and should not be
> | modified via @code{aset} or other destructive operations.
>
> (let ((l (list 1 2 3)))
> (let ((my-vector `[,@l]))
> my-vector))
>
> What does this sentence tell me about the vector I constructed?
Nothing, just as the documentation for splicing also says nothing about that
vector. These are both deficiencies in the documentation that should get fixed
(and in some form the deficiencies both predate the recent changes).
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 19 Apr 2020 22:52:01 GMT)
Full text and
rfc822 format available.
Message #69 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 4/19/20 3:24 PM, Drew Adams wrote:
> Don't say "constant". Say "don't try to change it".
That's too long and awkward a phrase for use in lots of places around the
manual. We need a simple noun phrase to describe the concept; this is
Documentation 101.
One possible substitute is "literal object", as Mattias pointed out. Another
possibility is "immutable object". Perhaps others might be better.
> The only cases that are problematic are those where
> you can think your code modifies something (anew)
> when in fact it might not.
No, that's not the only issue. If you modify some of these "constants" (or
"literal objects" or whatever term you like), the behavior is undefined: Emacs
can crash or remove your home directory or whatever. There is no checking.
> By mischaracterizing not mutable as "should not be
> changed" (instead of "cannot be changed"), you can
> give the false impression that the opposite is true:
> if something is mutable then there's no reason you
> shouldn't change it.
I don't see that false impression being given. But if it is being given,
presumably the problem could be fixed by appropriate wording changes. Specific
suggestions welcome.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 19 Apr 2020 23:47:01 GMT)
Full text and
rfc822 format available.
Message #72 received at 40671 <at> debbugs.gnu.org (full text, mbox):
Paul Eggert <eggert <at> cs.ucla.edu> writes:
> Yes, in hindsight I suppose you're right. If you like I can revert the
> changes now.
I can't estimate, for me it is enough if you are willing to revert if
there is no consent and we discuss all of this now.
> > Before your changes the manual used the
> > term "literal" objects, now you added a different wording "constant"
> > vs. "mutable" that describes more or less the same thing.
>
> Thanks, I hadn't recalled that use of "literal object" (in the
> Equality Predicates) section. Although the two notions are related
> they're not identical. For example, the reason one shouldn't modify
> byte-code objects is not the sharing issue mentioned in Equality
> Predicates: it's because doing so can make Emacs crash.
> That being said, it would be helpful discuss the two notions in a
> unified way rather than separately, as is the case now.
I would like to leave the suggestion of a good wording to someone like
Stefan, feeling not competent enough myself.
I have just the feeling sure if you simplify too much. Lisp has
reading, compiling, evaluation. When the reader reads something like
'(x y z), the (x y z) already produces the literal thing because the
reader transforms it into an object, contrarily to creation of objects
at run-time. The compiler can handle it differently. That's the main
difference. The quote comes into play when the thing gets evaluated.
When you evaluate the expression, the literal is returned. It could
also end up as part of a program, which was the pitfall case in the
initial report.
> > Then some things you added are just wrong, at least in the generality
> > you word them. As Drew said, `quote' doesn't always return constant
> > objects, the special form just returns the OBJECT, whatever it is, when
> > it is evaluated.
>
> It depends on what one means by "constant" objects. If we uniformly
> changed that word to "literal" would that remove the objection? For
> example, although byte-code objects aren't normally what one would
> think of as being "literal", we could simply define them to be
> "literal".
No, that's not (only) what I mean. Maybe you should remember how quote
is used in `defmacro's for example? Generally it's just a mean to
prevent evaluation. In your examples this returned the literal notated
after the quote, but it can be anything.
Or - about what do you speak? The part of the program being quoted, or
the thing "behind" the quote when the program is executed? When you
describe the return value of quote, the special form, in the docstring,
you are speaking about the latter, and then this is wrong, the return
value is the arbitrary OBJECT.
E.g.
(let ((l (list 1 2 3)))
`',l)
==> '(1 2 3)
If you evaluate this (the return value is a valid expression), `quote'
returns a list, but it's not a list literal. But if you try to modify
what the reader constructed after reading ",l", also a list (\, l),
you'll probably get a problem.
As a special case, quote can be used to create lists because Lisp
programs are lists and use list notation anyway. But that's only one
way of using it.
> > | Vectors written with square brackets are constants and should not be
> > | modified via @code{aset} or other destructive operations.
> > (let ((l (list 1 2 3)))
> > (let ((my-vector `[,@l]))
> > my-vector))
> > What does this sentence tell me about the vector I constructed?
>
> Nothing, just as the documentation for splicing also says nothing
> about that vector.
One could read your sentence as suggesting that `my-vector' would be
constant because square brackets are used to construct it. This was an
example to demonstrate where your wording is too vague in my opinion.
Michael.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Mon, 20 Apr 2020 00:25:02 GMT)
Full text and
rfc822 format available.
Message #75 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 4/19/20 4:45 PM, Michael Heerdegen wrote:
> I have just the feeling sure if you simplify too much. Lisp has
> reading, compiling, evaluation....
Yes, it can be complicated under the hood. The current section attempts to
document this conservatively, saying "If your program does this it'll be safe."
It does not attempt to document much of what happens if you step outside the
"safe" boundaries (i.e., if you attempt to modify "constants" - to use the
current terminology).
One can indeed imagine more-detailed documentation about what happens if you
modify constants. However, I didn't have the time or inclination to document the
details there, and on the whole I think this was the right decision. It's not a
win to greatly complicate the Elisp documentation to cover iffy edge-cases that
code shouldn't be exploring anyway. On the contrary, we should leave things
unspecified in this dangerous area, to give future implementers more freedom to
improve Emacs.
> (let ((l (list 1 2 3)))
> `',l)
>
> ==> '(1 2 3)
>
> If you evaluate this (the return value is a valid expression), `quote'
> returns a list, but it's not a list literal.
Sure, but one shouldn't be modifying that list. Once you hand a Lisp object to
'eval', modifying that object later ought to be a no-no even if the interpreter
happens to do something non-crashy now. Otherwise we're placing too many
constraints on the Lisp implementation (which can crash even now if you play
this sort of game).
>>> | Vectors written with square brackets are constants and should not be
>>> | modified via @code{aset} or other destructive operations.
>>> (let ((l (list 1 2 3)))
>>> (let ((my-vector `[,@l]))
>>> my-vector))
>>> What does this sentence tell me about the vector I constructed?
>>
>> Nothing, just as the documentation for splicing also says nothing
>> about that vector.
>
> One could read your sentence as suggesting that `my-vector' would be
> constant because square brackets are used to construct it. This was an
> example to demonstrate where your wording is too vague in my opinion.
OK, how about if we append the following sentence to that section:
As an exception to the above rules, a vector within a backquote construct
is not considered to be a constant if it contains a substitution or splice.
That is, the backquote causes the vector to (a) not be considered a constant,
(b) be newly created each time the backquote is evaluated, and (c) mutable. The
(a) and (b) parts fix problems that were already there in the longstanding
documentation; the (c) part is new.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Mon, 20 Apr 2020 00:54:01 GMT)
Full text and
rfc822 format available.
Message #78 received at 40671 <at> debbugs.gnu.org (full text, mbox):
Paul Eggert <eggert <at> cs.ucla.edu> writes:
> > (let ((l (list 1 2 3)))
> > `',l)
> > ==> '(1 2 3)
> > If you evaluate this (the return value is a valid expression),
> > `quote'
> > returns a list, but it's not a list literal.
>
> Sure, but one shouldn't be modifying that list. Once you hand a Lisp
> object to 'eval', modifying that object later ought to be a no-no even
> if the interpreter happens to do something non-crashy now.
But I can modify the list before handing it over to `eval',
e.g. replacing the `1' with `cons'.
And even when I eval the original list, I get just the same l as before:
(let ((l (list 1 2 3)))
`',l
(eq l (eval `',l)))
==> t.
AFAIU the problematic entities are the literal lists created by the
reader and the compiler.
> >>> (let ((l (list 1 2 3)))
> >>> (let ((my-vector `[,@l]))
> >>> my-vector))
> OK, how about if we append the following sentence to that section:
>
> As an exception to the above rules, a vector within a backquote construct
> is not considered to be a constant if it contains a substitution or splice.
> That is, the backquote causes the vector to (a) not be considered a
> constant, (b) be newly created each time the backquote is evaluated,
> and (c) mutable. The (a) and (b) parts fix problems that were already
> there in the longstanding documentation; the (c) part is new.
Here your perspective becomes complicated.
The Lisp reader reads the vector [,@l] while reading the program. That
vector is never used by the program, because already the expansion of
the code does not include a vector any more:
(macroexpand-all
'(let ((l (list 1 2 3)))
(let ((my-vector `[,@l]))
my-vector)))
==>
(let
((l (list 1 2 3)))
(let ((my-vector
(vconcat l)))
my-vector))
Only symbols, numbers, and lists.
Any other macro could do something similar, so backquote is not just an
exception, and was only an example that came to my mind first. If the
definition of backquote would try to modify the read [,@l] vector, this
vector of length 1, we would have a problem. But it only analyses this
vector to produce some other code that doesn't even contain a vector any
more.
We must distinguish between the objects created when a program is
read/compiled, i.e. the objects a program consists of (data and programs
are the same in Lisp, etc.), and the objects that that program actually
handles when it runs.
Michael.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Mon, 20 Apr 2020 03:24:02 GMT)
Full text and
rfc822 format available.
Message #81 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 4/19/20 5:53 PM, Michael Heerdegen wrote:
> Paul Eggert <eggert <at> cs.ucla.edu> writes:
>
>>> (let ((l (list 1 2 3)))
>>> `',l)
>>> ==> '(1 2 3)
>>> If you evaluate this (the return value is a valid expression),
>>> `quote'
>>> returns a list, but it's not a list literal.
>>
>> Sure, but one shouldn't be modifying that list. Once you hand a Lisp
>> object to 'eval', modifying that object later ought to be a no-no even
>> if the interpreter happens to do something non-crashy now.
>
> But I can modify the list before handing it over to `eval',
> e.g. replacing the `1' with `cons'.
Yes, that's fine. You can modify the list *before* handing it to eval, but it
should be off limits afterwards. That is, the manual doesn't say or imply that
the `,l yields a constant, so the result of the `,l is still modifiable. But
once you hand the list off to eval, watch out: you shouldn't modify it.
Another way to put it is: an object can start off mutable and later become
constant when you start using it as part of a program. Come to think of it,
perhaps this should be added to the Constants and Mutability section. Something
like the following patch, perhaps.
diff --git a/doc/lispref/objects.texi b/doc/lispref/objects.texi
index abd258eb53..dd7eaf5ae4 100644
--- a/doc/lispref/objects.texi
+++ b/doc/lispref/objects.texi
@@ -2400,6 +2400,11 @@ Constants and Mutability
call @code{(make-string 3 ?a)} yields a mutable string that can be
changed via later calls to @code{aset}.
+ A mutable object can become constant if it is passed to the
+@code{eval} function, because you should not modify an object that is
+being or might be executed. The reverse does not occur: constant
+objects should stay constant.
+
Trying to modify a constant variable signals an error
(@pxref{Constant Variables}).
A program should not attempt to modify other types of constants because the
> And even when I eval the original list, I get just the same l as before:
It's OK that the interpreter does that. But you shouldn't *modify* the original
list after handing it off to eval; it might work and it might not. You shouldn't
even rely on the interpreter giving you the same l as before, for that matter;
that's an implementation detail that is not documented and should not be
documented, any more than we should document the fact that (let ((x (cos 1.5)))
(eq x (+ x))) returns t in Emacs 27.
> We must distinguish between the objects created when a program is
> read/compiled, i.e. the objects a program consists of (data and programs
> are the same in Lisp, etc.), and the objects that that program actually
> handles when it runs.
Yes, and the basic idea is that one cannot reliably modify the objects that a
program consists of while running the program; it's not safe. (All we need to do
is to word this correctly and clearly. :-)
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Mon, 20 Apr 2020 03:37:01 GMT)
Full text and
rfc822 format available.
Message #84 received at 40671 <at> debbugs.gnu.org (full text, mbox):
Paul Eggert <eggert <at> cs.ucla.edu> writes:
> + A mutable object can become constant if it is passed to the
> +@code{eval} function, because you should not modify an object that is
> +being or might be executed. The reverse does not occur: constant
> +objects should stay constant.
> +
I don't know if what you say about the interpreter is true (I hope it is
not), and I must really go to bed now, but "you should not modify an
object that is being or might be executed" - isn't that quite common
when calculating macro expansions (which, typically, are executed)?
Michael.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Mon, 20 Apr 2020 05:33:01 GMT)
Full text and
rfc822 format available.
Message #87 received at 40671 <at> debbugs.gnu.org (full text, mbox):
> > Don't say "constant". Say "don't try to change it".
>
> That's too long and awkward a phrase for use in lots
> of places around the manual. We need a simple noun
> phrase to describe the concept; this is Documentation 101.
Giving it an undefined/unexplained name doesn't describe
it at all.
Giving it an existing name (e.g. "constant"), which means
something else, indirectly describes it incorrectly.
Why do we need to say this in "lots of places around
the manual"? Explain the gotcha in one place, and if
need to refer to that explanation elsewhere then do so
(link).
> One possible substitute is "literal object", as Mattias
> pointed out. Another possibility is "immutable object".
> Perhaps others might be better.
As I explained, none of those correspond to what I think
the gotcha is.
> > The only cases that are problematic are those where
> > you can think your code modifies something (anew)
> > when in fact it might not.
>
> No, that's not the only issue. If you modify some of
> these "constants" (or "literal objects" or whatever
> term you like), the behavior is undefined: Emacs can
> crash or remove your home directory or whatever.
If Emacs can crash or remove your home directory,
that's a bug, IMO. We don't document bugs, and we
certainly shouldn't let Emacs crash and just tell
you not to do XYZ because of that.
Saying the behavior in some case is not defined means
(usually) that we're not going to support/guarantee
what the behavior is in that case, and we're not
going to detail/say what it is. Saying some behavior
is undefined is never (in my experience) done knowing
it crashes the program.
> There is no checking.
If that's what's meant then say that.
The explanation of the gotcha should, IMO, include a
simple example of quoting a list: '(1 2 3), and then
modifying some of that list structure.
Say what can happen, e.g. with byte-compilation, and
how that's different from what one might expect if
'(1 2 3) is incorrectly thought of as always creating
new list structure each time that code is evaluated.
Maybe say that just reading the '(1 2 3) creates a
list, and that thereafter that same list is used by
the byte compiler.
The point in showing a simple list example is to
help make clear what's going on. More importantly,
the quoted-list version of the gotcha is the common
one.
I don't want to belabor this. If you don't get what
I'm saying then perhaps someone else will be willing
to explain it better than I. Or if what I've said
is unclear also to others, or is judged wrong, then
please forget about it.
To me, it's pretty simple in terms of effect: You
write '(1 2 3), and you mistakenly think you've
essentially written code that does what (list 1 2 3)
does: creates a new list each time the code it's in
gets evaluated.
Maybe that '(1 2 3) code is in a context where it
(looks like it) gets evaluated more than once.
You think you're getting a new list (new conses)
each time. Some other code modifies the list (e.g.
using setcar). You think that code is modifying
a new list each time, but it's not - it's modifying
the same cons. Gotcha.
There are no doubt other scenarios that exhibit
essentially the same gotcha. But I don't think
it's necessary to detail them all. What's needed
is to provide the warning, some general description
of the problem, and/or a simple example (using a
list).
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Mon, 20 Apr 2020 05:55:02 GMT)
Full text and
rfc822 format available.
Message #90 received at 40671 <at> debbugs.gnu.org (full text, mbox):
> Another way to put it is: an object can start off mutable and later
> become constant
I don't like that formulation at all. You must
instead be talking about different objects. A
mutable object cannot be changed to a constant,
AFAIK.
I think the gotcha we're talking about is thinking
that a particular object is mutable when it's not.
> +A mutable object can become constant if it is passed to the
> +@code{eval} function,
How so? What's an example?
> +because you should not modify an object that is
> +being or might be executed.
I don't think it even makes any sense to say that
something can become something else _because you
should not do XYZ_. That parses - is grammatical,
but it makes no sense.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Mon, 20 Apr 2020 06:03:01 GMT)
Full text and
rfc822 format available.
Message #93 received at 40671 <at> debbugs.gnu.org (full text, mbox):
> the reason one shouldn't modify byte-code objects
> is ... because doing so can make Emacs crash.
Really? If something can make Emacs crash it means
there's a bug; that's all. If there's a bug we
shouldn't document the bugged behavior (it should
be fixed), and we especially shouldn't, in the doc,
say "you should [not] do XYZ" because it can make
Emacs crash.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Mon, 20 Apr 2020 14:11:01 GMT)
Full text and
rfc822 format available.
Message #96 received at 40671 <at> debbugs.gnu.org (full text, mbox):
> Cc: mattiase <at> acm.org, 40671 <at> debbugs.gnu.org, ke.vigouroux <at> laposte.net
> From: Paul Eggert <eggert <at> cs.ucla.edu>
> Date: Sun, 19 Apr 2020 13:45:07 -0700
>
> > For example, the node "Sets and Lists" now sometimes uses literal
> > lists and sometimes non-literal ones -- without any explanation why.
> > Likewise in "Association Lists" and "Sequence Functions".
>
> This was in response to your request to not change examples if the examples
> didn't strictly need the changes. Although I preferred Mattias's original
> proposal because it switched to the (list ...) style more uniformly, the patch I
> installed mixed the '(...) and (list ...) styles because I thought that was what
> you were asking for.
>
> I installed the attached patch, which attempts to address this issue by adding
> comments that try to explain why (list ...) is needed sometimes.
This is better, thanks. Although my feeling that we complicated what
used to be a simple section is still here.
> However, in
> hindsight perhaps we should go back to the style used in Mattias's proposal, as
> it's simpler and more consistent and doesn't distract the reader from the focus
> of the documentation. Going back to Mattias's style would let us remove some of
> the comments that the attached patch inserts.
I think consistency should take a back seat in these situations.
Clarity and easiness of reading and understanding are much more
important.
> As you note, it's not essential that the list be modifiable in this particular
> example. That being said, the documentation should not suggest that it's OK to
> use a destructive operation like delq on a constant, so further improvements
> would be helpful here if someone can find the time.
But that's exactly the disagreement between us: you think that each
example must be perfect in that it follows all of the principles ever
mentioned anywhere in the manual, and shouldn't go anywhere near the
places which we explain elsewhere are, or might be, dangerous. The
problem with that is that if you want to be absolutely correct and
rigorous, you will more often than not be unable to say anything, or
will produce code samples that are so arcane to the beginner that they
will squarely miss their point. Witness your dialogue with Michael
Heerdegen about related issues.
I think there's no need to assign such crucial importance to every
example. If it is easy to make the example more correct by small
changes, we should consider doing that. But adding the likes of
copy-list to an example that's supposed to show how to delete a list
member is IMO a terrible overkill, and makes the example harder to
understand: a reader who just learned about making and modifying lists
suddenly needs to know what copy-list does (e.g., is it a deep copy or
not?). IMO and IME, this kind of rigor is self-defeating, unless it
comes in a special section marked "Advanced" or somesuch.
Bottom line: IMO the manual should introduce the material gradually;
it is okay to defer some subtle aspects to later sections, and
initially simply disregard them. E.g., in a section that describes
arithmetic operators like '+' in C to someone who is supposed to be a
C beginner, you won't right away talk about integer overflow and the
subsequent danger of crashing the system, and you won't tell the
reader "don't ever use '+', use INT_ADD_WRAPV instead", nor will you
replace examples that use '+' with that macro, would you?
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Tue, 21 Apr 2020 01:26:01 GMT)
Full text and
rfc822 format available.
Message #99 received at 40671 <at> debbugs.gnu.org (full text, mbox):
Michael Heerdegen <michael_heerdegen <at> web.de> writes:
> > Yes, in hindsight I suppose you're right. If you like I can revert the
> > changes now.
>
> I can't estimate, for me it is enough if you are willing to revert if
> there is no consent and we discuss all of this now.
But regardless of the impression that your chosen course of action gives
(my own course of action often gives bad impressions for other reasons,
and I don't mean to say that my impression is only bad, just a bit
like...blindside?), it is harder now to review and estimate your changes
in sum, and this is not good for the exchange of views that I think
would be very valuable in this case.
Michael.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Tue, 21 Apr 2020 02:21:02 GMT)
Full text and
rfc822 format available.
Message #102 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 4/20/20 6:25 PM, Michael Heerdegen wrote:
> it is harder now to review and estimate your changes
> in sum
Yes, software archaeology can be a bit of a pain. You could try running this
shell command:
git diff
eebfb72c906755c0a80d92c11deee7ac9faf5f4b^..05089a4d65831c5e873956f5f2d92a3d5672d405
-- doc/lispintro doc/lispref/elisp.texi doc/lispref/eval.texi
doc/lispref/keymaps.texi doc/lispref/lists.texi doc/lispref/objects.texi
doc/lispref/sequences.texi doc/lispref/strings.texi
though if the doc evolves further the command could get longer....
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Wed, 22 Apr 2020 06:31:02 GMT)
Full text and
rfc822 format available.
Message #105 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 4/19/20 8:36 PM, Michael Heerdegen wrote:
> Paul Eggert <eggert <at> cs.ucla.edu> writes:
>
>> + A mutable object can become constant if it is passed to the
>> +@code{eval} function, because you should not modify an object that is
>> +being or might be executed. The reverse does not occur: constant
>> +objects should stay constant.
>> +
>
> I don't know if what you say about the interpreter is true (I hope it is
> not),
Unfortunately it is true, for performance reasons: you can't reliably change a
form that is currently being executed by the Lisp interpreter. This is because
the interpreter can cache parts of such forms, or can check forms and later
execute them under the assumption that the checks succeeded, and if the caches
are invalid or the earlier checks no longer apply then Emacs can dump core or worse.
> "you should not modify an
> object that is being or might be executed" - isn't that quite common
> when calculating macro expansions (which, typically, are executed)?
You can modify the object before giving it to 'eval' (and macro expansion can do
modifications like that), but you shouldn't modify it while it's being evaluated.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Wed, 22 Apr 2020 17:22:02 GMT)
Full text and
rfc822 format available.
Message #108 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 4/19/20 10:54 PM, Drew Adams wrote:
> A mutable object cannot be changed to a constant
Sure they can. This idea is common in other languages, e.g., see Object.freeze
method in JavaScript. There's no reason Emacs Lisp can't use the idea.
>> +A mutable object can become constant if it is passed to the
>> +@code{eval} function,
>
> How so? What's an example?
(let ((x (make-string 1 ?a)))
(eval `(progn
(defun foo ()
(let ((a ,x))
(aset x 0 ?b)
(list a "a" (equal a "a"))))
(byte-compile 'foo)
(foo))))
This code is not well-formed because it modifies the string x after passing it
to eval (such strings should be constant). As a result, the behavior of the
program is unpredictable. On master it currently yields ("b" "b" t) but there's
no guarantee of this.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Wed, 22 Apr 2020 17:37:01 GMT)
Full text and
rfc822 format available.
Message #111 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 4/19/20 10:32 PM, Drew Adams wrote:
> Giving it an existing name (e.g. "constant"), which means
> something else
In informal language the word "constant" can mean different things to different
people. If the manual defines the word "constant" to mean "an object whose value
should never change" and it uses that word consistently, then that's OK; the
manual's terminology corresponds closely enough to the informal one. Of course
if we can come up with a better phrase than "constant" then we should use that;
but so far we haven't seemed to be able to.
> Explain the gotcha in one place, and if
> need to refer to that explanation elsewhere then do so
> (link).
Yes, that's what's done now.
> If Emacs can crash or remove your home directory,
> that's a bug, IMO. We don't document bugs
We should advise Lisp programmers about what they can do safely, and what they
should not do due to Emacs's unfortunate limitations. We already do this in
other dangerous areas (e.g., what happens if you increase max-lisp-eval-depth
too far), and we should do it in this dangerous area too. You're right that we
needn't document in detail what happens if a Lisp program does unsafe things.
> we certainly shouldn't let Emacs crash
If we can fix the problem that would be better, yes. However, it's not practical
to do that for Emacs 27 because it is so close to release and any fix would
require major surgery. It's not clear that it's practical to fix things even for
Emacs 28.
> Saying some behavior
> is undefined is never (in my experience) done knowing
> it crashes the program.
Welcome to the wonderful world of undefined behavior. I'm joking of course;
undefined behavior is not a good thing. But here we are.
> Maybe say that just reading the '(1 2 3) creates a
> list, and that thereafter that same list is used by
> the byte compiler.
Thanks, I'll add something along those lines.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Thu, 23 Apr 2020 00:51:02 GMT)
Full text and
rfc822 format available.
Message #114 received at 40671 <at> debbugs.gnu.org (full text, mbox):
Paul Eggert <eggert <at> cs.ucla.edu> writes:
> > A mutable object cannot be changed to a constant
>
> Sure they can. This idea is common in other languages, e.g., see
> Object.freeze method in JavaScript. There's no reason Emacs Lisp can't
> use the idea.
Ok. I still have questions and objections about your additions:
+ A mutable object can become constant if it is passed to the
+@code{eval} function, because you should not modify an object that is
+being or might be executed. The reverse does not occur: constant
+objects should stay constant.
`eval' is used quite rarely. Can what you describe happen under other
circumstances, or does it only happen to `eval'? E.g. what about this
case for example:
(let ((l (list 1 2 3)))
(funcall (lambda () l)))
Has the list become a constant?
I ask because the sub-clause "because you should not modify an object
that is being or might be executed" is totally different statement than
that about `eval'. A list literal (1 2 3) or a string as in the example
in your answer to Drew are surely not executed, as they are not valid
forms. They are part of a program. But anything a macro generates also
becomes part of a program. Maybe I misread "might be executed" as
"might be executed in the future" and you actually meant something like
"might (currently) be executed (as part of the expression the
interpreter currently executes).
BTW, speaking about Lisp the term "evaluate" is probably preferable to
"execute" I think.
Thanks,
Michael.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Fri, 24 Apr 2020 02:38:02 GMT)
Full text and
rfc822 format available.
Message #117 received at 40671 <at> debbugs.gnu.org (full text, mbox):
[[[ To any NSA and FBI agents reading my email: please consider ]]]
[[[ whether defending the US Constitution against all enemies, ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]
It seems strange to use the terms "constant" and "mutable" to describe
whether modifying its contents is something you had better avoid.
I think people will find that terminology confusing. Normally
"mutable" means that you CAN change it, not that it is OK to change it.
--
Dr Richard Stallman
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Fri, 24 Apr 2020 15:09:02 GMT)
Full text and
rfc822 format available.
Message #120 received at 40671 <at> debbugs.gnu.org (full text, mbox):
> It seems strange to use the terms "constant" and "mutable" to describe
> whether modifying its contents is something you had better avoid.
> I think people will find that terminology confusing. Normally
> "mutable" means that you CAN change it, not that it is OK to change it.
Yes. Precisely what I, Michael, and others said.
The message should be one of advice/guidance:
explaining a gotcha, or at least suggesting what
to avoid.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Fri, 24 Apr 2020 16:40:02 GMT)
Full text and
rfc822 format available.
Message #123 received at 40671 <at> debbugs.gnu.org (full text, mbox):
24 apr. 2020 kl. 04.36 skrev Richard Stallman <rms <at> gnu.org>:
> It seems strange to use the terms "constant" and "mutable" to describe
> whether modifying its contents is something you had better avoid.
> I think people will find that terminology confusing. Normally
> "mutable" means that you CAN change it, not that it is OK to change it.
That is an interesting point. What is the difference between CANNOT and SHOULD NOT, operationally? To the user, nothing; there is no gain from disobeying our advice. Implementation-wise, it's whether there are strong checks or not. (For example, in C you should not read from already freed memory, but there is no mechanism actually preventing you from doing so.)
It's useful to have the option to add strong checks, so that (setcar '(1 . 2) 3) throws an error. Then, what used to be SHOULD NOT turns into CANNOT, but the attentive user has no reason to change behaviour.
Of course the real world is messy and people sometimes have code that breaks the rules but still seem to work. There would need to be a transition period, and a switch to run in a permissive mode.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Fri, 24 Apr 2020 16:47:02 GMT)
Full text and
rfc822 format available.
Message #126 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 24.04.2020 19:39, Mattias Engdegård wrote:
> That is an interesting point. What is the difference between CANNOT and SHOULD NOT, operationally? To the user, nothing; there is no gain from disobeying our advice.
The difference is at runtime, obviously. And the problem is using the
words in a way that differs from other programming languages, for instance.
> It's useful to have the option to add strong checks, so that (setcar '(1 . 2) 3) throws an error. Then, what used to be SHOULD NOT turns into CANNOT, but the attentive user has no reason to change behaviour.
*If* we do that, we could call them constants. But I imagine we never
will, for backward compatibility reasons. Emacs core itself modifies
these "constants" at runtime in quite a few places, I'm sure.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Fri, 24 Apr 2020 17:21:01 GMT)
Full text and
rfc822 format available.
Message #129 received at 40671 <at> debbugs.gnu.org (full text, mbox):
> > It seems strange to use the terms "constant" and "mutable" to
> > describe whether modifying its contents is something you had
> > better avoid. I think people will find that terminology
> > confusing. Normally "mutable" means that you CAN change it,
> > not that it is OK to change it.
>
> What is the difference between CANNOT and
> SHOULD NOT, operationally? To the user, nothing; there is no gain from
> disobeying our advice.
No. To the user: something. And the negative
effects might not be immediately noticeable.
If we say that you can't modify XYZ there's no
need for you to pay attention, learn about the
gotcha, and try to avoid modifying XYZ.
The burden here is on the user (unfortunately).
Emacs Lisp doesn't protect you from doing what
you'd be told you "cannot" do. It's up to you
to know when you might be stumbling onto this
pitfall and avoid it.
Telling users they _can't_ fall into this pit
is like telling someone it's impossible for their
car to go through a red light. Nope, they're the
driver, and the message should be, "Don't drive
through a red light."
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sat, 25 Apr 2020 01:59:01 GMT)
Full text and
rfc822 format available.
Message #132 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 4/24/20 8:08 AM, Drew Adams wrote:
> The message should be one of advice/guidance:
> explaining a gotcha, or at least suggesting what
> to avoid.
That's what the current emacs-27 manual does, or tries to do. If it doesn't do
so clearly enough, specific suggestions for improving the wording would be helpful.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sat, 25 Apr 2020 02:22:02 GMT)
Full text and
rfc822 format available.
Message #135 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 4/24/20 9:46 AM, Dmitry Gutov wrote:
> On 24.04.2020 19:39, Mattias Engdegård wrote:
>> That is an interesting point. What is the difference between CANNOT and SHOULD
>> NOT, operationally? To the user, nothing; there is no gain from disobeying our
>> advice.
>
> The difference is at runtime, obviously. And the problem is using the words in a
> way that differs from other programming languages, for instance.
That depends on what other programming languages we're talking about. The
current use of 'constant' in the manual corresponds reasonably closely to
'const' objects in C and C++.
>> It's useful to have the option to add strong checks, so that (setcar '(1 . 2)
>> 3) throws an error. Then, what used to be SHOULD NOT turns into CANNOT, but
>> the attentive user has no reason to change behaviour.
>
> *If* we do that, we could call them constants. But I imagine we never will, for
> backward compatibility reasons. Emacs core itself modifies these "constants" at
> runtime in quite a few places, I'm sure.
Actually Emacs formerly was more careful about this sort of thing: more objects
were constant and Emacs reliably signaled an error if you tried to change them.
If we brought back this feature we'd actually be more backwards-compatible than
we already are, at least in some sense. I expect it'd be a good thing to do if
it didn't hurt performance, as it should help reliability/safety a bit.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sat, 25 Apr 2020 02:23:02 GMT)
Full text and
rfc822 format available.
Message #138 received at 40671 <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
On 4/22/20 5:49 PM, Michael Heerdegen wrote:
> + A mutable object can become constant if it is passed to the
> +@code{eval} function, because you should not modify an object that is
> +being or might be executed. The reverse does not occur: constant
> +objects should stay constant.
>
> `eval' is used quite rarely. Can what you describe happen under other
> circumstances, or does it only happen to `eval'? E.g. what about this
> case for example:
>
> (let ((l (list 1 2 3)))
> (funcall (lambda () l)))
>
> Has the list become a constant?
No, because the list is not part of the expression that is being evaluated.
However, something like this could cause trouble:
(let ((l (list 'lambda '(x) '(setcdr l x))))
(eval (list l l)))
because it modifies the list l while it is evaluating it. (As it happens, this
code behaves differently in Emacs 26 than it does in Emacs 27 - that's what you
can get with undefined behavior....)
> Maybe I misread "might be executed" as
> "might be executed in the future" and you actually meant something like
> "might (currently) be executed (as part of the expression the
> interpreter currently executes).
>
> BTW, speaking about Lisp the term "evaluate" is probably preferable to
> "execute" I think.
Both good points. The word "executed" is already gone from the manual, and I
installed the attached patch to try to address the other point.
[0001-Tweak-mutability-doc-a-bit-more.patch (text/x-patch, attachment)]
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sat, 25 Apr 2020 02:41:01 GMT)
Full text and
rfc822 format available.
Message #141 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 25.04.2020 05:21, Paul Eggert wrote:
> That depends on what other programming languages we're talking about. The
> current use of 'constant' in the manual corresponds reasonably closely to
> 'const' objects in C and C++.
Since we're talking about non-scalar values, do you mean constant
pointers to (generally) mutable objects? Or a constant aggregate of
mutable objects?
When a value is constant in C or C++, you can't change it.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sat, 25 Apr 2020 03:21:02 GMT)
Full text and
rfc822 format available.
Message #144 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 4/24/20 7:40 PM, Dmitry Gutov wrote:
>> That depends on what other programming languages we're talking about. The
>> current use of 'constant' in the manual corresponds reasonably closely to
>> 'const' objects in C and C++.
>
> Since we're talking about non-scalar values, do you mean constant pointers to
> (generally) mutable objects? Or a constant aggregate of mutable objects?
Neither. I mean a constant object, e.g., the array of chars denoted by the
string literal "abc" in C.
> When a value is constant in C or C++, you can't change it.
Yes, you can't change it in a portable program, because if you attempt to change
it the resulting behavior is undefined. The attempt might succeed so that the
"constant" is changed, or you might get a core dump, or you might get an
exception, or something else might happen.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sat, 25 Apr 2020 03:39:02 GMT)
Full text and
rfc822 format available.
Message #147 received at 40671 <at> debbugs.gnu.org (full text, mbox):
[[[ To any NSA and FBI agents reading my email: please consider ]]]
[[[ whether defending the US Constitution against all enemies, ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]
> That is an interesting point. What is the difference between
> CANNOT and SHOULD NOT, operationally? To the user, nothing; there
> is no gain from disobeying our advice.
It makes a big practical difference to programmers.
CANNOT means "If you try to chsnge it, it won't change",
and probably also "That will trigger a diagnostic."
SHOULOD NOT means "if you try to chsnge it, it will give you no
diagnostic and the value will seem to have changed, but afterward
bizarre things may happen."
--
Dr Richard Stallman
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sat, 25 Apr 2020 06:01:01 GMT)
Full text and
rfc822 format available.
Message #150 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On Apr 24 2020, Paul Eggert wrote:
> diff --git a/doc/lispref/objects.texi b/doc/lispref/objects.texi
> index 1eda94ab63..b4e9ff4411 100644
> --- a/doc/lispref/objects.texi
> +++ b/doc/lispref/objects.texi
> @@ -2401,8 +2401,8 @@ Constants and Mutability
> call @code{(make-string 3 ?a)} yields a mutable string that can be
> changed via later calls to @code{aset}.
>
> - A mutable object can become constant if it is passed to the
> -@code{eval} function, because a program should not modify an object
> + A mutable object can become constant if it is part of an expression
> +that is evaluated, because a program should not modify an object
> that is being evaluated. The reverse does not occur: constant objects
"that is evaluated ... that is being evaluated" is saying the same thing
twice.
Andreas.
--
Andreas Schwab, schwab <at> linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510 2552 DF73 E780 A9DA AEC1
"And now for something completely different."
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sat, 25 Apr 2020 18:24:02 GMT)
Full text and
rfc822 format available.
Message #153 received at 40671 <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
On 4/24/20 11:00 PM, Andreas Schwab wrote:
> "that is evaluated ... that is being evaluated" is saying the same thing
> twice.
Thanks for catching that; I installed the attached.
[0001-Remove-doc-duplication.patch (text/x-patch, attachment)]
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sat, 25 Apr 2020 18:27:01 GMT)
Full text and
rfc822 format available.
Message #156 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 4/24/20 8:38 PM, Richard Stallman wrote:
> SHOULOD NOT means "if you try to change it, it will give you no
> diagnostic and the value will seem to have changed, but afterward
> bizarre things may happen."
Here SHOULD NOT simply means "if you try to change it, afterward bizarre things
may happen". This includes the meaning you gave, and also includes some other
meanings.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sat, 25 Apr 2020 19:31:02 GMT)
Full text and
rfc822 format available.
Message #159 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 25.04.2020 06:20, Paul Eggert wrote:
>> When a value is constant in C or C++, you can't change it.
> Yes, you can't change it in a portable program, because if you attempt to change
> it the resulting behavior is undefined. The attempt might succeed so that the
> "constant" is changed, or you might get a core dump, or you might get an
> exception, or something else might happen.
Might succeed? Will it even compile?
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 26 Apr 2020 03:50:02 GMT)
Full text and
rfc822 format available.
Message #162 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 4/25/20 12:30 PM, Dmitry Gutov wrote:
> On 25.04.2020 06:20, Paul Eggert wrote:
>>> When a value is constant in C or C++, you can't change it.
>> Yes, you can't change it in a portable program, because if you attempt to change
>> it the resulting behavior is undefined. The attempt might succeed so that the
>> "constant" is changed, or you might get a core dump, or you might get an
>> exception, or something else might happen.
>
> Might succeed? Will it even compile?
Yes, although the C/C++ program must type-check and satisfy all other static
constraints of course (otherwise it won't compile). Here's a simple example:
#include <string.h>
int main (void) { return !strcpy ("a", "b"); }
This function attempts to modify the "a" string constant, so it might dump core,
or might return 0, or might do other things.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 26 Apr 2020 14:04:01 GMT)
Full text and
rfc822 format available.
Message #165 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 26.04.2020 06:49, Paul Eggert wrote:
>> Might succeed? Will it even compile?
> Yes, although the C/C++ program must type-check and satisfy all other static
> constraints of course (otherwise it won't compile). Here's a simple example:
>
> #include <string.h>
> int main (void) { return !strcpy ("a", "b"); }
>
> This function attempts to modify the "a" string constant, so it might dump core,
> or might return 0, or might do other things.
g++ string_const.c++
string_const.c++: In function ‘int main()’:
string_const.c++:2:35: warning: ISO C++ forbids converting a string
constant to ‘char*’ [-Wwrite-strings]
2 | int main (void) { return !strcpy ("a", "b"); }
I have no idea why it only shows a compile-time warning (probably
because of backward-compatibility concerns because in C a string is
*not* a const, just a source of undefined behavior), but the warning, at
least, is there for the user to see. Not just in the manual.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 26 Apr 2020 14:20:02 GMT)
Full text and
rfc822 format available.
Message #168 received at 40671 <at> debbugs.gnu.org (full text, mbox):
> From: Dmitry Gutov <dgutov <at> yandex.ru>
> Date: Sun, 26 Apr 2020 17:03:38 +0300
> Cc: Michael Heerdegen <michael_heerdegen <at> web.de>, ke.vigouroux <at> laposte.net,
> 40671 <at> debbugs.gnu.org
>
> > #include <string.h>
> > int main (void) { return !strcpy ("a", "b"); }
> >
> > This function attempts to modify the "a" string constant, so it might dump core,
> > or might return 0, or might do other things.
>
> g++ string_const.c++
> string_const.c++: In function ‘int main()’:
> string_const.c++:2:35: warning: ISO C++ forbids converting a string
> constant to ‘char*’ [-Wwrite-strings]
> 2 | int main (void) { return !strcpy ("a", "b"); }
Did you try compiling that as a C program, not a C++ program?
If I force the C compiler to use -Wwrite-strings, then I get:
gcc -Wwrite-strings string_const.c
string_const.c: In function 'main':
string_const.c:2:35: warning: passing argument 1 of 'strcpy' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
int main (void) { return !strcpy ("a", "b"); }
^~~
In file included from string_const.c:1:0:
d:\usr\include\string.h:79:40: note: expected 'char *' but argument is of type 'const char *'
_CRTIMP __cdecl __MINGW_NOTHROW char *strcpy (char *, const char *);
^~~~~~
but even that goes away if I modify the program as follows:
#include <string.h>
int main (void) { return !strcpy ((char *)"a", "b"); }
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 26 Apr 2020 14:36:02 GMT)
Full text and
rfc822 format available.
Message #171 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 26.04.2020 17:19, Eli Zaretskii wrote:
> Did you try compiling that as a C program, not a C++ program?
As C++.
From what I understand, in C string literals are not "const", it's just
UB to modify them.
> but even that goes away if I modify the program as follows:
>
> #include <string.h>
> int main (void) { return !strcpy ((char *)"a", "b"); }
If you go out of your way to avoid warnings, then indeed, the compiler
won't show them.
And typecasts are an easy way to turn compilation errors into runtime
errors, in general.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 26 Apr 2020 15:47:02 GMT)
Full text and
rfc822 format available.
Message #174 received at 40671 <at> debbugs.gnu.org (full text, mbox):
> Cc: eggert <at> cs.ucla.edu, mattiase <at> acm.org, rms <at> gnu.org,
> michael_heerdegen <at> web.de, ke.vigouroux <at> laposte.net, 40671 <at> debbugs.gnu.org
> From: Dmitry Gutov <dgutov <at> yandex.ru>
> Date: Sun, 26 Apr 2020 17:34:56 +0300
>
> > #include <string.h>
> > int main (void) { return !strcpy ((char *)"a", "b"); }
>
> If you go out of your way to avoid warnings, then indeed, the compiler
> won't show them.
>
> And typecasts are an easy way to turn compilation errors into runtime
> errors, in general.
I think this shows the difference between CANNOT and SHOULD NOT, wrt
constants.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 26 Apr 2020 16:03:02 GMT)
Full text and
rfc822 format available.
Message #177 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 26.04.2020 18:46, Eli Zaretskii wrote:
> I think this shows the difference between CANNOT and SHOULD NOT, wrt
> constants.
I'm not sure I understand the analogy.
Anyway, C and C++ have notoriously tricky semantics in edge cases. It's
probably not a good idea to use either of them as example for Emacs Lisp.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 26 Apr 2020 16:59:01 GMT)
Full text and
rfc822 format available.
Message #180 received at 40671 <at> debbugs.gnu.org (full text, mbox):
> Cc: ke.vigouroux <at> laposte.net, eggert <at> cs.ucla.edu, 40671 <at> debbugs.gnu.org,
> michael_heerdegen <at> web.de, mattiase <at> acm.org, rms <at> gnu.org
> From: Dmitry Gutov <dgutov <at> yandex.ru>
> Date: Sun, 26 Apr 2020 19:02:05 +0300
>
> On 26.04.2020 18:46, Eli Zaretskii wrote:
> > I think this shows the difference between CANNOT and SHOULD NOT, wrt
> > constants.
>
> I'm not sure I understand the analogy.
That program demonstrates that in C one CAN change a "constant"
array. But one definitely SHOULD NOT do that.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 26 Apr 2020 17:40:02 GMT)
Full text and
rfc822 format available.
Message #183 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 26.04.2020 19:58, Eli Zaretskii wrote:
> That program demonstrates that in C one CAN change a "constant"
> array.
When you first change it to a "non-constant" one, as far as the compiler
is concerned? It's an escape hatch. The same way you "can" funcall a string:
int main (void) {
return ((int(*) (int))"abc")(1);
}
It will blow up at runtime, of course.
Neither will be the case with "constant" Lisp forms we are talking
about. No runtime errors (only subtle, hard to investigate bugs from
time to time), and no compilation warnings. The only warnings at all
will be in the manual.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 26 Apr 2020 18:16:02 GMT)
Full text and
rfc822 format available.
Message #186 received at 40671 <at> debbugs.gnu.org (full text, mbox):
> Cc: ke.vigouroux <at> laposte.net, eggert <at> cs.ucla.edu, 40671 <at> debbugs.gnu.org,
> michael_heerdegen <at> web.de, mattiase <at> acm.org, rms <at> gnu.org
> From: Dmitry Gutov <dgutov <at> yandex.ru>
> Date: Sun, 26 Apr 2020 20:39:38 +0300
>
> int main (void) {
> return ((int(*) (int))"abc")(1);
> }
>
> It will blow up at runtime, of course.
But the previous program will not necessarily blow up at runtime.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 26 Apr 2020 18:33:02 GMT)
Full text and
rfc822 format available.
Message #189 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 26.04.2020 21:14, Eli Zaretskii wrote:
>> Cc: ke.vigouroux <at> laposte.net, eggert <at> cs.ucla.edu, 40671 <at> debbugs.gnu.org,
>> michael_heerdegen <at> web.de, mattiase <at> acm.org, rms <at> gnu.org
>> From: Dmitry Gutov <dgutov <at> yandex.ru>
>> Date: Sun, 26 Apr 2020 20:39:38 +0300
>>
>> int main (void) {
>> return ((int(*) (int))"abc")(1);
>> }
>>
>> It will blow up at runtime, of course.
>
> But the previous program will not necessarily blow up at runtime.
"not necessarily" is a damnably low qualifier.
My point is, that program is using the same instrument as this one,
which *will* blow up at runtime. And the instrument is "making the
compiler shut up".
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 26 Apr 2020 18:43:02 GMT)
Full text and
rfc822 format available.
Message #192 received at 40671 <at> debbugs.gnu.org (full text, mbox):
> Cc: ke.vigouroux <at> laposte.net, eggert <at> cs.ucla.edu, 40671 <at> debbugs.gnu.org,
> michael_heerdegen <at> web.de, mattiase <at> acm.org, rms <at> gnu.org
> From: Dmitry Gutov <dgutov <at> yandex.ru>
> Date: Sun, 26 Apr 2020 21:32:45 +0300
>
> My point is, that program is using the same instrument as this one,
> which *will* blow up at runtime.
No, it isn't the same instrument. Your program constructs a function
call using address that has no valid instructions. Paul's program
does nothing like that, it just attempts to write to a data address
which may or may not be in write-protected storage. So your program
will always blow up, whereas the other one will only blow up if the
memory is write-protected.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 26 Apr 2020 18:54:01 GMT)
Full text and
rfc822 format available.
Message #195 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 26.04.2020 21:41, Eli Zaretskii wrote:
>> Cc: ke.vigouroux <at> laposte.net, eggert <at> cs.ucla.edu, 40671 <at> debbugs.gnu.org,
>> michael_heerdegen <at> web.de, mattiase <at> acm.org, rms <at> gnu.org
>> From: Dmitry Gutov <dgutov <at> yandex.ru>
>> Date: Sun, 26 Apr 2020 21:32:45 +0300
>>
>> My point is, that program is using the same instrument as this one,
>> which *will* blow up at runtime.
>
> No, it isn't the same instrument. Your program constructs a function
> call using address that has no valid instructions. Paul's program
> does nothing like that, it just attempts to write to a data address
> which may or may not be in write-protected storage. So your program
> will always blow up, whereas the other one will only blow up if the
> memory is write-protected.
I was imprecise. The program is doing a different thing.
But the programmer is using the same instrument in both cases to make it
compile.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 26 Apr 2020 18:58:02 GMT)
Full text and
rfc822 format available.
Message #198 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 4/26/20 7:03 AM, Dmitry Gutov wrote:
> g++ string_const.c++
Ah, my example was C-only. Here is an example for both C and C++:
#include <string.h>
int main (void) {
union { char const *cp; char *p; } u = { "a" };
return !strcpy (u.p, "b");
}
This has undefined behavior, and might dump core or might not depending on the
implementation. Neither gcc nor g++ issue any warnings in default compilation.
Undefined behavior is undesirable and it's not a good thing that Emacs Lisp also
has areas that behave like this. Somebody should pry free time to look into
fixing them, but that won't be trivial. It appears that portable dumping and
other changes have broken some of Emacs's runtime checking in this area.
Unfortunately, the relevant code is hairy and any fixes certainly won't happen
before the Emacs 27 release. In the meantime it's better to warn users clearly
about the gotchas in this area, to help prevent some of the confusion
exemplified by Bug#40671.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 26 Apr 2020 19:23:01 GMT)
Full text and
rfc822 format available.
Message #201 received at 40671 <at> debbugs.gnu.org (full text, mbox):
Am So., 26. Apr. 2020 um 20:58 Uhr schrieb Paul Eggert <eggert <at> cs.ucla.edu>:
>
> On 4/26/20 7:03 AM, Dmitry Gutov wrote:
> > g++ string_const.c++
>
> Ah, my example was C-only. Here is an example for both C and C++:
>
> #include <string.h>
> int main (void) {
> union { char const *cp; char *p; } u = { "a" };
> return !strcpy (u.p, "b");
> }
>
> This has undefined behavior, and might dump core or might not depending on the
> implementation. Neither gcc nor g++ issue any warnings in default compilation.
Yes, but nobody "accidentally" writes code like this. OTOH, code like
attempting to mutate a "constant" Lisp object seems trivial to write
accidentally.
>
> Undefined behavior is undesirable and it's not a good thing that Emacs Lisp also
> has areas that behave like this. Somebody should pry free time to look into
> fixing them, but that won't be trivial.
What would be needed? We could either (a) remove the notion of
"constant" objects so that all objects become mutable, (b) introduce
static type checking including const-correctness so that attempting to
mutate a "constant" object would fail byte-compilation, and/or (c)
make it an error to mutate such objects at runtime (similar to (set t
nil)).
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 26 Apr 2020 20:15:01 GMT)
Full text and
rfc822 format available.
Message #204 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 4/26/20 12:22 PM, Philipp Stephani wrote:
> nobody "accidentally" writes code like this.
Not code like my trivial example, no. But the underlying problem is all too
common. After all, it's why Emacs is dumping core here - the Emacs Lisp
interpreter is using C code like that to implement some Lisp strings.
> We could either (a) remove the notion of
> "constant" objects so that all objects become mutable, (b) introduce
> static type checking including const-correctness so that attempting to
> mutate a "constant" object would fail byte-compilation, and/or (c)
> make it an error to mutate such objects at runtime (similar to (set t
> nil)).
Neither (a) nor (b) sound very practical. Emacs formerly did a better job at (c)
and could do so again, so it's an obvious way to move forward here.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 26 Apr 2020 21:24:02 GMT)
Full text and
rfc822 format available.
Message #207 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 26.04.2020 21:57, Paul Eggert wrote:
> On 4/26/20 7:03 AM, Dmitry Gutov wrote:
>> g++ string_const.c++
>
> Ah, my example was C-only. Here is an example for both C and C++:
>
> #include <string.h>
> int main (void) {
> union { char const *cp; char *p; } u = { "a" };
> return !strcpy (u.p, "b");
> }
>
> This has undefined behavior, and might dump core or might not depending on the
> implementation. Neither gcc nor g++ issue any warnings in default compilation.
This just illustrates a weakness of type system in C/C++. The same way
you could pass a string into a function that expects an int.
> Undefined behavior is undesirable and it's not a good thing that Emacs Lisp also
> has areas that behave like this.
But is it undefined? I think it's well-defined and predictable, though
it's harder to make sense of that we would like.
> Somebody should pry free time to look into
> fixing them, but that won't be trivial. It appears that portable dumping and
> other changes have broken some of Emacs's runtime checking in this area.
Do you have an example of a version of Emacs where this behavior was
different?
> Unfortunately, the relevant code is hairy and any fixes certainly won't happen
> before the Emacs 27 release. In the meantime it's better to warn users clearly
> about the gotchas in this area, to help prevent some of the confusion
> exemplified by Bug#40671.
Perhaps you meant some other bug report? This is the one we're
commenting on.
My concern here is the terms. I worry that someday someone will come
report a problem, and we respond with "this syntax creates constant
values, please take care not to modify them". Then that someone will go
away with very low opinion of our mental faculties.
In all of my experience, the term "constant" is usually applied to names
(variables), or pointers. And it almost always means that you're not
allowed to change it. Or if you are, you can't do it by accident.
The closest term that applies to values, I think, is "immutable". But
those are definitely protected from modification.
For our situation, the term "constant reference" comes to mind, but I
don't know exactly how to rephrase the manual best.
The previous term "literal objects", however, seems accurate enough, and
if the "constant-ness" is going to live only in the manual anyway,
perhaps we should just say "please don't modify literal objects [unless
you really know what you're doing]".
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 26 Apr 2020 23:15:01 GMT)
Full text and
rfc822 format available.
Message #210 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 4/26/20 2:23 PM, Dmitry Gutov wrote:
> This just illustrates a weakness of type system in C/C++. The same way you could
> pass a string into a function that expects an int.
Although it's a weakness, it's different from the char * vs int weakness. It's
well-defined in C that one can cast char * to char const * and back without
trouble. The same is not true for casting char * to int and back.
> is it undefined?
Yes, it's undefined. C11 section 6.7.3 paragraph 6 says, "If an attempt is made
to modify an object defined with a const-qualified type through use of an lvalue
with non-const-qualified type, the behavior is undefined."
> Do you have an example of a version of Emacs where this behavior was different?
Emacs 26.
>> Unfortunately, the relevant code is hairy and any fixes certainly won't happen
>> before the Emacs 27 release. In the meantime it's better to warn users clearly
>> about the gotchas in this area, to help prevent some of the confusion
>> exemplified by Bug#40671.
>
> Perhaps you meant some other bug report?
No, the original bug report that started this thread illustrates some of the
confusion in this area.
> In all of my experience, the term "constant" is usually applied to names
> (variables), or pointers. And it almost always means that you're not allowed to
> change it. Or if you are, you can't do it by accident.
Unfortunately that experience does not apply to C and to other low-level
languages. Even Java once allowed programs to modify "constants" by using
reflection, though recent Java versions have fixed this.
> The previous term "literal objects", however, seems accurate enough
We could use any term we like, and if there's consensus for using the term
"literal object" instead of "constant" then we can redo the manual that way.
However, the problem can occur with strings that were never string literals in
any source-code Elisp program. And a Elisp string can begin its life as a
mutable string and then become a "constant" (or "literal object") later. So it's
not clear that the longer phrase is less confusing.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Mon, 27 Apr 2020 00:55:01 GMT)
Full text and
rfc822 format available.
Message #213 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 27.04.2020 02:13, Paul Eggert wrote:
>> This just illustrates a weakness of type system in C/C++. The same way you could
>> pass a string into a function that expects an int.
>
> Although it's a weakness, it's different from the char * vs int weakness. It's
> well-defined in C that one can cast char * to char const * and back without
> trouble. The same is not true for casting char * to int and back.
This compiles fine:
#include <string.h>
int main (void) { return !strcpy ((char*)2, "b"); }
My point is, it's hard to discuss static typing guarantees when type
casting is involved.
>> is it undefined?
>
> Yes, it's undefined. C11 section 6.7.3 paragraph 6 says, "If an attempt is made
> to modify an object defined with a const-qualified type through use of an lvalue
> with non-const-qualified type, the behavior is undefined."
Sorry if that was unclear. I mean, is the behavior of "literal objects"
in Emacs Lisp undefined when one tries to modify them?
>> Do you have an example of a version of Emacs where this behavior was different?
>
> Emacs 26.
Sorry, I don't have an Emacs 26 at hand. Should 25 suffice? Just tried
this in IELM:
ELISP> (setq a '(1 . 2))
(1 . 2)
ELISP> (setcdr a 3)
3 (#o3, #x3, ?\C-c)
ELISP> a
(1 . 3)
ELISP> emacs-version
"25.2.3"
>>> Unfortunately, the relevant code is hairy and any fixes certainly won't happen
>>> before the Emacs 27 release. In the meantime it's better to warn users clearly
>>> about the gotchas in this area, to help prevent some of the confusion
>>> exemplified by Bug#40671.
>>
>> Perhaps you meant some other bug report?
>
> No, the original bug report that started this thread illustrates some of the
> confusion in this area.
Okay, yes. I though you had a bug report with a description of a
practical problem.
>> In all of my experience, the term "constant" is usually applied to names
>> (variables), or pointers. And it almost always means that you're not allowed to
>> change it. Or if you are, you can't do it by accident.
>
> Unfortunately that experience does not apply to C and to other low-level
> languages. Even Java once allowed programs to modify "constants" by using
> reflection, though recent Java versions have fixed this.
Hence the last sentence of my paragraph you quoted.
In Ruby, we also have "constants" and we sometimes laugh about being
able to change them. And yet, there also you can't do it by accident.
>> The previous term "literal objects", however, seems accurate enough
>
> We could use any term we like, and if there's consensus for using the term
> "literal object" instead of "constant" then we can redo the manual that way.
> However, the problem can occur with strings that were never string literals in
> any source-code Elisp program. And a Elisp string can begin its life as a
> mutable string and then become a "constant" (or "literal object") later. So it's
> not clear that the longer phrase is less confusing.
"A mutable string can become a constant later and yet remain modifiable
in practice" sounds really confusing.
We better warn against modifying any values that are part of a "literal
object" anywhere.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Mon, 27 Apr 2020 01:50:02 GMT)
Full text and
rfc822 format available.
Message #216 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 4/26/20 5:53 PM, Dmitry Gutov wrote:
> is the behavior of "literal objects" in Emacs
> Lisp undefined when one tries to modify them?
Yes.
>>> Do you have an example of a version of Emacs where this behavior was different?
>>
>> Emacs 26.
>
> Sorry, I don't have an Emacs 26 at hand. Should 25 suffice?
Yes.
Just tried this in
> IELM:
>
> ELISP> (setq a '(1 . 2))
> (1 . 2)
>
> ELISP> (setcdr a 3)
> 3 (#o3, #x3, ?\C-c)
> ELISP> a
> (1 . 3)
Yes, the behavior is undefined in Emacs 25 too. Undefined means that the
behavior you describe is allowed - in this instance you modified the "constant"
and got away with it.
> In Ruby, we also have "constants" and we sometimes laugh about being able to
> change them. And yet, there also you can't do it by accident.
I suppose it depends on what one means by "accident". :-) Perhaps we could agree
that accidents, whatever they are, happen more often in C....
> We better warn against modifying any values that are part of a "literal object"
> anywhere.
That's what the emacs-27 doc does, or at least tries to do.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Tue, 28 Apr 2020 03:06:01 GMT)
Full text and
rfc822 format available.
Message #219 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 27.04.2020 04:49, Paul Eggert wrote:
>> Sorry, I don't have an Emacs 26 at hand. Should 25 suffice?
>
> Yes.
>
> Just tried this in
>> IELM:
>>
>> ELISP> (setq a '(1 . 2))
>> (1 . 2)
>>
>> ELISP> (setcdr a 3)
>> 3 (#o3, #x3, ?\C-c)
>> ELISP> a
>> (1 . 3)
>
> Yes, the behavior is undefined in Emacs 25 too. Undefined means that the
> behavior you describe is allowed - in this instance you modified the "constant"
> and got away with it.
I'm not sure which problematic cases you mean, then. Ones related to
pure space?
>> In Ruby, we also have "constants" and we sometimes laugh about being able to
>> change them. And yet, there also you can't do it by accident.
>
> I suppose it depends on what one means by "accident". :-) Perhaps we could agree
> that accidents, whatever they are, happen more often in C....
It feels like you're just side-stepping the arguments, one after another.
>> We better warn against modifying any values that are part of a "literal object"
>> anywhere.
>
> That's what the emacs-27 doc does, or at least tries to do.
I wish it did that without inventing new meanings for the words
"constant" and "mutable". It will only breed confusion.
Take this paragraph:
Although all numbers are constants and all markers are
mutable, some types contain both constant and mutable members. These
types include conses, vectors, strings, and symbols. For example, the
string
literal @code{"aaa"} yields a constant string, whereas the function
call @code{(make-string 3 ?a)} yields a mutable string that can be
changed via later calls to @code{aset}.
It makes one think that 'aset' can't be called on "aaa". That it will
either fail to change the value, or signal an error. Whereas the result
is that the value is changed, no errors or warnings.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Tue, 28 Apr 2020 08:18:01 GMT)
Full text and
rfc822 format available.
Message #222 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 4/27/20 8:05 PM, Dmitry Gutov wrote:
> I'm not sure which problematic cases you mean, then. Ones related to pure space?
That's one issue. Earlier versions of Emacs also had trouble if you modified
list structures while executing them. I've squashed some of those issues more
recently but would not be surprised if some remain.
I don't know how much optimization the byte compiler did in earlier versions,
but if it did anything like what it does now, that's also a source of problems.
> Although all numbers are constants and all markers are
> mutable, some types contain both constant and mutable members. These
> types include conses, vectors, strings, and symbols. For example, the
> string
> literal @code{"aaa"} yields a constant string, whereas the function
> call @code{(make-string 3 ?a)} yields a mutable string that can be
> changed via later calls to @code{aset}.
>
> It makes one think that 'aset' can't be called on "aaa". That it will either
> fail to change the value, or signal an error. Whereas the result is that the
> value is changed, no errors or warnings.
'aset' *shouldn't* be called on "aaa".
We could replace "a constant string" with "a constant string that should not be
changed"; would that help?
> It feels like you're just side-stepping the arguments, one after another.
There's certainly no intent to side-step. And I don't sense that there's really
much disagreement here: we both agree that the current behavior is unfortunate,
the major point of disagreement is about terminology in the documentation.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Tue, 28 Apr 2020 13:55:02 GMT)
Full text and
rfc822 format available.
Message #225 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 28.04.2020 11:17, Paul Eggert wrote:
> On 4/27/20 8:05 PM, Dmitry Gutov wrote:
>
>> I'm not sure which problematic cases you mean, then. Ones related to pure space?
>
> That's one issue. Earlier versions of Emacs also had trouble if you modified
> list structures while executing them. I've squashed some of those issues more
> recently but would not be surprised if some remain.
If any led to segfaults, they have to be fixed in the code anyway.
> I don't know how much optimization the byte compiler did in earlier versions,
> but if it did anything like what it does now, that's also a source of problems.
Well, here's a damning example. And it doesn't involve the byte compiler:
ELISP> (defun abc () "abc")
abc
ELISP> (aset (abc) 0 ?b)
98 (#o142, #x62, ?b)
ELISP> (abc)
"bbc"
I wonder how other Lisps deal with that.
The Ruby interpreter, from the first release I think, always created
copies of the literals when a method was called. Exactly to avoid this
kind of broken semantics.
In the recent versions, they added a pragma string (to be added to the
top of the file) that makes all such literals in that file "immutable".
That means that any attempt to change them errors at runtime. And now
it's considered good style to use that pragma everywhere.
>> Although all numbers are constants and all markers are
>> mutable, some types contain both constant and mutable members. These
>> types include conses, vectors, strings, and symbols. For example, the
>> string
>> literal @code{"aaa"} yields a constant string, whereas the function
>> call @code{(make-string 3 ?a)} yields a mutable string that can be
>> changed via later calls to @code{aset}.
>>
>> It makes one think that 'aset' can't be called on "aaa". That it will either
>> fail to change the value, or signal an error. Whereas the result is that the
>> value is changed, no errors or warnings.
>
> 'aset' *shouldn't* be called on "aaa".
Indeed it shouldn't.
> We could replace "a constant string" with "a constant string that should not be
> changed"; would that help?
That sounds like a weird tautological non-advice.
It shouldn't be changed because it's a value of a string literal. Not
because it's constant (it isn't).
>> It feels like you're just side-stepping the arguments, one after another.
>
> There's certainly no intent to side-step. And I don't sense that there's really
> much disagreement here: we both agree that the current behavior is unfortunate,
> the major point of disagreement is about terminology in the documentation.
From the outset all arguments were about the terminology.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Tue, 28 Apr 2020 17:26:02 GMT)
Full text and
rfc822 format available.
Message #228 received at 40671 <at> debbugs.gnu.org (full text, mbox):
> There's certainly no intent to side-step.
> And I don't sense that there's really
> much disagreement here: we both agree that
> the current behavior is unfortunate,
> the major point of disagreement is about
> terminology in the documentation.
Has anyone agreed with you here about your use
of "cannot" instead of "should not" and your
unconventional use of "constant"/"immutable"
and "mutable"?
I don't think I've seen any support for that
here (did I just miss it?). Still you persist.
I don't really see the doc/message for users
getting clearer; it seems like the waters are
being muddied.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Tue, 28 Apr 2020 17:48:02 GMT)
Full text and
rfc822 format available.
Message #231 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 4/28/20 10:25 AM, Drew Adams wrote:
> Has anyone agreed with you
Nobody's happy with the current documentation's language (not even me), but
nobody has proposed specific wording improvements either. That's what committees
do sometimes; we might not agree, but the guy who does most of the work
generates something that nobody has the time to improve significantly.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Tue, 28 Apr 2020 18:00:02 GMT)
Full text and
rfc822 format available.
Message #234 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 4/28/20 6:54 AM, Dmitry Gutov wrote:
> It shouldn't be changed because it's a value of a string literal. Not because
> it's constant (it isn't).
That depends on the string literal and the particular Emacs implementation. In
Emacs master, some string literals yield strings that are constant because Emacs
has undefined behavior at the C level (maybe coredump, maybe not) if you try to
change them, some string literals are constant because if you try to change them
Emacs will reliably signal an error, some string literals are constant because
if you change them Emacs might behave unpredictably without having undefined
behavior at the C level, and the remaining string literals are constant becase
you shouldn't change them. We have never documented exactly which string
literals are which, and we shouldn't document that now because it is an
implementation detail that users should not rely upon.
It would be a mistake for the documentation to say that the problems we've been
discussing occur only with string literals, as these problems can occur for
strings that were not generated from string literals, and they can also occur
for objects that are not strings. So "string literal" would be the wrong
terminology here.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Tue, 28 Apr 2020 18:47:02 GMT)
Full text and
rfc822 format available.
Message #237 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 28.04.2020 20:59, Paul Eggert wrote:
> On 4/28/20 6:54 AM, Dmitry Gutov wrote:
>> It shouldn't be changed because it's a value of a string literal. Not because
>> it's constant (it isn't).
>
> That depends on the string literal and the particular Emacs implementation. In
> Emacs master, some string literals yield strings that are constant because Emacs
> has undefined behavior at the C level (maybe coredump, maybe not)
That sounds like something we have to fix. Emacs shouldn't dump core no
matter what Lisp code the user wrote. Unless it leads to an OOM, I guess.
> if you try to
> change them, some string literals are constant because if you try to change them
> Emacs will reliably signal an error, some string literals are constant because
> if you change them Emacs might behave unpredictably without having undefined
> behavior at the C level, and the remaining string literals are constant becase
> you shouldn't change them.
That's not a constant, that's an eldritch abomination. Some unknown,
unpredictable thing. Which is generally bad for language semantics and
for its users. I understand why it's hard to fix that, but co-opting
common words to mean different things is bad. Using semantics that might
be "slightly familiar" only to grizzled C programmers is also bad.
If you really want to have an adjective for such values, either ask some
language theorist or make up one (and I'm only half-kidding here).
Example: Some values in Emacs are constant, meaning you can't change
them (e.g. you can't change an integer), and some are mutable (e.g. a
cons cell is easy to change). There is a particular kind of values
called fizzleworp (see {String literals}, {Quote} and {Backquote}),
which are dangerous to modify. Please take care not to do that in your code.
<... some enumeration of situation which create fizzleworp values or
make an existing value fizzleworp ...>
OR
Anyplace we introduce literals in the manual, if they are dangerous to
modify, we say that. Without inventing new words.
> We have never documented exactly which string
> literals are which, and we shouldn't document that now because it is an
> implementation detail that users should not rely upon.
No argument here.
> It would be a mistake for the documentation to say that the problems we've been
> discussing occur only with string literals, as these problems can occur for
> strings that were not generated from string literals, and they can also occur
> for objects that are not strings. So "string literal" would be the wrong
> terminology here.
String literals, Lisp form literals, and any members of such forms. I
might be forgetting something, but this list is not too long, is it?
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Tue, 28 Apr 2020 19:21:01 GMT)
Full text and
rfc822 format available.
Message #240 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 4/28/20 11:46 AM, Dmitry Gutov wrote:
> That sounds like something we have to fix.
Yes, absolutely, though we can't feasibly do that before the next release.
> That's not a constant, that's an eldritch abomination.
I say "constant", you say "eldritch". :-)
> Using semantics that might be "slightly familiar"
> only to grizzled C programmers is also bad.
It's not just "slightly familiar" to grizzled C/C++/etc. programmers. It's a
concept that's pretty much part of their daily lives.
> There is a particular kind of values called fizzleworp (see {String literals}, {Quote} and {Backquote}), which are dangerous to modify.
Let's not go that route. It'd be overdocumenting internal details that are not
generally known. I don't know all the details, so I couldn't write all that
documentation without a lot of nontrivial investigation. And these details are
likely to change so users should not rely on them anyway.
Instead of going out into the wilderness and tagging and identifying each dragon
and its lair, the documentation should keep things simple and merely say "there
are dragons out in the wilderness; you shouldn't go there". This is much simpler
and easier to understand and maintain, and is safer overall.
> Lisp form literals, and any members of such forms. I might be forgetting something, but this list is not too long, is it?
Yes the list isn't *that* long, and it's in the documentation already - as long
as we are willing to put up with a conservative list (e.g., you shouldn't modify
anything in the list) rather than insisting on an exhaustive list (e.g., here's
what happens if you try to modify X, here's what happens if you try to modify Y,
etc.).
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Tue, 28 Apr 2020 19:35:01 GMT)
Full text and
rfc822 format available.
Message #243 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 28.04.2020 22:20, Paul Eggert wrote:
> On 4/28/20 11:46 AM, Dmitry Gutov wrote:
>
>> That sounds like something we have to fix.
>
> Yes, absolutely, though we can't feasibly do that before the next release.
Yeah, ok.
>> That's not a constant, that's an eldritch abomination.
>
> I say "constant", you say "eldritch". :-)
And then I explain why "constant" is bad, multiple times. With examples
from other languages.
>> Using semantics that might be "slightly familiar"
>> only to grizzled C programmers is also bad.
>
> It's not just "slightly familiar" to grizzled C/C++/etc. programmers. It's a
> concept that's pretty much part of their daily lives.
You take the concept of "constant values", look it up in the C standard
(where modifying a constant is "undefined behavior") and then make a
conclusion that if modifying something is "undefined behavior", it must
be called a constant. Outside of C standard, to boot.
Emacs users are not C programmers.
>> There is a particular kind of values called fizzleworp (see {String literals}, {Quote} and {Backquote}), which are dangerous to modify.
>
> Let's not go that route. It'd be overdocumenting internal details that are not
> generally known. I don't know all the details, so I couldn't write all that
> documentation without a lot of nontrivial investigation. And these details are
> likely to change so users should not rely on them anyway.
That's not what I was suggesting. I gave an example on using the words,
not on which cases to enumerate.
> Instead of going out into the wilderness and tagging and identifying each dragon
> and its lair, the documentation should keep things simple and merely say "there
> are dragons out in the wilderness; you shouldn't go there". This is much simpler
> and easier to understand and maintain, and is safer overall.
The map still has to circle the wilderness on the map somehow.
>> Lisp form literals, and any members of such forms. I might be forgetting something, but this list is not too long, is it?
>
> Yes the list isn't *that* long, and it's in the documentation already - as long
> as we are willing to put up with a conservative list (e.g., you shouldn't modify
> anything in the list) rather than insisting on an exhaustive list (e.g., here's
> what happens if you try to modify X, here's what happens if you try to modify Y,
> etc.).
Conservative list is fine, as long as we don't use the word "constant".
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Tue, 28 Apr 2020 20:10:01 GMT)
Full text and
rfc822 format available.
Message #246 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 4/28/20 12:33 PM, Dmitry Gutov wrote:
> And then I explain why "constant" is bad, multiple times. With examples from
> other languages.
The word "constant" means different things in different programming languages.
The meaning used in the Elisp manual is reasonably close to its meaning in
C/C++/Fortran/Common Lisp/etc., and that describes how Emacs behaves now. We'd
prefer it if Emacs behaved more like what Python does with its immutable
objects, and some day we should change Emacs to do that. When we do so, we can
modify the Elisp manual accordingly. In the meantime we need to document what we
have.
> Emacs users are not C programmers.
Of course not, but this area needs documentation and when the Emacs concept is
similar to an already-existing one in C/C++/etc. it's not necessarily a bad
thing to adopt their terminology and/or notation, even if that
terminology/notation happens to mean something else in other contexts.
>>> There is a particular kind of values called fizzleworp (see {String
>>> literals}, {Quote} and {Backquote}), which are dangerous to modify.
>>
>> Let's not go that route. It'd be overdocumenting internal details that are not
>> generally known. I don't know all the details, so I couldn't write all that
>> documentation without a lot of nontrivial investigation. And these details are
>> likely to change so users should not rely on them anyway.
>
> That's not what I was suggesting. I gave an example on using the words, not on
> which cases to enumerate.
Then I don't understand your suggestion.
I thought you were saying that we should distinguish among the types of
constants and should say what happens when you modify each type. The manual
already does this to a very limited extent, and I thought you were suggesting
that it should do a reasonably exhaustive job of it, in order to greatly limit
the area where Emacs behavior is undefined.
I'd rather not go that route generally, for the reasons stated above. That being
said, it might make sense to make some changes in this area. Or perhaps I'm
still misunderstanding you, in which case further clarification would be helpful.
A simple way to be clear in this area is to propose specific wording changes,
preferably in git format-patch form. It's not enough to say "I don't like the
word 'constant'."
> The map still has to circle the wilderness on the map somehow.
Yes, and the documentation does that now. The edge of the wild is the line
between constants and non-constants. A program that tries to modify a constant
is out in the wilderness.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Tue, 28 Apr 2020 21:12:02 GMT)
Full text and
rfc822 format available.
Message #249 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 28.04.2020 23:09, Paul Eggert wrote:
> The word "constant" means different things in different programming languages.
> The meaning used in the Elisp manual is reasonably close to its meaning in
> C/C++/Fortran/Common Lisp/etc., and that describes how Emacs behaves now.
As we've pointed out, Elisp is a wildly different beast from C. Static
vs. dynamic, etcetera.
> Of course not, but this area needs documentation and when the Emacs concept is
> similar to an already-existing one in C/C++/etc.
Not really.
> Then I don't understand your suggestion.
>
> I thought you were saying that we should distinguish among the types of
> constants and should say what happens when you modify each type.
Which part of my example contained the "what happens when"?
> A simple way to be clear in this area is to propose specific wording changes,
> preferably in git format-patch form. It's not enough to say "I don't like the
> word 'constant'."
Could you first provide the list of your commits that changed the manual
pertaining to this discussion?
Then I'll at least know what to try to change.
> Yes, and the documentation does that now. The edge of the wild is the line
> between constants and non-constants.
Write that line between fizzleworp and non-fizzleworp values.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Tue, 28 Apr 2020 21:19:01 GMT)
Full text and
rfc822 format available.
Message #252 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 28.04.2020 23:09, Paul Eggert wrote:
> I thought you were saying that we should distinguish among the types of
> constants
Among the types of mutable values. Between the "normal" and "do not
touch" ones.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Tue, 28 Apr 2020 23:12:01 GMT)
Full text and
rfc822 format available.
Message #255 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 4/28/20 2:10 PM, Dmitry Gutov wrote:
> On 28.04.2020 23:09, Paul Eggert wrote:
>> The meaning used in the Elisp manual is reasonably close to its meaning in
>> C/C++/Fortran/Common Lisp/etc., and that describes how Emacs behaves now.
>
> As we've pointed out, Elisp is a wildly different beast from C.
And Elisp is also wildly different from Common Lisp, for some interpretation of
"wildly different". But it's close enough in this area. I don't see why we
should depart from terminology used by C/C++/Fortran/Common Lisp/etc.; it's
reasonably well-established.
>> I thought you were saying that we should distinguish among the types of
>> constants and should say what happens when you modify each type.
> Among the types of mutable values. Between the "normal" and "do not touch" ones.
The "do not touch" values are called "constants" in the documentation now, just
as they are in the documentation for the other languages. I don't see why values
that should not change should be called "mutable".
And even if we called these values "mutable", I don't see why the documentation
should distinguish among the various types of "mutable" values that should not
change. The whole area is messy and differs from release to release and from
platform to platform. Programs should not change values-that-should-not-change
and we shouldn't try to catalog what happens if programs do what they shouldn't,
since it's complicated and we often don't even know what'll happen.
Generally speaking, the Elisp documentation should just say "you shouldn't
change these objects", like it does for C/C++/etc.
> Could you first provide the list of your commits that changed the manual
> pertaining to this discussion?
You can run this shell command in the emacs-27 branch.
git log --author=eggert --since='Apr 18 12:59:17 2020 -0700'
> Write that line between fizzleworp and non-fizzleworp values.
I don't understand this remark.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Tue, 28 Apr 2020 23:38:02 GMT)
Full text and
rfc822 format available.
Message #258 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 29.04.2020 02:10, Paul Eggert wrote:
> The "do not touch" values are called "constants" in the documentation now, just
> as they are in the documentation for the other languages.
In other languages, constants are something you can't change.
> I don't see why values
> that should not change should be called "mutable".
Mutable values are ones the user _can_ change. It's a structural thing.
> And even if we called these values "mutable", I don't see why the documentation
> should distinguish among the various types of "mutable" values that should not
> change.
Because the user sees strings and conses in both cases. All mutable
values, and yet changing some of them is a bad idea (even though Emacs
will most likely let you).
> Generally speaking, the Elisp documentation should just say "you shouldn't
> change these objects", like it does for C/C++/etc.
Do you see me arguing against that?
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Tue, 28 Apr 2020 23:53:01 GMT)
Full text and
rfc822 format available.
Message #261 received at 40671 <at> debbugs.gnu.org (full text, mbox):
Paul Eggert <eggert <at> cs.ucla.edu> writes:
> > (let ((l (list 1 2 3)))
> > (funcall (lambda () l)))
> >
> > Has the list become a constant?
>
> No, because the list is not part of the expression that is being evaluated.
> However, something like this could cause trouble:
>
> (let ((l (list 'lambda '(x) '(setcdr l x))))
> (eval (list l l)))
FWIW, I asked also because `funcall' seems, at least AFAIU, share some
code with `eval', and with lexical-binding on the lambda gets
transformed into something that does include the original list, so the
list becomes part of the evaluated expression.
Michael.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Tue, 28 Apr 2020 23:54:02 GMT)
Full text and
rfc822 format available.
Message #264 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 29.04.2020 02:10, Paul Eggert wrote:
> terminology used by C/C++/Fortran
Quote from https://en.cppreference.com/w/cpp/language/cv:
const object - an object whose type is const-qualified, or a non-mutable
subobject of a const object. Such object _cannot_ be modified: attempt
to do so directly is a _compile-time error_, and attempt to do so
indirectly (e.g., by modifying the const object through a reference or
pointer to non-const type) results in undefined behavior.
Emphasis mine.
I'll take a look at the commit, thanks.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Tue, 28 Apr 2020 23:54:02 GMT)
Full text and
rfc822 format available.
Message #267 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 4/28/20 4:36 PM, Dmitry Gutov wrote:
> On 29.04.2020 02:10, Paul Eggert wrote:
>> The "do not touch" values are called "constants" in the documentation now, just
>> as they are in the documentation for the other languages.
>
> In other languages, constants are something you can't change.
That's not true for C, or for Common Lisp, or for the other languages I
mentioned. You can change constants sometimes and not others. Behavior is
undefined if you try.
It sounds like we're merely disagreeing about using the word "constant" vs using
some other word or phrase (it's not clear what). But there's clear precedent
elsewhere for the terminology now in use in the emacs-27 manual.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Tue, 28 Apr 2020 23:58:01 GMT)
Full text and
rfc822 format available.
Message #270 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 29.04.2020 02:53, Paul Eggert wrote:
> It sounds like we're merely disagreeing about using the word "constant" vs using
> some other word or phrase (it's not clear what).
I gave a couple of options.
> But there's clear precedent
> elsewhere for the terminology now in use in the emacs-27 manual.
Any particular example? Before your latest changes, I mean.
Please don't say 'defconst'.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Wed, 29 Apr 2020 00:06:02 GMT)
Full text and
rfc822 format available.
Message #273 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 4/28/20 4:53 PM, Dmitry Gutov wrote:
> const object - an object whose type is const-qualified, or a non-mutable
> subobject of a const object. Such object _cannot_ be modified: attempt to do so
> directly is a _compile-time error_, and attempt to do so indirectly (e.g., by
> modifying the const object through a reference or pointer to non-const type)
> results in undefined behavior.
It's reasonable to have compile-time checking in a statically-typed language,
though (as the above quote notes) the checking isn't adequate for C++ and one
can get undefined behavior anyway in that language. And we could add some
similar compile-time checking for the Elisp byte-compiler: it could warn about
misuses like (aset "abc" 0 ?d), for example.
However, any such compile-time checking would be either too restrictive (with
false positives) or only partial (with false negatives) or both (as in C++). So
it wouldn't be an adequate substitute for documenting that some objects should
not be changed.
> I gave a couple of options.
I recall your using "literal object" but that's not a good choice of wording
because the problem can occur with objects that are not literally present in any
source code.
>> there's clear precedent
>> elsewhere for the terminology now in use in the emacs-27 manual.
>
> Any particular example?
By "elsewhere" I meant in other language documentation (C/C++/etc.), not
elsewhere in the emacs-27 manual.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Wed, 29 Apr 2020 00:15:01 GMT)
Full text and
rfc822 format available.
Message #276 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 29.04.2020 03:04, Paul Eggert wrote:
> It's reasonable to have compile-time checking in a statically-typed language,
> though (as the above quote notes) the checking isn't adequate for C++ and one
> can get undefined behavior anyway in that language.
All the undefined-behavior stuff in the language is part of backward
compatibility with C. Like I said, the same argument that says "you can
change a const in C++" also says "string and int and void are basically
the same type".
> And we could add some
> similar compile-time checking for the Elisp byte-compiler: it could warn about
> misuses like (aset "abc" 0 ?d), for example.
Not the worst idea. Won't work: it's a dynamic language. Hence the
example of how a similar problem was dealt with in a fellow dynamic
language that I wrote about a couple of messages ago.
> However, any such compile-time checking would be either too restrictive (with
> false positives)
The "too restrictive" end of the spectrum will result in prohibiting the
user from modifying any and all conses.
> or only partial (with false negatives) or both (as in C++). So
> it wouldn't be an adequate substitute for documenting that some objects should
> not be changed.
With runtime checks, it could. But that might be too costly.
> I recall your using "literal object" but that's not a good choice of wording
> because the problem can occur with objects that are not literally present in any
> source code.
"Any object that is part of a literal value". You can probably extend
that sentence to be exhaustive.
> By "elsewhere" I meant in other language documentation (C/C++/etc.), not
> elsewhere in the emacs-27 manual.
In "etc", you mentioned Common Lisp previously. Any idea how it deals
with that problem?
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Wed, 29 Apr 2020 00:33:02 GMT)
Full text and
rfc822 format available.
Message #279 received at 40671 <at> debbugs.gnu.org (full text, mbox):
Paul Eggert <eggert <at> cs.ucla.edu> writes:
> On 4/28/20 10:25 AM, Drew Adams wrote:
> > Has anyone agreed with you
>
> Nobody's happy with the current documentation's language (not even
> me), but nobody has proposed specific wording improvements either.
I think the feedback would be better if you had been more cooperative/
open minded at the beginning. You have started committing stuff without
even asking whether people like your approach in general. What if
people think slight rewording is not enough? You started the thing not
very cooperatively, and that's how things developed. Just my point of
view.
> That's what committees do sometimes; we might not agree, but the guy
> who does most of the work generates something that nobody has the time
> to improve significantly.
We all do stuff here nobody else has time to do. Obviously, in this
case a collective brainstorming at the beginning would have been better.
Apart from questions like "please give me a better wording for this I
wrote if _you_ don't like it", why did you never ask "how could we
improve this aspect of the manual, what do you think?" or "do people
agree with what I have in mind?". Now stuff is already in the repo,
it's inconvenient to review, and the committer doesn't seem to be very
open to other perspectives.
A lot of the discussion here currently is rather destructive, yes,
that's not good, I guess everyone involved is to blame.
Michael.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Wed, 29 Apr 2020 00:56:01 GMT)
Full text and
rfc822 format available.
Message #282 received at 40671 <at> debbugs.gnu.org (full text, mbox):
> I don't see why we should depart from terminology used by
> C/C++/Fortran/Common Lisp/etc.; it's reasonably well-established.
You're _not_ using the language that's used for Common Lisp.
I echoed what the CL doc said. Elisp corresponds
to the behavior of CLTL1 in this regard, not to any
later update that makes the interpreter behave more
like compiled code (raising an error in both).
Like CLTL1, we should just warn about the gotcha,
not say that it's about modification or attempted
modification of "constants".
A few mails ago, you wondered if the disagreement
has been only about terminology. And the response
was mostly "Yes" - objections to your use of
"mutable" and "constant"/"immutable", and your use
of "cannot" instead of "should not" (aka "Don't").
You've since ignored that response, it seems. This
has dragged on, just circling. I, for one, give up.
But I do hope you'll listen to others. And yes,
Michael's point about committing before discussing
& deciding is spot on too. Remember your curly-quote
crusade? You did the same thing then, with similar
complaints about acting widely, unilaterally, and
prematurely.
My suggestion is to see how people have already
warned users about this gotcha here & there (forums
etc.) and do likewise. Come to an agreement about
the behavior to warn users about - in practical,
operational, but not exhaustive, terms.
A simple quoted-list example is enough, along with
a general description. Once there's agreement
about the message, including any example(s), the
wording will fall out naturally. (At least the
wording won't be a battleground, once the message
is decided on.)
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Wed, 29 Apr 2020 01:04:01 GMT)
Full text and
rfc822 format available.
Message #285 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 29.04.2020 03:55, Drew Adams wrote:
> But I do hope you'll listen to others. And yes,
> Michael's point about committing before discussing
> & deciding is spot on too. Remember your curly-quote
> crusade? You did the same thing then, with similar
> complaints about acting widely, unilaterally, and
> prematurely.
I disagree about the comparison. The curly-quote was (still is) a
fiasco, a big scope of changes (and breakages) with comparatively little
practical benefit. This bug report at least deals with a real problem.
And of course it's much easier to criticize (what a lot of us have been
doing) than provide actual wording changes. So I wouldn't say committing
too soon was a significant problem in this particular instance. It's not
a far-reaching change, and we could still revert it.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Wed, 29 Apr 2020 01:16:02 GMT)
Full text and
rfc822 format available.
Message #288 received at 40671 <at> debbugs.gnu.org (full text, mbox):
> > Remember your curly-quote
> > crusade? You did the same thing then, with similar
> > complaints about acting widely, unilaterally, and
> > prematurely.
>
> I disagree about the comparison. The curly-quote was (still is) a
> fiasco, a big scope of changes (and breakages) with comparatively
> little practical benefit. This bug report at least deals with a
> real problem.
Yes, I agree about that difference.
> And of course it's much easier to criticize (what a lot of us have been
> doing) than provide actual wording changes. So I wouldn't say
> committing too soon was a significant problem in this particular
> instance. It's not a far-reaching change, and we could still revert it.
And I agree with you there, too.
But I think Michael's point was about the
cooperation/attitude, not the nature or difficulty
of the problem to solve or the magnitude of any
problem of undoing committed changes.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Wed, 29 Apr 2020 01:29:02 GMT)
Full text and
rfc822 format available.
Message #291 received at 40671 <at> debbugs.gnu.org (full text, mbox):
Drew Adams <drew.adams <at> oracle.com> writes:
> But I think Michael's point was about the cooperation/attitude, not
> the nature or difficulty of the problem to solve or the magnitude of
> any problem of undoing committed changes.
Yes, I was referring to Paul's complaints and frustration, and I
wondered why the discussion developed like that. Maybe I'm totally
wrong, it's just how I experienced things.
Michael.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Wed, 29 Apr 2020 01:39:02 GMT)
Full text and
rfc822 format available.
Message #294 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 4/28/20 5:55 PM, Drew Adams wrote:
> You're _not_ using the language that's used for Common Lisp.
In what sense does the language differ? Here's a quote from CLtL2 (page 115):
"it is an error to destructively modify any object that appears as a constant
in executable code, whether within a 'quote' special form or as
a self-evaluating form."
This use of the word "constant" is consistent with what's in the emacs-27 doc.
> Elisp corresponds
> to the behavior of CLTL1 in this regard, not to any
> later update
Those older CLtL semantics were not well-defined, and to the extent that they
were defined were not followed by Common Lisp implementations. It's not clear
that the emacs-27 Elisp implementation corresponds to those older semantics, and
it's also not clear that documenting CLtL1 semantics would be a good idea for Elisp.
> A few mails ago, you wondered if the disagreement
> has been only about terminology. And the response
> was mostly "Yes" - objections to your use of
> "mutable" and "constant"/"immutable", and your use
> of "cannot" instead of "should not" (aka "Don't").
>
> You've since ignored that response, it seems.
I responded to those specific wording objections by removing the "immutable"s
and "cannots" that were objected to. At least, that was my intent; if I missed
something please let me know.
I admit I have not made changes in response to vaguer suggestions, but that's
partly because I don't really understand what's involved.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Wed, 29 Apr 2020 01:41:02 GMT)
Full text and
rfc822 format available.
Message #297 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 4/28/20 5:32 PM, Michael Heerdegen wrote:
> A lot of the discussion here currently is rather destructive, yes,
> that's not good, I guess everyone involved is to blame.
At this point the disagreement over a relatively minor terminology issue is so
lengthy that the whole documentation change is arguably more trouble than it's
worth. So again: anyone who wants to revert my recent doc changes to emacs-27 is
welcome to do so. Or, if you'd prefer to uniformly subsitute "literal object"
for "constant", please feel free to do that too. It's really not worth arguing
about, and I apologize for stirring up this hornet's nest.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Wed, 29 Apr 2020 04:37:01 GMT)
Full text and
rfc822 format available.
Message #300 received at 40671 <at> debbugs.gnu.org (full text, mbox):
> > You're _not_ using the language that's used
> > for Common Lisp.
>
> In what sense does the language differ? Here's
> a quote from CLtL2 (page 115):
>
> "it is an error to destructively modify any object that appears as a
> constant in executable code, whether within a 'quote' special form or as
> a self-evaluating form."
>
> This use of the word "constant" is consistent
> with what's in the emacs-27 doc.
I quoted that same text as part of a proposal to
FIX the very gotcha that Elisp still suffers from.
I already addressed this, specifically.
See https://debbugs.gnu.org/cgi/bugreport.cgi?bug=40671#24
I specifically spoke of CLTL1, because its state,
and the state of CL at that time corresponds more
closely with that of Elisp and its doc, since CLTL1
predates the proposal to handle the gotcha
systematically.
> > Elisp corresponds to the behavior of CLTL1 in
> > this regard, not to any later update
>
> Those older CLtL semantics were not well-defined,
Precisely the problem Emacs Lisp has! And not
just not well defined. Different behavior
sometimes between interpreted and compiled code.
That IS the gotcha - the fact that Elisp does NOT
raise an error systematically in all such cases.
It does NOT always prevent you from modifying a
constant, quoted list etc.
Elisp is like CL was BEFORE the proposal I quoted,
which was adopted as the CLTL2 text you quoted.
They fixed the problem for CL by redefining CL
to not have it. For an implementation of CL to
follow the updated definition, it must provide
consistent behavior, preventing modification of
constants, quoted lists, etc.
Sound familiar yet?
> and to the extent that they were defined were not
> followed by Common Lisp implementations. It's not
> clear that the emacs-27 Elisp implementation
> corresponds to those older semantics, and it's
> also not clear that documenting CLtL1 semantics
> would be a good idea for Elisp.
The point is that the problem they fixed is the
problem Elisp still has. Whether it is exactly
the same in all particulars is unimportant -
it's about the behavior being undefined and not
necessarily the same if interpreted or compiled.
I mentioned the CL proposal, to take effect
for CLTL2, quoting:
"clarify that it is an error to destructively
^^^^^^^ ^^^^^^^^^^^^^^
modify objects which are self-evaluating
forms or which appear inside of a QUOTE
special form."
Why "clarify"? Because it was NOT stated as
part of the previous definition of CL that
that is an error. And that meant that CL
implementations were NOT required to
systematically raise an error to enforce that.
They did NOT always prevent you from modifying
such thingies.
The proposal also said:
"Disallowing modification of constants
^^^^^^^^^^^
consistently in all situations, rather than
^^^^^^^^^^^^
just in compiled code, is proposed because
^^^^^^^^^^^
in some compiled-only situations it may be
difficult to distinguish between "compiled"
and "interpreted" code."
That was the problem to be fixed, by raising an
error, i.e., by disallowing, in practice. And
that's exactly the problem that Elisp still has:
it does NOT disallow (systematic error). And no
amount of saying that it does (claiming you
"cannot" do it) changes that fact.
I quoted CLTL about the behavior before the
proposal, i.e., before systematically raising
an error:
"implicit sharing of compiled data structures
may result in unpredictable behavior if
^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^
destructive operations are performed. However,
CLtL does not explicitly allow or disallow
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
destructive operations on constants."
And about that I said:
Unpredictable behavior. It doesn't say it's
^^^^^^^
always impossible to modify such things. It
^^^^^^^^^^^^^^^^^
says, in effect, don't try.
^^^^^^^^^
That's what we should say for Emacs Lisp, since
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
we do NOT "disallow modification of constants
consistently in all situations."
For Emacs Lisp this is a gotcha, so we need a
SHOULD. If it were enforced as a MUST then we
wouldn't need such a caveat.
That's precisely the point. We do NOT disallow.
We do NOT always raise an error. We do NOT
always PREVENT changing quoted list structure etc.
AND SO we should NOT tell users that they CANNOT
do so - sometimes they CAN. We should instead
tell them that they SHOULD NOT try to do so, and
if they do then the resulting behavior is undefined.
___
I said last message that I gave up. And now I'm
literally repeating what I wrote 10 days ago.
You haven't heard, or you're not listening. (And
my impression is that others have said the same as
I, or similar.) Sorry, I'm done.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Wed, 29 Apr 2020 04:42:01 GMT)
Full text and
rfc822 format available.
Message #303 received at 40671 <at> debbugs.gnu.org (full text, mbox):
Paul Eggert <eggert <at> cs.ucla.edu> writes:
> So again: anyone who wants to revert my recent doc changes to emacs-27
> is welcome to do so. Or, if you'd prefer to uniformly subsitute
> "literal object" for "constant"
I don't think "literal" covers all the cases you have in mind. I don't
have an idea for a name of the class of cases you have in mind, because
I would not subsume all examples you gave in one class at all. They
might be implementation- or memory-wise, but I don't think this is a good
perspective to describe a high-level language.
For example, the result of `symbol-name'. In my eyes, modifying the
result has a side effect (renaming the symbol, but in a way that is not
supported), and this side effect will have undesired consequences. But
that is true for other strings, too, that you would call mutable. It's
hard to draw a clear line here, unless you think (C-) implementation
wise.
For what you describe I would just say that under certain conditions
certain objects that are, in principle, mutable, should not be changed
in certain circumstances because of implementation details, here is a
list of such cases: ..., that's it.
I'm sorry that I also can't offer patches because I don't speak texinfo.
> It's really not worth arguing about, and I apologize for stirring up
> this hornet's nest.
I've never been called a hornet before.
Michael.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Wed, 29 Apr 2020 08:03:02 GMT)
Full text and
rfc822 format available.
Message #306 received at 40671 <at> debbugs.gnu.org (full text, mbox):
> From: Michael Heerdegen <michael_heerdegen <at> web.de>
> Date: Wed, 29 Apr 2020 06:40:39 +0200
> Cc: ke.vigouroux <at> laposte.net, 40671 <at> debbugs.gnu.org,
> Mattias Engdegård <mattiase <at> acm.org>,
> Dmitry Gutov <dgutov <at> yandex.ru>, Richard Stallman <rms <at> gnu.org>
>
> I'm sorry that I also can't offer patches because I don't speak texinfo.
Would you be willing to review the relevant portions of the manual and
post comments to the parts that in your opinion need further work? I
think that would be a good step towards making the text less
controversial.
TIA
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Wed, 29 Apr 2020 16:19:02 GMT)
Full text and
rfc822 format available.
Message #309 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 4/28/20 9:36 PM, Drew Adams wrote:
> Elisp is like CL was BEFORE the proposal I quoted,
No, that's backwards. CLtL1 was hazy, but arguably would have disallowed Elisp's
behavior because it arguably required the interpreter to immediately respond to
changes in objects currently being executed, and arguably required the
interpreter to not coalesce identical literals, and the Elisp interpreter
violates both requirements. In contrast, CLtL2 allows the Elisp behavior, so
CLtL2 is the better way to go here.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Wed, 29 Apr 2020 16:37:01 GMT)
Full text and
rfc822 format available.
Message #312 received at 40671 <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
On 4/28/20 5:32 PM, Michael Heerdegen wrote:
> Now stuff is already in the repo, it's inconvenient to review,
I took the trouble of retrieving all changes to the emacs-27 documentation since
this exercise started, discarding the irrelevant changes, with the result being
the attached diff. This should make the new material more convenient to review.
Of course this is not a complete substitute for reviewing what's in the manual
now, as I could have well missed some stuff that needs changing.
[constants.diff (text/x-patch, attachment)]
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Fri, 01 May 2020 02:48:02 GMT)
Full text and
rfc822 format available.
Message #315 received at 40671 <at> debbugs.gnu.org (full text, mbox):
[[[ To any NSA and FBI agents reading my email: please consider ]]]
[[[ whether defending the US Constitution against all enemies, ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]
To a purist, the vagueness about what happens to Emacs if you modify
code at the wrong time may seem intolerable. If there were an easy
and painless way to implement well-defined behavior, it might be worth
doing so. But there isn't.
This isn't a big difficulty in practice. It isn't worth sacrificing
anything that matters.
--
Dr Richard Stallman
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Fri, 01 May 2020 03:05:02 GMT)
Full text and
rfc822 format available.
Message #318 received at 40671-done <at> debbugs.gnu.org (full text, mbox):
On 19.04.2020 00:54, Drew Adams wrote:
> It's about code that always creates new list
> structure, versus code that might create new
> list structure only sometimes (e.g. the first
> time it's encountered).
Could we call them "interned values"? Like "interned strings" in some
programming languages. And then say "don't try to modify them please".
The "sometimes" aspect is a semantic snag, but it's certainly better
than calling them constant.
"literal values" is also an option, but that definition seems limiting.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Fri, 01 May 2020 03:15:01 GMT)
Full text and
rfc822 format available.
Message #321 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 29.04.2020 04:38, Paul Eggert wrote:
> On 4/28/20 5:55 PM, Drew Adams wrote:
>> You're_not_ using the language that's used for Common Lisp.
> In what sense does the language differ? Here's a quote from CLtL2 (page 115):
>
> "it is an error to destructively modify any object that appears as a constant
> in executable code, whether within a 'quote' special form or as
> a self-evaluating form."
As Drew pointed out (and if I understood this correctly), the above
specification leads to implementations that do raise an error when
someone tried to modify such a value.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Fri, 01 May 2020 05:18:01 GMT)
Full text and
rfc822 format available.
Message #324 received at 40671-done <at> debbugs.gnu.org (full text, mbox):
> > It's about code that always creates new list
> > structure, versus code that might create new
> > list structure only sometimes (e.g. the first
> > time it's encountered).
>
> Could we call them "interned values"? Like "interned strings" in some
> programming languages. And then say "don't try to modify them please".
>
> The "sometimes" aspect is a semantic snag, but it's certainly better
> than calling them constant.
>
> "literal values" is also an option, but that definition seems limiting.
You're replying to a message of mine from a
while back. I agree with the limitation or
difficulty of communicating the "sometimes"
aspect. And I agree that the message for users
should be "don't try to modify them" (even
though the "them" isn't detailed).
My own opinion is to avoid mention of any such
name: constant, literal, interned this-or-that.
Better to keep it vague, and just sketch the
problem and say that the behavior is undefined.
IMO, the message for users for the quoted-list
gotcha should be to not assume that code that
has a quoted list in it creates a new list
whenever you might think that that code (Lisp
source or byte-compiled) gets evaluated.
`quote' returns its arg unevaluated, but it's
not always clear by looking at the source code
just when or how many times a quoted list might
get evaluated. That's undefined, so assume
nothing about it. In particular, the behavior
can differ for the same source code, depending
on whether it's interpreted or byte-compiled.
A simple example could suffice, to make that
point.
If it helps, we can also say, for the example,
that the source-code quoted list might, in
effect, get replaced by its value when it's
read or byte-compiled, so the same cons cells
(not new list structure) might get reused each
time the resulting code gets evaluated.
And because of that possibility you're advised
not to try to modify such a list.
Yes, there are other examples of the problem,
besides quoted lists. Like the Common Lisp
doc, we could list some of them, without
giving more examples or going into detail.
Or we could give a second simple example,
perhaps with a string literal.
What's important, I think, is to (1) get
across the general idea/problem, (2) give
some idea how to recognize situations where
the gotcha can arise, and make clear that
you cannot depend on the behavior.
There's no prevention of the gotcha, e.g. by
raising an error systematically. You just
have to learn to recognize the possibility of
trying to modify something that may have
become, at some point, effectively
unmodifiable - and not do that.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Fri, 01 May 2020 05:19:02 GMT)
Full text and
rfc822 format available.
Message #327 received at 40671 <at> debbugs.gnu.org (full text, mbox):
> >> You're _not_ using the language that's used for Common Lisp.
> > In what sense does the language differ? Here's a quote from CLtL2
> (page 115):
> >
> > "it is an error to destructively modify any object that appears as a
> constant
> > in executable code, whether within a 'quote' special form or as
> > a self-evaluating form."
>
> As Drew pointed out (and if I understood this correctly), the above
> specification leads to implementations that do raise an error when
> someone tried to modify such a value.
That's my understanding. I believe that wasn't
the case for CLTL(1) - there was no such promise
or requirement. And I think it's also not the
case for Elisp. Like CLTL(1), we should just
warn users about the gotcha, since there's no
protection from it.
To be clear, I'm no expert on CLTL2. I used
CL for years before that. The gotcha bit me
once, having modified the result of a quoted
list - and then someone explained what was
happening.
It's too easy for a newbie to think only in
terms of textual source code being interpreted.
It's easy not to realize, as Michael said, that
there's the Lisp reader, the interpreter, and
the byte-compiler, and each might get a chance
to handle a quoted list. And just how they did
so was not specified.
Presumably, a conformant CL implementation now
protects you from this gotcha.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Fri, 01 May 2020 06:24:01 GMT)
Full text and
rfc822 format available.
Message #330 received at 40671 <at> debbugs.gnu.org (full text, mbox):
> From: Richard Stallman <rms <at> gnu.org>
> Date: Thu, 30 Apr 2020 22:47:32 -0400
> Cc: ke.vigouroux <at> laposte.net, 40671 <at> debbugs.gnu.org, michael_heerdegen <at> web.de,
> mattiase <at> acm.org, dgutov <at> yandex.ru
>
> To a purist, the vagueness about what happens to Emacs if you modify
> code at the wrong time may seem intolerable. If there were an easy
> and painless way to implement well-defined behavior, it might be worth
> doing so. But there isn't.
>
> This isn't a big difficulty in practice. It isn't worth sacrificing
> anything that matters.
I agree, but the practical problem is that we have a couple of purists
on board, for whom this is an itch they scratch not too infrequently.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Fri, 01 May 2020 21:42:01 GMT)
Full text and
rfc822 format available.
Message #333 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 4/30/20 8:13 PM, Dmitry Gutov wrote:
> On 29.04.2020 04:38, Paul Eggert wrote:
>> Here's a quote from CLtL2 (page 115):
>>
>> "it is an error to destructively modify any object that appears as a constant
>> in executable code, whether within a 'quote' special form or as
>> a self-evaluating form."
>
> As Drew pointed out (and if I understood this correctly), the above
> specification leads to implementations that do raise an error when someone tried
> to modify such a value.
Although those implementations conform to the Common Lisp spec, that's because
the spec explicitly says such behavior is undefined - which means
implementations can signal an error, dump core, or do whatever else they want.
See <https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node11.html>, which uses
"should" in the same sense the emacs-27 elisp manual uses "should". Here's a quote:
-----
When this book specifies that it "is an error" for some situation to occur, this
means that:
* No valid Common Lisp program should cause this situation to occur.
* If this situation occurs, the effects and results are completely undefined as
far as adherence to the Common Lisp specification is concerned.
* No Common Lisp implementation is required to detect such an error. Of course,
implementors are encouraged to provide for detection of such errors wherever
reasonable.
This is not to say that some particular implementation might not define the
effects and results for such a situation; the point is that no program
conforming to the Common Lisp specification may correctly depend on such effects
or results.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Fri, 01 May 2020 21:47:02 GMT)
Full text and
rfc822 format available.
Message #336 received at 40671-done <at> debbugs.gnu.org (full text, mbox):
On 4/30/20 8:03 PM, Dmitry Gutov wrote:
> Could we call them "interned values"? Like "interned strings" in some
> programming languages.
"Interned" would imply that we're merely deduplicating objects by hashing their
contents, which means modifying one deduplicated object modifies them all. But
the problem is bigger than that. There are some objects that one simply should
not modify, even if they are not deduplicated.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Fri, 01 May 2020 22:06:02 GMT)
Full text and
rfc822 format available.
Message #339 received at 40671 <at> debbugs.gnu.org (full text, mbox):
> >> Here's a quote from CLtL2 (page 115):
> >>
> >> "it is an error to destructively modify any object that appears as a
> >> constant in executable code, whether within a 'quote' special form or as
> >> a self-evaluating form."
> >
> > As Drew pointed out (and if I understood this correctly), the above
> > specification leads to implementations that do raise an error when
> > someone tried to modify such a value.
>
> Although those implementations conform to the Common Lisp spec, that's
> because the spec explicitly says such behavior is undefined - which means
> implementations can signal an error, dump core, or do whatever else
> they want.
> See
> <https://urldefense.com/v3/__https://www.cs.cmu.edu/Groups/AI/html/cltl
> /clm/node11.html__;!!GqivPVa7Brio!NeqWMrCFKgi8Ktwdz5aIkeBh_-TPzH-
> XiJbWDMeSRu1VKiI70b5LK6Sy2v5CMxaq$ >, which uses
> "should" in the same sense the emacs-27 elisp manual uses "should".
I stand corrected. I was assuming that the "proposal"
I cited had actually been adopted for CLTL2.
So CLTL2 is in the same boat as CLTL(1), in the regard
relevant to this thread: There is NO systematic raising
of an error - no prevention of the gotcha.
So what I said about Elisp being like CLTL(1) applies
also to CLTL2: We should NOT say that you _cannot_
do XYZ (because you might be able to, and the behavior
if you try is undefined). We should instead say that
you _should not_.
We're still circling, though. But thanks for clarifying
that "it's an error" meaning. I misremembered that as
meaning that a conformant implementation is required to
raise an error. I was thinking/assuming that the cited
proposal was in fact adopted as part of the CL definition.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Fri, 01 May 2020 22:29:01 GMT)
Full text and
rfc822 format available.
Message #342 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 5/1/20 3:05 PM, Drew Adams wrote:
> We should NOT say that you _cannot_
> do XYZ (because you might be able to, and the behavior
> if you try is undefined). We should instead say that
> you _should not_.
That's what the emacs-27 manual does now.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Fri, 01 May 2020 23:38:01 GMT)
Full text and
rfc822 format available.
Message #345 received at 40671-done <at> debbugs.gnu.org (full text, mbox):
On 02.05.2020 00:46, Paul Eggert wrote:
> On 4/30/20 8:03 PM, Dmitry Gutov wrote:
>> Could we call them "interned values"? Like "interned strings" in some
>> programming languages.
> "Interned" would imply that we're merely deduplicating objects by hashing their
> contents, which means modifying one deduplicated object modifies them all. But
> the problem is bigger than that. There are some objects that one simply should
> not modify, even if they are not deduplicated.
True. It's just the closest term from other languages I know that I
could think of.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sat, 02 May 2020 01:08:01 GMT)
Full text and
rfc822 format available.
Message #348 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 02.05.2020 00:40, Paul Eggert wrote:
>> As Drew pointed out (and if I understood this correctly), the above
>> specification leads to implementations that do raise an error when someone tried
>> to modify such a value.
>
> Although those implementations conform to the Common Lisp spec, that's because
> the spec explicitly says such behavior is undefined - which means
> implementations can signal an error, dump core, or do whatever else they want.
> See <https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node11.html>, which uses
> "should" in the same sense the emacs-27 elisp manual uses "should".
I suppose so.
> When this book specifies that it "is an error" for some situation to occur, this
> means that:
>
> * No valid Common Lisp program should cause this situation to occur.
>
> * If this situation occurs, the effects and results are completely undefined as
> far as adherence to the Common Lisp specification is concerned.
>
> * No Common Lisp implementation is required to detect such an error. Of course,
> implementors are encouraged to provide for detection of such errors wherever
> reasonable.
>
> This is not to say that some particular implementation might not define the
> effects and results for such a situation; the point is that no program
> conforming to the Common Lisp specification may correctly depend on such effects
> or results.
Indeed.
I took a longer look around the CLtL, to see how the term "constant" is
used there, though. Some phrases:
---
...it is an error to destructively modify any object that appears as
a constant in executable code, whether as a self-evaluating form or
within a quote special form
...to specify what objects can be in compiled constants...
quoted constants in it are similar in this sense to quoted constants
in the corresponding source code
An object may be used as a quoted constant...
Some types of objects, such as streams, are not supported in
constants processed by the file compiler. Such objects may not portably
appear as constants in code processed with compile-file.
The following terms are used throughout this section. The term
constant refers to a quoted or self-evaluating constant, not a named
constant defined by defconstant.
Two objects are similar as a constant if and only if they are both of
one of the types listed below and satisfy...
Two conses are similar as constants if the values of their respective
car and cdr attributes are similar as constants.
(Then comes the description of "similar as constants" values being
coalesced in compiled code).
---
CL's terminology seems fairly old by today's standards, but it looks
like they were grasping for words, just as we are now.
They very rarely use the phrase "constant objects", however. Instead,
it's almost always "objects that appears as a constant [in code]",
"object ... used as a quoted constant", "object may not ... appear as
constants in code", "objects are similar as a constant".
IOW, it's the difference between constant values and constant pointers
to [mutable] values. And the users are advised not to change the objects
that "appear as constants"/[play the role of constants]/[are the values
of constants] in executable code.
And there is no juxtaposition of "mutable objects" vs "constant objects"
anywhere in there, with "constant" defined like that, which is the part
of our new documentation that really got me into this discussion. So the
section "Constants and Mutability", even though it has valuable
information, could use a full rewrite. And could probably move to end of
the "Self-Evaluating Forms" section.
I'm also not sure it's a good idea to add too much explanations to the
introduction featuring phrases like "a list that is part of the program
and bad things could happen if we tried to change part of the program
while running it", so I'd keep the changes in the examples (the ones I
looked at look sensible), but remove most of the explanations. Moreso
that they are using the phrases "mutable values" and "constant values".
Some short explanation could say that it's a bad idea to modify a quoted
form (and then reference "Self-Evaluating Forms").
I can try to make a patch, but at this point is would consist mostly of
deletions.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sat, 02 May 2020 06:29:02 GMT)
Full text and
rfc822 format available.
Message #351 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 5/1/20 6:07 PM, Dmitry Gutov wrote:
> They very rarely use the phrase "constant objects", however. Instead, it's
> almost always "objects that appears as a constant [in code]", "object ... used
> as a quoted constant", "object may not ... appear as constants in code",
> "objects are similar as a constant".
We could use similar circumlocutions. Or instead of saying "constant" we could
say "unchanging", as distinct from "unchangeable". (It beats
"object-that-should-not-be-changed" or "glass object - you changed it, you broke
it!". :-) The usual word for this notion is "constant", though.
> IOW, it's the difference between constant values and constant pointers to
> [mutable] values.
I don't see that. A constant (or "unchanging") string is like a mutable string,
except you shouldn't change it. There's no sense in CLtL in which a mutable
object must be implemented via a pointer to a value whereas a constant must not
be implemented that way.
> there is no juxtaposition of "mutable objects" vs "constant objects"
> anywhere in there
Yes, the mutable/immutable terminology revolution happened mostly after CLtL was
written.
> So the section
> "Constants and Mutability", even though it has valuable information, could use a
> full rewrite. And could probably move to end of the "Self-Evaluating Forms"
> section.
Whether an object is constant is distinct from whether it's derived from a
self-evaluating form, because one can have constants that were never derived
from any self-evaluating form. Any doc rewrite should be careful to keep the two
notions distinct, quite plausibily (though not necessarily) in different sections.
> I can try to make a patch, but at this point is would consist mostly of deletions.
Certainly some stuff could be deleted (the tutorial could be trimmed as you
suggest, for example), but we should keep the baby while we're throwing out the
bathwater. And if we're using circumlocutions the text is likely to get longer,
not shorter.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sat, 02 May 2020 15:43:01 GMT)
Full text and
rfc822 format available.
Message #354 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 02.05.2020 09:28, Paul Eggert wrote:
> On 5/1/20 6:07 PM, Dmitry Gutov wrote:
>
>> They very rarely use the phrase "constant objects", however. Instead, it's
>> almost always "objects that appears as a constant [in code]", "object ... used
>> as a quoted constant", "object may not ... appear as constants in code",
>> "objects are similar as a constant".
>
> We could use similar circumlocutions. Or instead of saying "constant" we could
> say "unchanging", as distinct from "unchangeable". (It beats
> "object-that-should-not-be-changed" or "glass object - you changed it, you broke
> it!". :-) The usual word for this notion is "constant", though.
"glass objects" or "voldemort objects" all sound better to me. :-)
"unchanging" is one of the meanings of "constant". It's a property of a
process, not something we can call a value out of context.
CLtL uses the term "coalesced", though. We can consider it.
>> IOW, it's the difference between constant values and constant pointers to
>> [mutable] values.
>
> I don't see that. A constant (or "unchanging") string is like a mutable string,
> except you shouldn't change it.
An unchanging string is just a string that nobody changed. "Please don't
change unchanging strings" is a prohibition of time travel.
> There's no sense in CLtL in which a mutable
> object must be implemented via a pointer to a value whereas a
constant must not
> be implemented that way.
The "objects that appear as a constant" are objects to which exist
references from executable code, and where such references are
"constant" (or possibly constant, since an implementation might opt not
to coalesce the values). That why it's about constant references (and
objects to which such references exist).
>> there is no juxtaposition of "mutable objects" vs "constant objects"
>> anywhere in there
>
> Yes, the mutable/immutable terminology revolution happened mostly after CLtL was
> written.
Not just because of that.
>> So the section
>> "Constants and Mutability", even though it has valuable information, could use a
>> full rewrite. And could probably move to end of the "Self-Evaluating Forms"
>> section.
>
> Whether an object is constant is distinct from whether it's derived from a
> self-evaluating form, because one can have constants that were never derived
> from any self-evaluating form.
Examples?
I mean,
A mutable object can become constant if it is part of an expression
that is evaluated
does add some cases not covered by self-evaluating forms, but those are
more complex cases (e.g. creating forms programmatically and then
passing them to 'eval'), and then the programmer might justifiably be
expected to use their head. The self-evaluating forms case is arguably
less obvious.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sat, 02 May 2020 19:37:02 GMT)
Full text and
rfc822 format available.
Message #357 received at 40671 <at> debbugs.gnu.org (full text, mbox):
>> There's no sense in CLtL in which a mutable
>> object must be implemented via a pointer to a value whereas a constant must not
>> be implemented that way.
>
> The "objects that appear as a constant" are objects to which exist references
> from executable code, and where such references are "constant" (or possibly
> constant, since an implementation might opt not to coalesce the values). That
> why it's about constant references (and objects to which such references exist).
I don't understand this point.
It sounds like you might be trying to distinguish between constant references
(i.e., pointers that don't change) and constant objects implemented via
references (i.e., the pointed-to values don't change). However, whether the
references themselves are constant is independent of the issue at hand. The
issue wouldn't change, for example, if Emacs relocated objects so that
references were updated regardless of whether the objects' values were constant.
>> Whether an object is constant is distinct from whether it's derived from a
>> self-evaluating form, because one can have constants that were never derived
>> from any self-evaluating form.
>
> Examples?
One example is (aset (symbol-name 'car) 0 ?d), which I mentioned a while ago.
Here's a trickier one:
(let ((constant-string (aref (symbol-function 'error) 1)))
(aset constant-string 0 183)
(number-sequence 0 1 0))
This also provokes undefined behavior at the C level while number-sequence is
doing its thing; my Emacs dumps core, yours may do something different. I'm sure
there are other examples. The point is that programs should not modify constants.
It would be nice if Emacs reliably signaled these errors and we should be able
to do a better job of that than we're doing now. However, doing a better job
would require interpreter surgery that would be too much for emacs-27.
> A mutable object can become constant if it is part of an expression
> that is evaluated
>
> does add some cases not covered by self-evaluating forms, but those are more
> complex cases (e.g. creating forms programmatically and then passing them to
> 'eval'), and then the programmer might justifiably be expected to use their
> head. The self-evaluating forms case is arguably less obvious.
The documentation should not limit itself to self-evaluating forms when
discussing this problem area. Although it's OK for the doc to emphasize
self-evaluating forms, they are not the whole story here.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 03 May 2020 01:31:02 GMT)
Full text and
rfc822 format available.
Message #360 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 02.05.2020 22:35, Paul Eggert wrote:
>> The "objects that appear as a constant" are objects to which exist references
>> from executable code, and where such references are "constant" (or possibly
>> constant, since an implementation might opt not to coalesce the values). That
>> why it's about constant references (and objects to which such references exist).
>
> I don't understand this point.
>
> It sounds like you might be trying to distinguish between constant references
> (i.e., pointers that don't change) and constant objects implemented via
> references (i.e., the pointed-to values don't change).
I'm making a semantic point: these values are special because they are
at the other end of a certain set of "constant references". Not because
they have any other property themselves, like being immutable.
> However, whether the
> references themselves are constant is independent of the issue at hand. The
> issue wouldn't change, for example, if Emacs relocated objects so that
> references were updated regardless of whether the objects' values were constant.
Object relocation is immaterial for the semantics of Elisp. Even if the
objects were relocated from time to time, the references would be
updated, and would point to the same objects again, and thus be constant.
>>> Whether an object is constant is distinct from whether it's derived from a
>>> self-evaluating form, because one can have constants that were never derived
>>> from any self-evaluating form.
>>
>> Examples?
>
> One example is (aset (symbol-name 'car) 0 ?d), which I mentioned a while ago.
> Here's a trickier one:
>
> (let ((constant-string (aref (symbol-function 'error) 1)))
> (aset constant-string 0 183)
> (number-sequence 0 1 0))
>
> This also provokes undefined behavior at the C level while number-sequence is
> doing its thing; my Emacs dumps core, yours may do something different. I'm sure
> there are other examples. The point is that programs should not modify constants.
These two are pretty obviously "undefined behavior", and anybody who
does that have only themselves to blame. So of course it's good to
document this, but since apparently you're not going to fix the semantic
problem currently under discussion yourself, I'm not sure I can keep
this info. You're welcome to re-add it, of course.
> It would be nice if Emacs reliably signaled these errors and we should be able
> to do a better job of that than we're doing now. However, doing a better job
> would require interpreter surgery that would be too much for emacs-27.
Of course.
>> A mutable object can become constant if it is part of an expression
>> that is evaluated
>>
>> does add some cases not covered by self-evaluating forms, but those are more
>> complex cases (e.g. creating forms programmatically and then passing them to
>> 'eval'), and then the programmer might justifiably be expected to use their
>> head. The self-evaluating forms case is arguably less obvious.
>
> The documentation should not limit itself to self-evaluating forms when
> discussing this problem area. Although it's OK for the doc to emphasize
> self-evaluating forms, they are not the whole story here.
The "whole story" can be enumerated in some place, sure. Self-evaluating
forms seem to be the most important area to cover, though.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 03 May 2020 07:41:02 GMT)
Full text and
rfc822 format available.
Message #363 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 5/2/20 6:30 PM, Dmitry Gutov wrote:
> I'm making a semantic point: these values are special because they are at the
> other end of a certain set of "constant references". Not because they have any
> other property themselves, like being immutable.
I don't see why this semantic point makes a difference to the user. Regardless
of whether the objects are targets of "constant references" (whatever that
means), programs should not modify the objects in question. And if the semantic
point makes no practical difference, why complicate the manual with it?
It's simpler just to say: programs shouldn't modify these objects.
> The "whole story" can be enumerated in some place, sure. Self-evaluating forms
> seem to be the most important area to cover, though.
They're not the only thing to cover, and attempting to shoehorn this all into
self-evaluating forms could even be misleading.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 03 May 2020 16:45:01 GMT)
Full text and
rfc822 format available.
Message #366 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 03.05.2020 10:40, Paul Eggert wrote:
> It's simpler just to say: programs shouldn't modify these objects.
Which objects, then?
> They're not the only thing to cover, and attempting to shoehorn this all into
> self-evaluating forms could even be misleading.
Which section would that go into? "Constants and Mutability" doesn't work.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 03 May 2020 20:49:02 GMT)
Full text and
rfc822 format available.
Message #369 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 5/3/20 9:44 AM, Dmitry Gutov wrote:
> On 03.05.2020 10:40, Paul Eggert wrote:
>> It's simpler just to say: programs shouldn't modify these objects.
>
> Which objects, then?
Objects that the documentation currently calls "constants". (If there's a better
term than "constants" we haven't found it yet.)
>> They're not the only thing to cover, and attempting to shoehorn this all into
>> self-evaluating forms could even be misleading.
>
> Which section would that go into? "Constants and Mutability" doesn't work.
If we change the word "constants" to something else, we would presumably retitle
the section and adjust its contents accordingly. Regardless of which word is
chosen we should document the issue, which is broader than that of constants
from self-evaluating forms.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 03 May 2020 22:18:01 GMT)
Full text and
rfc822 format available.
Message #372 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 03.05.2020 23:48, Paul Eggert wrote:
> If we change the word "constants" to something else, we would presumably retitle
> the section and adjust its contents accordingly. Regardless of which word is
> chosen we should document the issue, which is broader than that of constants
> from self-evaluating forms.
Yes. But you supposedly want to move some of the contents (which don't
pertain exactly to self-evaluating forms) to some other section.
Could you make that naming choice yourself? I can only move it to one of
the existing ones.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 03 May 2020 22:19:01 GMT)
Full text and
rfc822 format available.
Message #375 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 03.05.2020 23:48, Paul Eggert wrote:
> (If there's a better
> term than "constants" we haven't found it yet.)
"Objects referenced from executable code", presumably.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 03 May 2020 22:41:02 GMT)
Full text and
rfc822 format available.
Message #378 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 5/3/20 3:18 PM, Dmitry Gutov wrote:
> On 03.05.2020 23:48, Paul Eggert wrote:
>> (If there's a better
>> term than "constants" we haven't found it yet.)
>
> "Objects referenced from executable code", presumably.
A fair number of objects fit that category. (The objects that don't are
typically garbage collected. :-) So that term doesn't describe what we want
clearly and accurately; plus, it's pretty long....
> On 03.05.2020 23:48, Paul Eggert wrote:
>> If we change the word "constants" to something else, we would presumably retitle
>> the section and adjust its contents accordingly. Regardless of which word is
>> chosen we should document the issue, which is broader than that of constants
>> from self-evaluating forms.
>
> Yes. But you supposedly want to move some of the contents (which don't pertain exactly to self-evaluating forms) to some other section.
There must be some miscommunication, as I thought you wanted to move some of
that section's contents. I vaguely recall responding that something along those
lines could work, but I don't recall any specific suggestion after that.
> Could you make that naming choice yourself? I can only move it to one of the existing ones.
I don't understand this request; I don't know what you mean by "it" or by
"moving" or by "existing ones".
If you're talking about the title of the "Constants and Mutability" section, the
current term "constants" is fine with me, as it follows existing practice in
CLtL etc. I'm open for suggestions for changing the term, but we haven't come up
with a better term as far as I can see, or even a term that's roughly equal in
quality.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 03 May 2020 22:54:01 GMT)
Full text and
rfc822 format available.
Message #381 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 04.05.2020 01:39, Paul Eggert wrote:
> A fair number of objects fit that category. (The objects that don't
> are typically garbage collected. So that term doesn't describe what
> we want clearly and accurately; plus, it's pretty long....
Example, please.
> If you're talking about the title of the "Constants and Mutability" section, the
> current term "constants" is fine with me, as it follows existing practice in
> CLtL etc. I'm open for suggestions for changing the term, but we haven't come up
> with a better term as far as I can see, or even a term that's roughly equal in
> quality.
I'm clearly not the only one objecting to the new terms. And especially
the juxtaposition of "constants and mutability" that you added to the
docs. It would be a shame to revert your whole work, though.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 03 May 2020 23:11:01 GMT)
Full text and
rfc822 format available.
Message #384 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 5/3/20 3:53 PM, Dmitry Gutov wrote:
> On 04.05.2020 01:39, Paul Eggert wrote:
>> A fair number of objects fit that category. (The objects that don't
>> are typically garbage collected. So that term doesn't describe what
>> we want clearly and accurately; plus, it's pretty long....
>
> Example, please.
The term you used was "Objects referenced from executable code". But that term
includes pretty much every object used in Elisp, at least until the object
becomes unreachable and is garbage-collected.
The concept you were describing is not that general: it's limited to objects
that are part of an expressions that are evaluated. So a better term would be
something like "Objects that are part of expressions that are evaluated" - but
this term is way too long; plus it doesn't accurately describe all the
problematic objects, as there are other reasons that some objects should not be
modified.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Mon, 04 May 2020 10:17:02 GMT)
Full text and
rfc822 format available.
Message #387 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 04.05.2020 02:10, Paul Eggert wrote:
> The term you used was "Objects referenced from executable code". But that term
> includes pretty much every object used in Elisp, at least until the object
> becomes unreachable and is garbage-collected.
I see. Could you present a specific counter-example, however?
One where the phrasing "referenced from executable code" would apply,
but "part of expressions that are evaluated" wouldn't.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Mon, 04 May 2020 17:53:01 GMT)
Full text and
rfc822 format available.
Message #390 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 5/4/20 3:16 AM, Dmitry Gutov wrote:
> On 04.05.2020 02:10, Paul Eggert wrote:
>> The term you used was "Objects referenced from executable code". But that term
>> includes pretty much every object used in Elisp, at least until the object
>> becomes unreachable and is garbage-collected.
>
> I see. Could you present a specific counter-example, however?
>
> One where the phrasing "referenced from executable code" would apply, but "part
> of expressions that are evaluated" wouldn't.
Pretty much any ordinary cons will do. In (let ((x (cons 0 0))) (setcar x 1)),
for example, the cons is referenced from executable code but it's OK to modify
the cons. The cons becomes unreachable when the 'let' finishes. The cons is not
part of any expression that is evaluated.
The problem here evidently is one of terminology, not of understanding the
underlying issues. When I read "Objects referenced from executable code" I
evidently got a different meaning than what you intended. These things happen
when introducing a new terminology.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Tue, 05 May 2020 01:40:02 GMT)
Full text and
rfc822 format available.
Message #393 received at 40671 <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
On 04.05.2020 20:52, Paul Eggert wrote:
> Pretty much any ordinary cons will do. In (let ((x (cons 0 0))) (setcar x 1)),
> for example, the cons is referenced from executable code but it's OK to modify
> the cons. The cons becomes unreachable when the 'let' finishes. The cons is not
> part of any expression that is evaluated.
But, I mean, if we just make it a literal:
(let ((x '(0 . 0))) (setcar x 1))
...it also becomes okay to modify it because the cons becomes
unreachable right away. Even so, we strongly recommend against this in
the manual now.
When the form above is a part of a function body, however, then it's
*really* inadvisable to use the latter option.
> The problem here evidently is one of terminology, not of understanding the
> underlying issues. When I read "Objects referenced from executable code" I
> evidently got a different meaning than what you intended. These things happen
> when introducing a new terminology.
I have asked for clarification to try to come up with better phrasing.
But to be frank it's not so important to me as fixing the existing one.
So if you can find a better option, please be my guest.
In the meantime, what do you think about the attached patch?
[no_constants.diff (text/x-patch, attachment)]
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Tue, 05 May 2020 06:10:01 GMT)
Full text and
rfc822 format available.
Message #396 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 5/4/20 6:39 PM, Dmitry Gutov wrote:
> if we just make it a literal:
>
> (let ((x '(0 . 0))) (setcar x 1))
>
> ...it also becomes okay to modify it
No, because the literal might be placed in read-only storage of some sort.
> In the meantime, what do you think about the attached patch?
Most of it is OK, but it goes too far in removing useful practical advice about
not doing "dangerous mutations" (to use the terminology you prefer). The defspec
for quote, the defuns for aset, setcar and setcdr, and the square-bracket
notation for vectors, should all point to the Dangerous Mutations section.
Also, the section on Dangerous Mutations should not imply that self-evaluating
forms are the only way to get objects that are dangerous to mutate, as there are
other ways to get such objects.
The section Dangerous Mutations is really about Mutations, not merely about
Dangerous Mutations. For example, it talks about modifying constant variables.
So I suggest changing its name to just "Mutations". This will help us in future
versions of Emacs, in which at least some of these mutations should become
non-dangerous.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Tue, 05 May 2020 12:39:02 GMT)
Full text and
rfc822 format available.
Message #399 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 05.05.2020 09:09, Paul Eggert wrote:
>> In the meantime, what do you think about the attached patch?
>
> Most of it is OK, but it goes too far in removing useful practical advice about
> not doing "dangerous mutations" (to use the terminology you prefer). The defspec
> for quote, the defuns for aset, setcar and setcdr, and the square-bracket
> notation for vectors, should all point to the Dangerous Mutations section.
I think that was too much: we've been living with this problem for many
years without hitting it too often. Sticking warning all over seems like
an overreaction.
> Also, the section on Dangerous Mutations should not imply that self-evaluating
> forms are the only way to get objects that are dangerous to mutate, as there are
> other ways to get such objects.
I thought your explanation was a bit too vague, so I added concreteness.
In essence though it was saying constants this and constants that, but
the actual examples were also only about self-evaluating forms. Did I
delete some informative part?
> The section Dangerous Mutations is really about Mutations, not merely about
> Dangerous Mutations. For example, it talks about modifying constant variables.
> So I suggest changing its name to just "Mutations". This will help us in future
> versions of Emacs, in which at least some of these mutations should become
> non-dangerous.
It's talking about the cases where a modification shouldn't occur, hence
the name. When something from the list becomes legal, I think this
section will just stop mentioning it?
In any case, none of my objections here are strong ones. How about you
take the proposed patch and update it as you see fit? As long as
"constant values" don't make a comeback, I'm good.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Tue, 05 May 2020 17:42:01 GMT)
Full text and
rfc822 format available.
Message #402 received at 40671 <at> debbugs.gnu.org (full text, mbox):
Apologies for chiming in here again.
And I haven't read the proposed text or
followed the thread recently.
But I just saw "Dangerous Mutations".
I really don't think that it's helpful or
appropriate to speak of danger in the context
of the gotcha we've been discussing.
Danger is danger. Yes, with undefined behavior,
and with possible modification of list structure
etc., there is the possibility of loss of data,
and that's not a good thing. Undefined is scary.
But I'm not in favor of crying "DANGER" about
such things. At all.
Check the Common Lisp doc. You don't find
such screaming warnings plastered throughout,
whenever it comes to destructive modification.
The word "destructive" is sufficiently strong.
And in the case of the gotchas being discussed
it's not necessarily even destructive
modification. The unknown/undefined is just
that. No need (and inappropriate) to wrap it
DANGEROUS!
Just one opinion.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Tue, 05 May 2020 18:50:02 GMT)
Full text and
rfc822 format available.
Message #405 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 05.05.2020 20:40, Drew Adams wrote:
> The word "destructive" is sufficiently strong.
> And in the case of the gotchas being discussed
> it's not necessarily even destructive
> modification.
It's not modification if it's not destructive. At least, in the context
of the problem we're trying to describe.
Destructive modification, by itself, is a very regular occasion. Not
something to warn against.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Tue, 05 May 2020 19:29:01 GMT)
Full text and
rfc822 format available.
Message #408 received at 40671 <at> debbugs.gnu.org (full text, mbox):
> It's not modification if it's not destructive. At least, in the context
> of the problem we're trying to describe.
>
> Destructive modification, by itself, is a very regular occasion. Not
> something to warn against.
Whatever. My point is that there's no need to
scream "Danger!". A warning does not imply
danger. And a tip about a gotcha is not
necessarily even a warning.
Can the consequences ever be awful? Presumably.
Will they often be awful? Not likely.
The most likely negative effect is spending
time trying to figure out what's happening.
That's why we should have a tip about the
gotcha.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Tue, 05 May 2020 21:37:01 GMT)
Full text and
rfc822 format available.
Message #411 received at 40671 <at> debbugs.gnu.org (full text, mbox):
Paul Eggert <eggert <at> cs.ucla.edu> writes:
> On 5/4/20 3:16 AM, Dmitry Gutov wrote:
>> On 04.05.2020 02:10, Paul Eggert wrote:
>>> The term you used was "Objects referenced from executable code". But that term
>>> includes pretty much every object used in Elisp, at least until the object
>>> becomes unreachable and is garbage-collected.
>>
>> I see. Could you present a specific counter-example, however?
>>
>> One where the phrasing "referenced from executable code" would apply, but "part
>> of expressions that are evaluated" wouldn't.
>
> Pretty much any ordinary cons will do. In (let ((x (cons 0 0))) (setcar x 1)),
> for example, the cons is referenced from executable code but it's OK to modify
> the cons. The cons becomes unreachable when the 'let' finishes. The cons is not
> part of any expression that is evaluated.
>
> The problem here evidently is one of terminology, not of understanding the
> underlying issues. When I read "Objects referenced from executable code" I
> evidently got a different meaning than what you intended. These things happen
> when introducing a new terminology.
Would the expression "constant form" be appropriate? Here is the
definition given in the CLHS (in the glossary).
Constant form: Any form for which evaluation always yields the same
value, that neither affects nor is affected by the environment in which
it is evaluated (except that is permitted to refer to the names of
constant variables defined in the environment), and that neither affects
nor is affected by the state of any object except those objects that are
otherwise inaccessible parts of objects created by the form
itself. For instance, a car form in which the argument is a quote form is a
constant form.
If I understand correctly, the problem is partially related to self-modifying code.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sat, 09 May 2020 05:58:01 GMT)
Full text and
rfc822 format available.
Message #414 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 5/5/20 1:48 PM, Kevin Vigouroux wrote:
> Would the expression "constant form" be appropriate?
Not exactly, as that refers to a form in the source code, whereas we are talking
about objects available at run-time. There is overlap between the two concepts
but some objects are "constant" (in the sense of the current emacs-27 doc)
without appearing in the source code.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sat, 09 May 2020 06:11:01 GMT)
Full text and
rfc822 format available.
Message #417 received at 40671 <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
On 5/5/20 5:38 AM, Dmitry Gutov wrote:
> In any case, none of my objections here are strong ones. How about you take the
> proposed patch and update it as you see fit? As long as "constant values" don't
> make a comeback, I'm good.
OK, attached is a draft patch to emacs-27. Although it doesn't go as far as your
patch, it does keep some of it, and in particular it gets rid of the
introduction of the term "constant" to describe objects that should not be
changed. It also omits the "Dangerous" that Drew objected to, and gives an
example of a term that was formerly mutable but is now something that you should
not change.
[0001-Don-t-use-constant-for-values-you-shouldn-t-change.txt (text/plain, attachment)]
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 10 May 2020 03:14:02 GMT)
Full text and
rfc822 format available.
Message #420 received at 40671 <at> debbugs.gnu.org (full text, mbox):
Hi Paul,
On 09.05.2020 09:10, Paul Eggert wrote:
> On 5/5/20 5:38 AM, Dmitry Gutov wrote:
>
>> In any case, none of my objections here are strong ones. How about you take the
>> proposed patch and update it as you see fit? As long as "constant values" don't
>> make a comeback, I'm good.
> OK, attached is a draft patch to emacs-27. Although it doesn't go as far as your
> patch, it does keep some of it, and in particular it gets rid of the
> introduction of the term "constant" to describe objects that should not be
> changed. It also omits the "Dangerous" that Drew objected to, and gives an
> example of a term that was formerly mutable but is now something that you should
> not change.
It's an improvement, but still I don't understand your choice.
Starting with:
Some Lisp objects should never change. For example, you can create
a new number by calculating one, but you cannot modify the value of an
existing number.
You start talking about objects that "should [not] change". And give an
example of an object that _cannot_ change.
Then, this passage is still confusing, and it doesn't have to be:
Although numbers never change and all markers are mutable, a type
can be a hybrid with some members mutable and other members not.
I could understand it if it was describing an existing type system of
the language, or implementation internals, but this is a purely
imaginary type system. Why make the mental image harder than we have to?
Further down:
A mutable object stops being mutable if it is part of an expression
that is evaluated. For example,
in @code{(eval (list 'quote (list 1)))}
the list @code{(1)} was mutable when it was created, but it should not
be changed after it was part of an argument to @code{eval}.
But the list object didn't change, just an outside reference to its head
was created, and that made it "possibly shared", depending on how the
aggregated value is subsequently used.
And further:
...whereas the
call @code{(make-string 3 ?a)} yields a mutable string that can be
changed via later calls to @code{aset}
The opposite of "mutable" is "immutable". Are quoted strings immutable?
They are not.
Overall the phrase "that might be shared" is a good replacement. Why not
keep to it? The rest of the patch doesn't try so hard to force the new
definitions anymore, so your new meaning of "mutable" doesn't seem
indispensable.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 10 May 2020 13:35:01 GMT)
Full text and
rfc822 format available.
Message #423 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 10.05.2020 06:13, Dmitry Gutov wrote:
> The opposite of "mutable" is "immutable". Are quoted strings immutable?
^ string literals
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 10 May 2020 17:30:02 GMT)
Full text and
rfc822 format available.
Message #426 received at 40671 <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
On 5/9/20 8:13 PM, Dmitry Gutov wrote:
> You start talking about objects that "should [not] change". And give an example
> of an object that _cannot_ change.
That's easily altered to also give an example of an object that should not
change; see attached patch.
> I could understand it if it was describing an existing type system of the
> language, or implementation internals, but this is a purely imaginary type
> system.
objects.texi already talks about the Emacs Lisp type system and specifically
mentions strings, conses, etc. as types. Even if one considers the Emacs Lisp
type system to be "imaginary", it's reasonable to use the documentation's
already-existing terminology here.
> the list object didn't change, just an outside reference to its head was
> created,
The attached patch alters the example so that the list object does change (or at
least tries to).
> The opposite of "mutable" is "immutable". Are string literals immutable? They are
> not.
They might be mutable, and they might not be. The documentation deliberately
doesn't say, because we don't want to document the details (they have changed in
the past and are likely to change in the future).
> Overall the phrase "that might be shared" is a good replacement. Why not keep to
> it?
Because it's not an accurate statement of the problem. The set of objects that
might be shared differs from the set of objects that should not change. The
Mutability node focuses on the latter set of objects, and gives the former as an
example but it is not the only sort of object that should not change.
> your new meaning of "mutable" doesn't seem indispensable.
That bar is too high, as hardly anything in the manual is *indispensable*. Ihe
notion of mutability is good to have in the manual, as it reduces confusion and
helps in documentation elsewhere. That's good enough.
I'm attaching two patches. The first are the changes mentioned above, and the
second is a single patch that combines the first patch with the changes I
previously proposed.
[0001-Update-mutability-doc.patch (text/x-patch, attachment)]
[0001-Don-t-use-constant-for-values-you-shouldn-t-change.patch (text/x-patch, attachment)]
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Mon, 11 May 2020 00:01:02 GMT)
Full text and
rfc822 format available.
Message #429 received at 40671 <at> debbugs.gnu.org (full text, mbox):
Paul Eggert <eggert <at> cs.ucla.edu> writes:
> I'm attaching two patches.
Thanks for the continued work on this, I appreciate the improvements and
the general direction. I may have missed parts of the discussion
recently, sorry if some comments are unsubstantial.
So, a few questions about the patches:
> + Although numbers never change and all markers are mutable,
> +some types have members some of which are mutable and others not. These
> +types include conses, vectors, strings, and symbols. For example,
> +although @code{"aaa"} yields a string that should not be changed,
> +@code{(make-string 3 ?a)} yields a mutable string that can be
> changed via later calls to @code{aset}.
Is this a good statement? The string read syntax, and the syntax for
lists makes it easy to make such objects part of a program. But all
classes of objects you call mutable can end up as part of a program.
Are there any classes of "types" where all members are always mutable?
Second point: you mix up objects vs. object evaluation. For conses you
speak about the objects, for symbols about the binding (i.e. the result
of the evaluation). Conses can also be evaluated (most programs are
conses), but that's surely not what you want to describe. I would not
say symbols are mutable. Symbols are constant AFAICT, their bindings
are not (variables are not constant).
> + A mutable object stops being mutable if it is part of an expression
> +that is evaluated. For example:
FWIW, I would feel better about the word "mutable" if you would
introduce the term like "safely mutable", and then say that we call it
just "mutable" in the following sections because this is shorter. Drew
mentioned his dislike for the term "safe" AFAIR but I think "my Emacs
won't crash if I follow this" vs. "it can crash" describes some kind of
safety. Ignore if this comment is irrelevant because this is already
done or treated otherwise.
> + When the same value appears multiple times in a program, the Lisp
> +interpreter might save time or space by reusing existing values or
> +their components. For example, @code{(eq "abc" "abc")} returns
I think we call "values" what evaluation of expressions yields, so
values don't appear in a program (to be read). I don't know the
backgrounds and when this can happen. Is it always the interpreter that
does this mapping?
"Same syntax" is not good as well:
(eq (list 1 2 3) (list 1 2 3))
doesn't provoke the pitfall you warn about, but your wording doesn't
make clear why the one case is ok and the other is not. Maybe it's
again as simple as saying something about objects as being part of a
program?
Thanks again,
Michael.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Mon, 11 May 2020 00:28:01 GMT)
Full text and
rfc822 format available.
Message #432 received at 40671 <at> debbugs.gnu.org (full text, mbox):
Thanks, Michael,
+1 on your points, but this one especially:
On 11.05.2020 03:00, Michael Heerdegen wrote:
>> + A mutable object stops being mutable if it is part of an expression
>> +that is evaluated. For example:
>
> FWIW, I would feel better about the word "mutable" if you would
> introduce the term like "safely mutable", and then say that we call it
> just "mutable" in the following sections because this is shorter. Drew
> mentioned his dislike for the term "safe" AFAIR but I think "my Emacs
> won't crash if I follow this" vs. "it can crash" describes some kind of
> safety.
"safely mutable" definitely sounds better to me. And while we might use
the shorthand "mutable" in the corresponding section, while referring to
this notion outside of it, it would be better to use the full two-word
version.
>> + When the same value appears multiple times in a program, the Lisp
>> +interpreter might save time or space by reusing existing values or
>> +their components. For example, @code{(eq "abc" "abc")} returns
>
> I think we call "values" what evaluation of expressions yields, so
> values don't appear in a program (to be read). I don't know the
> backgrounds and when this can happen. Is it always the interpreter that
> does this mapping?
>
> "Same syntax" is not good as well:
>
> (eq (list 1 2 3) (list 1 2 3))
>
> doesn't provoke the pitfall you warn about, but your wording doesn't
> make clear why the one case is ok and the other is not. Maybe it's
> again as simple as saying something about objects as being part of a
> program?
FWIW, CLtL seems to use a clunky term "similar as constants" for this.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Mon, 11 May 2020 00:46:02 GMT)
Full text and
rfc822 format available.
Message #435 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 10.05.2020 20:29, Paul Eggert wrote:
> On 5/9/20 8:13 PM, Dmitry Gutov wrote:
>
>> You start talking about objects that "should [not] change". And give an example
>> of an object that _cannot_ change.
>
> That's easily altered to also give an example of an object that should not
> change; see attached patch.
Quoting the new paragraph. Now it goes "should not" -> "cannot":
+ Some Lisp objects should never change. For example, the Lisp
+expression @code{"aaa"} yields a string, but you should not change
+its contents. Indeed, some objects cannot be changed; for example,
+although you can create a new number by calculating one, Lisp provides
+no operation to change the value of an existing number.
"Indeed"?
>> I could understand it if it was describing an existing type system of the
>> language, or implementation internals, but this is a purely imaginary type
>> system.
>
> objects.texi already talks about the Emacs Lisp type system and specifically
> mentions strings, conses, etc. as types. Even if one considers the Emacs Lisp
> type system to be "imaginary", it's reasonable to use the documentation's
> already-existing terminology here.
Strings, conses, etc, are anything but imaginary (try using one in a
function that expects another, and you'll almost always get a runtime
error). The changing "mutability" status is imaginary, however.
This also requires the reader to read the manual without missing a
reference. A regular person would not understand your meaning of
"mutable" without following the reference to {Mutability}. Which not
everybody is going to do, and which is harder to do when reading a
printed version.
>> the list object didn't change, just an outside reference to its head was
>> created,
>
> The attached patch alters the example so that the list object does change (or at
> least tries to).
Does is ignore the possibility of the example in the previous version, then?
>> The opposite of "mutable" is "immutable". Are string literals immutable? They are
>> not.
>
> They might be mutable, and they might not be. The documentation deliberately
> doesn't say, because we don't want to document the details (they have changed in
> the past and are likely to change in the future).
I'm trying to point out the incompatibility with the regular meanings of
the words used.
Also see Michael's suggestion.
>> Overall the phrase "that might be shared" is a good replacement. Why not keep to
>> it?
>
> Because it's not an accurate statement of the problem. The set of objects that
> might be shared differs from the set of objects that should not change. The
> Mutability node focuses on the latter set of objects, and gives the former as an
> example but it is not the only sort of object that should not change.
But if we don't mention such cases in "Mutability", where do we cover them?
I'm also looking at the new example:
+(let* ((x (list 0.5))
+ (y (eval (list 'quote x))))
+ (setcar x 1.5) ;; The program should not do this.
+ y)
Why is this a problem? Do we expect this it could lead to a segfault?
Evaluating this expression in IELM leads to a stable result. Putting it
in a function doesn't bring any surprises either.
Example:
ELISP> (defun test (v)
(let* ((x (list v))
(y (eval (list 'quote x))))
(setcar x 1.5)
y))
test
ELISP> (test 3)
(1.5)
It's an advanced, yes, but clearly the expected behavior if someone
wrote a function like that.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Mon, 11 May 2020 01:49:01 GMT)
Full text and
rfc822 format available.
Message #438 received at 40671 <at> debbugs.gnu.org (full text, mbox):
> Symbols are constant AFAICT, their bindings
> are not (variables are not constant).
Their bindings as variables are not constant, except
for keyword symbols, nil, and t (are there any others?).
But are symbols otherwise constant, besides their
values? Depends what you mean by "symbol", perhaps.
Certainly you can change not only `symbol-value' but
also `symbol-function' and `symbol-plist'. I don't
see symbols as very constant.
[Personally, as I suggested, I don't think the text
about this gotcha should get down in the weeds about
mutable/immutable anything. I think it should stay
general, not try to catalog specific problems (e.g.
strings, conses, whatever).
It should show and explain a very simple example of
what can happen with a quoted list, and then leave
it at that. Maybe it should mention, as you said a
while back, that there are the reader, interpreter,
and byte compiler, when saying something about the
problem in general. But I already said all this,
and I said I was done here...]
BTW, in Common Lisp you can even do nasty things
like modify the `symbol-name' of a symbol. For that,
CLTL2 says:
"It is an extremely bad idea to modify a string
being used as the print name of a symbol. Such
a modification may tremendously confuse the
function `read' and the package system."
That's the _kind_ of somewhat vague gotcha
description I think we should have. Enough to
let users know they don't want to do it.
> > + A mutable object stops being mutable if it is part of an
> expression
> > +that is evaluated. For example:
>
> FWIW, I would feel better about the word "mutable" if you would
> introduce the term like "safely mutable", and then say that we call it
> just "mutable" in the following sections because this is shorter. Drew
> mentioned his dislike for the term "safe" AFAIR
I don't recall saying that, but I may have. Not
sure what's meant here. I objected to using
"dangerous", as if the gotcha was generally
hazardous to life.
> but I think "my Emacs
> won't crash if I follow this" vs. "it can crash" describes some kind of
> safety. Ignore if this comment is irrelevant because this is already
> done or treated otherwise.
To me, the problem for users is not so much that
Emacs can crash as it is that they may lose data.
Or more likely (and worth mentioning, I think, as
a motivator) that they might have a heck of a time
trying to figure out why their code doesn't seem
to behave as they expect. Seeing a quoted list
in source code can make you think new list
structure is created each time that code is run.
Code "initializing" part of some list structure
to a quoted list might give you the impression
that that's what happens each time (e.g. each
time a function that seems to do that gets called),
but the same cons from a first evaluation (or
reading) of that quoted list might remain in use
for each invocation of the function. And if you
at some point modify that cons then you might not
get your apparent "initialization" to that quoted
list each time the function's invoked.
> > + When the same value appears multiple times
^^^^^ ^^^^^^^
> > +in a program, the Lisp interpreter might save
> > +time or space by reusing existing values or
^^^^^^
> > +their components.
>
> I think we call "values" what evaluation of expressions yields, so
> values don't appear in a program (to be read). I don't know the
> backgrounds and when this can happen. Is it always the interpreter
> that does this mapping?
I think that text wasn't too bad, but I see your point.
And it's especially not good to use "value" in the two
different senses, as (1) something you see ("appears")
in a source program and (2) a runtime value that results
from reading, byte-compiling, or interpreting that source
code.
Maybe "object" or "Lisp object" instead of "value", for
#2?
(Note: I didn't read the full text. I'm just reacting
to what was cited in your mail. Sorry.)
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Mon, 11 May 2020 01:54:01 GMT)
Full text and
rfc822 format available.
Message #441 received at 40671 <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
On 5/10/20 5:00 PM, Michael Heerdegen wrote:
> Are there any classes of "types" where all members are always mutable?
Markers, for one. (This is mentioned in the previous paragraph.) There are
others. We needn't list them all here.
> Second point: you mix up objects vs. object evaluation. For conses you
> speak about the objects, for symbols about the binding (i.e. the result
> of the evaluation). Conses can also be evaluated (most programs are
> conses), but that's surely not what you want to describe. I would not
> say symbols are mutable. Symbols are constant AFAICT, their bindings
> are not (variables are not constant).
All good points. The simplest fix is to not mention symbol bindings here, as
they're a complicated topic. Their mutability issues can be documented later, if
someone wants to tackle the subject.
> FWIW, I would feel better about the word "mutable" if you would
> introduce the term like "safely mutable", and then say that we call it
> just "mutable" in the following sections because this is shorter. Drew
> mentioned his dislike for the term "safe" AFAIR but I think "my Emacs
> won't crash if I follow this" vs. "it can crash" describes some kind of
> safety. Ignore if this comment is irrelevant because this is already
> done or treated otherwise.
I think that's pretty much already done, since the definition of "mutable" says
"it is safe to change their values". I'd rather not use the term "safely
mutable" everywhere, as I don't want the manual to push the idea of "safely
mutable" as opposed to "mutable"; instead, I want the manual to look forward to
a future version where objects are either mutable or are immutable (and the
latter is checked by the interpreter).
>> + When the same value appears multiple times in a program, the Lisp
>> +interpreter might save time or space by reusing existing values or
>> +their components. For example, @code{(eq "abc" "abc")} returns
>
> I think we call "values" what evaluation of expressions yields, so
> values don't appear in a program (to be read).
They can if one feeds the values into 'eval', which runs part of a program. And
'read' can read programs. So I'm not sure I get the distinction.
> Is it always the interpreter that
> does this mapping?
This section is written at a high level and uses "interpreter" to refer to the
whole Emacs Lisp system. (This usage is longstanding in the manual.) So if any
mapping is being done, it's by the "interpreter" in that sense.
> "Same syntax" is not good as well:
I don't see that phrase used in the manual. I assume you meant "same values"?
> (eq (list 1 2 3) (list 1 2 3))
>
> doesn't provoke the pitfall you warn about, but your wording doesn't
> make clear why the one case is ok and the other is not. Maybe it's
> again as simple as saying something about objects as being part of a
> program?
I changed it to use "parts of a program" and I can changed the "values" to
"constants".
Further patch attached; it also attempts to address the issues raised by Dmitry
and Drew recently. I'm also attaching a single patch that accumulates it into
all the patches proposed for emacs-27.
[0001-doc-lispref-objects.texi-Mutability-More-tweaking.patch (text/x-patch, attachment)]
[0001-Don-t-use-constant-for-values-you-shouldn-t-change.patch (text/x-patch, attachment)]
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Mon, 11 May 2020 01:56:02 GMT)
Full text and
rfc822 format available.
Message #444 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 11.05.2020 04:47, Drew Adams wrote:
>> Drew
>> mentioned his dislike for the term "safe" AFAIR
> I don't recall saying that, but I may have. Not
> sure what's meant here. I objected to using
> "dangerous", as if the gotcha was generally
> hazardous to life.
Would "unsafe mutations" be better?
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Mon, 11 May 2020 01:58:01 GMT)
Full text and
rfc822 format available.
Message #447 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 5/10/20 5:44 PM, Dmitry Gutov wrote:
> "Indeed"?
Indeed yes. :-)
> The changing "mutability" status is imaginary, however.
It's part of a spec. Not every constraint in a spec needs to be enforced
directly by the implementation. That doesn't mean these constraints are "imaginary".
> This also requires the reader to read the manual without missing a reference. A
> regular person would not understand your meaning of "mutable" without following
> the reference to {Mutability}.
If a paragraph says "mutable" and has a cross-reference to the "Mutability"
section, that's good enough. This is a reference manual, not a tutorial, and we
can assume a reasonable level of competence on the part of the reader.
> Does is ignore the possibility of the example in the previous version, then?
I don't understand this remark.
> I'm trying to point out the incompatibility with the regular meanings of the
> words used.
>> Because it's not an accurate statement of the problem. The set of objects that
>> might be shared differs from the set of objects that should not change. The
>> Mutability node focuses on the latter set of objects, and gives the former as an
>> example but it is not the only sort of object that should not change.
>
> But if we don't mention such cases in "Mutability", where do we cover them?
Fair enough. I added an example of such a case to "Mutability" in the proposal
in my most-recent email (Bug#40671#441).
> +(let* ((x (list 0.5))
> + (y (eval (list 'quote x))))
> + (setcar x 1.5) ;; The program should not do this.
> + y)
>
> Why is this a problem? Do we expect this it could lead to a segfault?
Probably not a segfault in the current implementation, but the behavior isn't
defined. And we don't want the behavior to be defined, as that would prohibit
some optimizations that may be coming down the road.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Mon, 11 May 2020 02:35:01 GMT)
Full text and
rfc822 format available.
Message #450 received at 40671 <at> debbugs.gnu.org (full text, mbox):
> >> Drew mentioned his dislike for the term "safe" AFAIR
> >
> > I don't recall saying that, but I may have. Not
> > sure what's meant here. I objected to using
> > "dangerous", as if the gotcha was generally
> > hazardous to life.
>
> Would "unsafe mutations" be better?
I didn't really want to get into this with you
guys. I just wanted to reply to Michael's
message. But...
I'd prefer that we speak of "modification",
not "mutation". "Mutation" has a connotation
of something happening on its own. If that
were the case then we wouldn't be trying to
tell people not to do something!
I'm not a big fan of "safe" (or, especially,
"dangerous"), unless it's about human safety
(e.g. an airline maintenance manual).
I'd prefer that we just tell users that if
they do certain things then the behavior of
their code _might not be what they expect_.
Or that the behavior is "undefined". And
let it go at that.
What's important is to give them some idea
of _what_ it is that we're telling them not
to do. I don't have an example, but I think
a simple quoted-list example can get the point
across. And then you can say something about
strings or whatever, if you like, without
bothering with more examples.
My advice: don't try to explain too well
just what happens. See if you can get the
general point across without any exhaustive
rundown of a bunch of different cases or
trying to be too exact.
If a user understands that internal Lisp
structures (objects) can get created by
(1) the Lisp reader, (2) the interpreter, and
(3) the byte compiler, and if s?he understands
that what's seen in the source code does not
necessarily correspond to when a corresponding
Lisp object gets created, then s?he'll get it.
Just when, and how many times does the source
code of a quoted list result in a new cons?
You can't really know. When it's read?
byte-compiled?
A new Lisp user thinks in terms of interpreted
source code. Seeing a quoted list, s?he thinks
that a new cons is created each time it's read,
interpreted, or byte-compiled. But that may
not (typically does not) happen. If you modify
the cons that resulted from a source-code quoted
list then that _same_ cons might be baked into
the internal code thereafter.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Mon, 11 May 2020 02:57:02 GMT)
Full text and
rfc822 format available.
Message #453 received at 40671 <at> debbugs.gnu.org (full text, mbox):
Drew Adams <drew.adams <at> oracle.com> writes:
> But are symbols otherwise constant, besides their
> values? Depends what you mean by "symbol", perhaps.
> Certainly you can change not only `symbol-value' but
> also `symbol-function' and `symbol-plist'. I don't
> see symbols as very constant.
Also makes sense, yes.
> I think that text wasn't too bad, but I see your point.
>
> And it's especially not good to use "value" in the two
> different senses, as (1) something you see ("appears")
> in a source program and (2) a runtime value that results
> from reading, byte-compiling, or interpreting that source
> code.
>
> Maybe "object" or "Lisp object" instead of "value", for
> #2?
The term "value" is used all over the place in the manual for #2, so
people are familiar with it, we need a better term for (1) instead I
think. (info "(elisp) Equality Predicates") already uses the term
"literal object" btw:
The Emacs Lisp byte compiler may collapse identical literal
objects, such as literal strings, into references to the same
object, with the effect that the byte-compiled code will compare
such objects as ‘eq’, while the interpreted version of the same
code will not.
Michael.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Mon, 11 May 2020 03:19:02 GMT)
Full text and
rfc822 format available.
Message #456 received at 40671 <at> debbugs.gnu.org (full text, mbox):
Paul Eggert <eggert <at> cs.ucla.edu> writes:
> All good points. The simplest fix is to not mention symbol bindings
> here, as they're a complicated topic.
Yes, agreed.
> >> + When the same value appears multiple times in a program, the Lisp
> >> +interpreter might save time or space by reusing existing values or
> >> +their components. For example, @code{(eq "abc" "abc")} returns
> >
> > I think we call "values" what evaluation of expressions yields, so
> > values don't appear in a program (to be read).
>
> They can if one feeds the values into 'eval', which runs part of a
> program. And 'read' can read programs. So I'm not sure I get the
> distinction.
Now I get how you meant this. I read the sentence more with a written
program and syntax in mind.
Michael.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Mon, 11 May 2020 04:22:02 GMT)
Full text and
rfc822 format available.
Message #459 received at 40671 <at> debbugs.gnu.org (full text, mbox):
(This ended up long and a bit off-topic; sorry.
Hope it still helps.)
> > And it's especially not good to use "value" in the two
> > different senses, as (1) something you see ("appears")
> > in a source program and (2) a runtime value that results
> > from reading, byte-compiling, or interpreting that source
> > code.
> >
> > Maybe "object" or "Lisp object" instead of "value", for
> > #2?
>
> The term "value" is used all over the place in the manual for #2, so
> people are familiar with it, we need a better term for (1) instead I
> think. (info "(elisp) Equality Predicates") already uses the term
> "literal object" btw:
>
> The Emacs Lisp byte compiler may collapse identical literal
> objects, such as literal strings, into references to the same
> object, with the effect that the byte-compiled code will compare
> such objects as ‘eq’, while the interpreted version of the same
> code will not.
BTW, that node does NOT already contain that text.
That paragraph is new for Emacs 27, which is not yet
released. IOW, that text is _proposed_ for Emacs 27.
But OK. That describes the problem as being about
"literal objects".
That's essentially the message we're discussing, I
think, but it should be broadened beyond just the
byte-compiler, I think.
Where, if anywhere, does the manual define or describe
"literal objects"? I don't think we want to be doing
that, unless it's done carefully.
For the message we're talking about, I'd say start by
talking about source code: forms, sexps.
Yes, the sexps that are problematic are, I suppose,
what that text calls "literal objects". But I don't
see that term defined anywhere. And it seems odd to
me to talk about source-code thingies as "objects".
Maybe the result of reading, or the result of some
initial stage of byte-compiling or interpreting, is a
"literal object", but is a source-code sexp a "literal
object"?
A "literal string" makes sense to me, as a string
in source code ("..."). But "literal object" doesn't
sound like a source-code thing. Perhaps that's what
literal numbers, strings, etc. in source code are
called now - "objects"? Sounds odd to me.
Checking `i literal' in the Emacs 27 manual, I see
no "literal object", but I do see "literal evaluation"
and "literal in rx", where "literal" is used as a noun
(in both cases presumably).
However, the former index entry takes you to node
`Self-Evaluating Forms', which never once uses the
word "literal" (as adjective or noun) - it talks only
about "forms", i.e., source code. That text looks OK.
The index item seems wrong - you never get any text
that tells you anything about "literal evaluation".
This node, and index entry "literal evaluation" are
in Emacs 26 (and probably earlier).
[Index entry "literal in rx" takes you to node `Rx
Constructs', where you find `(literal EXPR)', which
is about matching a "literal string". To me, "literal
string" is clear enough, and I think of it as both a
source-code thing (text) and as a Lisp object (after
reading the text, for example). This node is new for
Emacs 27.]
Searching the Emacs 27 Elisp manual for "literal"
I see that there is another occurrence of "literal
object", also in a node that is new for release 27,
`pcase Macro'.
There too the term "literal object"is totally
unexplained: "Matches if EXPL equals the literal
object. This is a special case of ‘'VAL’, above,
possible because literal objects of these types
are self-quoting."
(The "possible because..." is not correct English,
and I don't know what it's trying to say. Maybe
"possibly because..." was meant. Or maybe what
was meant was to end a sentence after "above" and
start a new sentence with "This is possible
because...".)
And again, in another new-to-Emacs-27 node,
`Backquote Patterns', I see "literal object":
"Matches if the corresponding element of EXPVAL
is ‘equal’ to the specified literal object." And
again, the term is totally unexplained.
(That node also has "literal symbol", which, like
"literal string" doesn't shock me. It is "literal
object" that I find odd.)
Both Emacs 27 and 26, node `Mode-Specific Indent',
mention "a literal value (usually zero)". That's
OK, I guess, but I think it's untrue. I think
what's meant is just "a number (usually zero)".
There's nothing literal about it.
Node `Rx Constructs' of Emacs 27 introduces
"Literals" (noun) as forms (source-code sexps),
and shows that they can be strings or chars.
I don't have a problem with that.
Node `Rx Functions' says "if `literal' or `regexp'
forms are used", and I guess that's referring to
the forms `(literal...)' and `(regexp...)'
introduced in node `Rx Constructs'. And it refers
to "string literals". All of that's OK.
Node `Extending Rx' mentions "a list literal".
Again, like string literal, char literal, etc.,
this isn't introduced anywhere that I can see,
but that's OK - use of "literal" as a noun in
such cases clearly means the same as "literal
string" etc.
Node `Module Initialization' is another new one
for Emacs 27, and another place where "literal"
is used as a noun: "number literal". Again, no
problem for me with that (like "string literal").
All other occurrences of "literal" in the manual
are about literal chars, finding a file literally,
displaying or matching text literally, or
replacing literal text. No problem there, and
nothing new there.
In sum, "literal object" is nowhere defined,
described, or explained. And "object" sounds
wrong, to me, when referring to source-code text.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Mon, 11 May 2020 04:53:01 GMT)
Full text and
rfc822 format available.
Message #462 received at 40671 <at> debbugs.gnu.org (full text, mbox):
Drew Adams <drew.adams <at> oracle.com> writes:
> In sum, "literal object" is nowhere defined,
> described, or explained. And "object" sounds
> wrong, to me, when referring to source-code text.
Yes, it's vague. Maybe the place I cited should formulated otherwise,
since we didn't use the term for the "no no" objects, for reasons.
BTW (also @Paul) there are some places (five or so) in Elisp source
files that look like
(nconc '(x y z) (get-some-list))
Should they be rewritten?
Michael.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Mon, 11 May 2020 06:29:01 GMT)
Full text and
rfc822 format available.
Message #465 received at 40671 <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
On 5/10/20 9:51 PM, Michael Heerdegen wrote:
> BTW (also @Paul) there are some places (five or so) in Elisp source
> files that look like
>
> (nconc '(x y z) (get-some-list))
>
> Should they be rewritten?
Yes, of course. Does the attached diff (against master) match what you found?
[nconc.diff (text/x-patch, attachment)]
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Mon, 11 May 2020 13:58:02 GMT)
Full text and
rfc822 format available.
Message #468 received at 40671 <at> debbugs.gnu.org (full text, mbox):
Paul Eggert <eggert <at> cs.ucla.edu> writes:
> (defvar gnus-article-mode-line-format-alist
> - (nconc '((?w (gnus-article-wash-status) ?s)
> - (?m (gnus-article-mime-part-status) ?s))
> - gnus-summary-mode-line-format-alist))
> + (nconc `((?w (gnus-article-wash-status) ?s)
> + (?m (gnus-article-mime-part-status) ?s)
> + ,@gnus-summary-mode-line-format-alist)))
You meant to remove the nconc call too, right?
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Mon, 11 May 2020 22:32:02 GMT)
Full text and
rfc822 format available.
Message #471 received at 40671 <at> debbugs.gnu.org (full text, mbox):
Paul Eggert <eggert <at> cs.ucla.edu> writes:
> Yes, of course. Does the attached diff (against master) match what you
> found?
Yes, I think so.
Thanks,
Michael.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Mon, 11 May 2020 22:37:02 GMT)
Full text and
rfc822 format available.
Message #474 received at 40671 <at> debbugs.gnu.org (full text, mbox):
Noam Postavsky <npostavs <at> gmail.com> writes:
> Paul Eggert <eggert <at> cs.ucla.edu> writes:
>
> > (defvar gnus-article-mode-line-format-alist
> > - (nconc '((?w (gnus-article-wash-status) ?s)
> > - (?m (gnus-article-mime-part-status) ?s))
> > - gnus-summary-mode-line-format-alist))
> > + (nconc `((?w (gnus-article-wash-status) ?s)
> > + (?m (gnus-article-mime-part-status) ?s)
> > + ,@gnus-summary-mode-line-format-alist)))
>
> You meant to remove the nconc call too, right?
That, and, the code still makes literal lists to alist entries. If you
modify these associations, you modify these literal lists.
I wonder how many of such uses of backquote expressions used to
construct alists are scattered throughout the Emacs code.
Michael.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Tue, 12 May 2020 02:01:01 GMT)
Full text and
rfc822 format available.
Message #477 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 11.05.2020 04:57, Paul Eggert wrote:
> On 5/10/20 5:44 PM, Dmitry Gutov wrote:
>
>> "Indeed"?
>
> Indeed yes. :-)
That paragraph doesn't scan. You could replace that word with "And", though.
>> The changing "mutability" status is imaginary, however.
>
> It's part of a spec. Not every constraint in a spec needs to be enforced
> directly by the implementation. That doesn't mean these constraints are "imaginary".
Part of the "spec" you just added in this series of patches.
I think that's exactly what a "constraint" means: something that is
enforced.
>>> Because it's not an accurate statement of the problem. The set of objects that
>>> might be shared differs from the set of objects that should not change. The
>>> Mutability node focuses on the latter set of objects, and gives the former as an
>>> example but it is not the only sort of object that should not change.
>>
>> But if we don't mention such cases in "Mutability", where do we cover them?
>
> Fair enough. I added an example of such a case to "Mutability" in the proposal
> in my most-recent email (Bug#40671#441).
Curious case of an meaningful reference where I have to construct the
URL manually anyway. The symbol-name example? I'm not sure it's really
important to warn about this one in particular.
But are we effectively saying "there exist values that are unsafe to
modify, for example, any return values of symbol-name", and that's it?
When one tries to describe "unsafe" things to do, they don't just give a
few examples, they usually try to cover all cases. Perhaps by including
some false positives (which the 'let*' example below, I think, is), but
trying hard to avoid false negatives.
Inventing a name for such values doesn't help if the user doesn't have
enough knowledge to avoid all members of this set. Or is "part of an
expression that is evaluated" after all the test we'll be teaching?
By the way, I have read last two paragraphs of that section now. C and
"constants" are still there.
>> +(let* ((x (list 0.5))
>> + (y (eval (list 'quote x))))
>> + (setcar x 1.5) ;; The program should not do this.
>> + y)
>>
>> Why is this a problem? Do we expect this it could lead to a segfault?
>
> Probably not a segfault in the current implementation, but the behavior isn't
> defined. And we don't want the behavior to be defined, as that would prohibit
> some optimizations that may be coming down the road.
I'm curious to see the discussion about actually making this error at
runtime in one of the next Emacs version.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Tue, 12 May 2020 03:21:01 GMT)
Full text and
rfc822 format available.
Message #480 received at 40671 <at> debbugs.gnu.org (full text, mbox):
[[[ To any NSA and FBI agents reading my email: please consider ]]]
[[[ whether defending the US Constitution against all enemies, ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]
Would someone like to search all our Lisp sources for "(nconc '" and
check every occurrence?
--
Dr Richard Stallman
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Tue, 12 May 2020 04:26:02 GMT)
Full text and
rfc822 format available.
Message #483 received at 40671 <at> debbugs.gnu.org (full text, mbox):
Richard Stallman <rms <at> gnu.org> writes:
> Would someone like to search all our Lisp sources for "(nconc '" and
> check every occurrence?
Paul and I found the same matches with probably different methods - so I
think this already has been done.
Michael.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Wed, 13 May 2020 03:58:02 GMT)
Full text and
rfc822 format available.
Message #486 received at 40671 <at> debbugs.gnu.org (full text, mbox):
[[[ To any NSA and FBI agents reading my email: please consider ]]]
[[[ whether defending the US Constitution against all enemies, ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]
> Paul and I found the same matches with probably different methods - so I
> think this already has been done.
When you found them, did you fix them?
--
Dr Richard Stallman
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Wed, 13 May 2020 05:06:02 GMT)
Full text and
rfc822 format available.
Message #489 received at 40671 <at> debbugs.gnu.org (full text, mbox):
Richard Stallman <rms <at> gnu.org> writes:
> When you found them, did you fix them?
Paul has already proposed a patch, I guess he will install it later
(maybe after caring about the remarks by Noam and me).
Michael.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Thu, 14 May 2020 05:15:01 GMT)
Full text and
rfc822 format available.
Message #492 received at 40671 <at> debbugs.gnu.org (full text, mbox):
[[[ To any NSA and FBI agents reading my email: please consider ]]]
[[[ whether defending the US Constitution against all enemies, ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]
> Paul has already proposed a patch, I guess he will install it later
> (maybe after caring about the remarks by Noam and me).
Thank you, and Paul.
--
Dr Richard Stallman
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 17 May 2020 00:12:01 GMT)
Full text and
rfc822 format available.
Message #495 received at 40671 <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
On 5/11/20 2:29 AM, Mattias Engdegård wrote:
> As an experiment, I added an immutable cons type some time ago and found these and more. The attachment contains some of the adjustments made at the time. This isn't complete; I never got to a full bootstrap, for unrelated reasons.
Thanks for sending that patch. Even if incomplete, it's better to not try to
modify constants so I installed the attached into master; it's derived from your
patch and supersedes my earlier (typo-containing) patch about nconc.
> By the way: Is there any reason you prefer `(a b c ,@tail) to (append '(a b c) tail)?
No, I just wasn't thinking. The attached patch uses 'append'.
[0001-Don-t-attempt-to-modify-constant-conses.txt (text/plain, attachment)]
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 17 May 2020 01:29:01 GMT)
Full text and
rfc822 format available.
Message #498 received at 40671 <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
On 5/11/20 6:59 PM, Dmitry Gutov wrote:
> I think that's exactly what a "constraint" means: something that is enforced.
Not necessarily. In some software systems constraints are not enforced. (Use
Google to search for "unenforced constraints", which can be quite the thing in
the database world.) But I am straying from the documentation issue.
> The symbol-name example? I'm not sure it's really important to
> warn about this one in particular.
OK, but then you also write:
> When one tries to
> describe "unsafe" things to do, they don't just give a few examples, they
> usually try to cover all cases.
... and symbol-name is one of the cases.
As far as the bigger project (cover all the cases) goes, I don't know how
feasible that would be. I suppose someone could take that on as a further task.
In the attached patch I did add one more example, of calling the copy-sequence
function, but there would be lots more examples where that came from.
> Inventing a name for such values doesn't help if the user doesn't have enough
> knowledge to avoid all members of this set. Or is "part of an expression that is
> evaluated" after all the test we'll be teaching?
No, it's not the only way that something can be a constant. This is why the
(symbol-name 'cons) example is relevant: it yields a string that has never been
"part of an expression that is evaluated".
> By the way, I have read last two paragraphs of that section now. C and
> "constants" are still there.
It's appropriate to talk about constants in the footnote that mentions languages
that have constants. And the footnote is helpful, because it documents the core
issue that prompted this long thread: different languages/traditions mean
different things by the word "constant" and/or "immutable", and the footnote
makes it clear that the documentation's "objects that should not be changed"
follows the Common Lisp / C tradition, not the Python / JavaScript tradition.
That being said, it'd be helpful if the footnote mentions both "constants" and
"immutable objects" if only to remind readers of relevant buzzwords. So I did
that in the attached patch.
> I'm curious to see the discussion about actually making this error at runtime in
> one of the next Emacs version.
Me too. That's for a later thread, one that I'd like to get rolling instead of
worrying about the minor details in the current doc. To help get things rolling
I installed the patch that I proposed earlier, followed by the attached minor
patch that attempt to address the abovementioned issues. I plan to look at
improving the runtime checking next.
[0001-Minor-fixups-for-mutability-doc.patch (text/x-patch, attachment)]
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 17 May 2020 05:04:01 GMT)
Full text and
rfc822 format available.
Message #501 received at 40671 <at> debbugs.gnu.org (full text, mbox):
Paul Eggert <eggert <at> cs.ucla.edu> writes:
> ... and symbol-name is one of the cases.
I'm wondering about this one for a while, too. Is it that the resulting
string is really like the "object is part of an evaluated program"
cases, or is it just that modifying it has an unwanted side effect
(changing the name of the symbol, and Emacs doesn't handle this
correctly). I mean, you can modify a lot of objects in Emacs and that
will cause trouble. We surely don't want to call them all constant or
not safely mutable or whatever. How is the result of `symbol-name'
different from these other cases? Is it only that the side effect/ mess
is not visible from Lisp? Where do you draw the line? Yes, the hidden
question is still what your definition of safely mutable is.
Thanks,
Michael.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 17 May 2020 09:45:02 GMT)
Full text and
rfc822 format available.
Message #504 received at 40671 <at> debbugs.gnu.org (full text, mbox):
17 maj 2020 kl. 02.11 skrev Paul Eggert <eggert <at> cs.ucla.edu>:
> Thanks for sending that patch. Even if incomplete, it's better to not try to
> modify constants so I installed the attached into master; it's derived from your
> patch and supersedes my earlier (typo-containing) patch about nconc.
Thank you, and your resulting patch looks all right. As an extra check, I verified that the AWK-generated files result in the same tables.
The follow-up change reducing string and vector literal mutation also looks fine. Just out of curiosity, how did you locate those instances? By searching for calls to mutating functions or with an instrumented Emacs?
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 17 May 2020 12:40:01 GMT)
Full text and
rfc822 format available.
Message #507 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 17.05.2020 04:28, Paul Eggert wrote:
> On 5/11/20 6:59 PM, Dmitry Gutov wrote:
>
>> I think that's exactly what a "constraint" means: something that is enforced.
>
> Not necessarily. In some software systems constraints are not enforced. (Use
> Google to search for "unenforced constraints", which can be quite the thing in
> the database world.) But I am straying from the documentation issue.
An existence of a technical term doesn't really cancel out the regular
meaning of the word.
>> The symbol-name example? I'm not sure it's really important to
>> warn about this one in particular.
>
> OK, but then you also write:
>
>> When one tries to
>> describe "unsafe" things to do, they don't just give a few examples, they
>> usually try to cover all cases.
>
> ... and symbol-name is one of the cases.
These are just two distinct points:
1. You seem to be trying to redefine the term "motable" as a way to
avoid enumerating all possible cases. But since the meaning of the term
is different from how it is understood in the English language, it
should at least have a proper definition. But the said definition would
have to cover the possible cases too.
2. symbol-name seems like something we don't have to explain specially.
So if that's the only counter-example to "values that appear in
expressions", or whichever phrase we chose, then we could as well just
on the phrase and dispense with additional complications. Which would
also make having a redefinition of the term "mutable" less relevant.
> As far as the bigger project (cover all the cases) goes, I don't know how
> feasible that would be. I suppose someone could take that on as a further task.
> In the attached patch I did add one more example, of calling the copy-sequence
> function, but there would be lots more examples where that came from.
>
>> Inventing a name for such values doesn't help if the user doesn't have enough
>> knowledge to avoid all members of this set. Or is "part of an expression that is
>> evaluated" after all the test we'll be teaching?
>
> No, it's not the only way that something can be a constant. This is why the
> (symbol-name 'cons) example is relevant: it yields a string that has never been
> "part of an expression that is evaluated".
There's an argument to be made that the name of the symbol 'cons is part
of any expression or program that uses `cons'.
>> By the way, I have read last two paragraphs of that section now. C and
>> "constants" are still there.
>
> It's appropriate to talk about constants in the footnote that mentions languages
> that have constants. And the footnote is helpful, because it documents the core
> issue that prompted this long thread: different languages/traditions mean
> different things by the word "constant" and/or "immutable", and the footnote
> makes it clear that the documentation's "objects that should not be changed"
> follows the Common Lisp / C tradition, not the Python / JavaScript tradition.
>
> That being said, it'd be helpful if the footnote mentions both "constants" and
> "immutable objects" if only to remind readers of relevant buzzwords. So I did
> that in the attached patch.
I like that change, thank you.
>> I'm curious to see the discussion about actually making this error at runtime in
>> one of the next Emacs version.
>
> Me too. That's for a later thread, one that I'd like to get rolling instead of
> worrying about the minor details in the current doc. To help get things rolling
> I installed the patch that I proposed earlier, followed by the attached minor
> patch that attempt to address the abovementioned issues. I plan to look at
> improving the runtime checking next.
OK, thank you.
My intuition, though, that making cases like the one you just changed in
emacs-lisp-mode-tests.el blow up at runtime will create a massive
backward incompatibility.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 17 May 2020 16:22:02 GMT)
Full text and
rfc822 format available.
Message #510 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 5/17/20 5:39 AM, Dmitry Gutov wrote:
> An existence of a technical term doesn't really cancel out the regular meaning
> of the word.
I continue to be skeptical that "constraints are always enforced" is the regular
meaning of the word "constraints" in computing. Lots of constraints are not
enforced in the computing world. Internet RFCs are a classic example: "Be
liberal in what you accept" means "Don't enforce constraints".
But again, we are straying from the point at hand, as the word "constraints"
isn't used in the documentation when talking about mutability.
> 1. You seem to be trying to redefine the term "motable" as a way to avoid
> enumerating all possible cases.
That is a normal practice for definitions, and this practice increases the
utility of the documentation. The Emacs manual defines "string" without
enumering all possible cases of strings (whether they come from the program
text, or from reading input, or from symbol-name, etc.) because enumerating all
cases would be bloat that would cause more harm than good. Similarly, the manual
defines "mutable" without defining all possible cases of mutable objects.
> 2. symbol-name seems like something we don't have to explain specially.
I don't understand this comment. symbol-name is just an example. It's helpful to
have an example or two, even if they're not absolutely required.
> There's an argument to be made that the name of the symbol 'cons is part of any
> expression or program that uses `cons'.
Sure, and that argument is part of any bigger project to document more about
mutability ("covering all the cases" in some way). This would not be a trivial
project, and it's not something we have to do today.
> My intuition, though, that making cases like the one you just changed in emacs-lisp-mode-tests.el blow up at runtime will create a massive backward incompatibility.
I'm sure there are compatibility issues. But we already have those issues: an
Elisp program that modifies a string constant is already "broken" in that it's
making assumptions that have never been documented and are sometimes not true
even now. Emacs used to have some runtime checking for this bug but it doesn't
now, and when we reinstitute checking we will undoubtedly shake out some latent
bugs in user code.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 17 May 2020 16:35:01 GMT)
Full text and
rfc822 format available.
Message #513 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 5/16/20 10:02 PM, Michael Heerdegen wrote:
> you can modify a lot of objects in Emacs and that
> will cause trouble. We surely don't want to call them all constant or
> not safely mutable or whatever.
We may not *want* to do that, but that's what we're doing now (with the two
classes currently documented as "mutable objects" and "objects that you should
not change"). And I don't see any easy way to change the documentation to draw
the line that we'd like to draw (namely, between "mutable objects" and "objects
that you cannot change") because that's not how Emacs works and changing Emacs's
behavior will be nontrivial.
At this point I suspect it'll be a better of our time to look into improving
Emacs's behavior in this area, and worry about documentation wording later.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#40671
; Package
emacs
.
(Sun, 17 May 2020 16:39:02 GMT)
Full text and
rfc822 format available.
Message #516 received at 40671 <at> debbugs.gnu.org (full text, mbox):
On 5/17/20 2:43 AM, Mattias Engdegård wrote:
> how did you locate those instances? By searching for calls to mutating functions or with an instrumented Emacs?
I built an instrumented Emacs. I am working on making it faster, since I don't
want the extra runtime checks to cost so much that people would prefer sticking
with the current, sometimes-crashing Emacs.
bug archived.
Request was from
Debbugs Internal Request <help-debbugs <at> gnu.org>
to
internal_control <at> debbugs.gnu.org
.
(Mon, 15 Jun 2020 11:24:06 GMT)
Full text and
rfc822 format available.
This bug report was last modified 5 years and 1 day ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.