[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: 31395511: "Don’t attempt to modify constant strings"

From: João Távora
Subject: Re: 31395511: "Don’t attempt to modify constant strings"
Date: Fri, 05 Jun 2020 16:25:28 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux)

Paul Eggert <eggert@cs.ucla.edu> writes:

> On 6/3/20 4:48 PM, João Távora wrote:
>> I think I'd rather this previous behavior were retained, or at least
>> achievable by request.
> It's tricky, as make-text-button in emacs-27 (and earlier) modifies its string
> argument, which is buggy because string constants are not always unique. For
> example:
> (defun example-bug ()
>   (concat "1. " (make-text-button
>                  "example" nil
>                  'action (lambda (_) (message "action 1")))
>           "2. " (make-text-button
>                  "example" nil
>                  'action (lambda (_) (message "action 2")))))
> If you byte-compile this in emacs-27, both buttons message "action 2" because
> there's there's really just one instance of the string constant "example", and
> so there's just one button and the second action overwrites the first.

But if you evaluate it, that doesn't happen, which is probably even

And this is even stranger, IMO:

    (defun example-bug2 ()
      (eq (make-text-button
                     "example" nil
                     'action (lambda (_) (message "action 1")))
                     "example" nil
                     'action (lambda (_) (message "action 2")))))
    (defun example-bug3 ()
      (eq "example" "example"))
    (defun example-bug4 ()
      (let ((str1 "example")
            (str2 "example"))
        (eq str1 str2)))
    (list (example-bug2) (example-bug3) (example-bug4))

  when compiled, last form returns (t nil t)   in emacs 27,
  when compiled, last form returns (nil nil t) in emacs 28.
  when evaluated, last form returns (nil nil nil) in emacs 28.

For comparison, example-bug4 is valid Common Lisp and will return nil in
every Common Lisp implementation I know (I tested with ACL and SBCL),
regardless of whether compiled or evaluated.  I'm reasonably confident
there's somewhere in the Hyperspec where that behaviour may be specified
(I trust some CL pope will find it for me ;-) )

Elisp is its own Lisp of course, and I suppose these things allow for
performance/space optimizations under the hood, but is all that strange
behaviour worth it?

> Does SLY always pass mutable strings to make-text-button? I.e., strings built
> from 'concat' etc. (not string constants)? If so, I could change
> make-string-button to copy its string argument only if it's a constant, and 
> that
> should fix the compatibility issue without needing to make any changes
> to SLY.

No it doesn't, as someone else has already reported.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]