[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#40692: 28.0.50; Constant list modified inside function
From: |
Štěpán Němec |
Subject: |
bug#40692: 28.0.50; Constant list modified inside function |
Date: |
Sat, 18 Apr 2020 11:18:46 +0200 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) |
On Fri, 17 Apr 2020 17:45:12 -0600
Ivan Andrus wrote:
> Starting from Emacs -Q (I am building off of trunk, but my brother verified
> the same behavior in 26.3), if I evaluate the following code I get an error
> the second time I call withdraw.
>
> (defmacro show (var)
> `(message ,(format "%S %%S" var) ,var))
>
> (defun my-test-fun (amount params)
> (when (memq 'tricked-ya params)
> (error "What happened here?"))
> (show amount)
> (show params)
> (setcdr (cdr params) (list 'tricked-ya))
> (show params))
>
> (defun fun-withdraw (amount)
> (my-test-fun amount
> `((amount . , amount)
> (const . some-constant))))
>
> (fun-withdraw 12)
>
> (fun-withdraw 12) ;; The second time it's called it will error because the
> "constant" list was modified.
>
>
> I believe this is the root cause of a bug in magit/forge
> https://github.com/magit/forge/issues/267 in which all subsequent pull
> requests created have the same name. The maintainer of magit/forge (tarsius)
> was unable to reproduce that bug, so I tried my hand at creating a minimal
> test case, and I was able to get it down to this.
>
> Now, I understand reference semantics of lists in general, but it
> seems like this should be different. If this behavior is intentional,
I think it is, although I admit I was confused by it, too, as I've
somehow come to believe that e.g. `(list) macroexpands to (list 'list),
but that's not the case: it expands to '(list).
> what's the best way to for creation of a new list every time so that
> functions using the alist don't have to worry about not changing the
> list?
If you change the backquoted form in `fun-withdraw' to
(list `(amount . ,amount)
'(const . some-constant))
it works as desired.