unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
* Is `eval' allowed to modify its argument?
@ 2020-11-12 21:06 Michael Heerdegen
  2020-11-12 21:18 ` Michael Heerdegen
  2020-11-12 22:13 ` Stefan Monnier
  0 siblings, 2 replies; 8+ messages in thread
From: Michael Heerdegen @ 2020-11-12 21:06 UTC (permalink / raw)
  To: Emacs mailing list

Hello,

is `eval' allowed to modify a list specified as FORM argument?  It seems
to happen to me in one case.

TIA,

Michael.



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Is `eval' allowed to modify its argument?
  2020-11-12 21:06 Is `eval' allowed to modify its argument? Michael Heerdegen
@ 2020-11-12 21:18 ` Michael Heerdegen
  2020-11-12 22:13 ` Stefan Monnier
  1 sibling, 0 replies; 8+ messages in thread
From: Michael Heerdegen @ 2020-11-12 21:18 UTC (permalink / raw)
  To: help-gnu-emacs

Michael Heerdegen <michael_heerdegen@web.de> writes:

> is `eval' allowed to modify a list specified as FORM argument?

Can it happen when FORM is macroexpanded and an expander destructively
modifies an input expression?

Michael.




^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Is `eval' allowed to modify its argument?
  2020-11-12 21:06 Is `eval' allowed to modify its argument? Michael Heerdegen
  2020-11-12 21:18 ` Michael Heerdegen
@ 2020-11-12 22:13 ` Stefan Monnier
  2020-11-13 11:29   ` Michael Heerdegen
  1 sibling, 1 reply; 8+ messages in thread
From: Stefan Monnier @ 2020-11-12 22:13 UTC (permalink / raw)
  To: help-gnu-emacs

> is `eval' allowed to modify a list specified as FORM argument?

There's nothing that says it's no allowed, I think.  It's probably not
very desirable in general, tho I would expect some macros to do it
(e.g. in a previous life I played with a version of `macroexpand` which
modified its argument in place to replace the original code with its
macro-expanded form: I was considering it as an optimization to speed up
execution of non-byte-compiled loops by avoiding the re-expansion of
macro invocations in the body).

> It seems to happen to me in one case.

I can imagine cases where one might think it's a good idea to do so, but
I suspect that in practice it probably always ends up being a bad idea,
so you might like to report it as a ... let's not call it a bug but
a "sign that something's fishy"?


        Stefan




^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Is `eval' allowed to modify its argument?
  2020-11-12 22:13 ` Stefan Monnier
@ 2020-11-13 11:29   ` Michael Heerdegen
  2020-11-13 14:12     ` Stefan Monnier
  0 siblings, 1 reply; 8+ messages in thread
From: Michael Heerdegen @ 2020-11-13 11:29 UTC (permalink / raw)
  To: help-gnu-emacs

Stefan Monnier <monnier@iro.umontreal.ca> writes:

> I can imagine cases where one might think it's a good idea to do so,

I suspect in most cases it happens by accident.  My case is thunk-let*
(AFAIR I was related in implementing it...):

(let ((form '(thunk-let* ((x (+ 1 2))
                          (y (+ x 3)))
               (* x y))))
  (ignore (macroexpand form))
  form)

==>

 (thunk-let*
    ((x
      (+ 1 2))) ;; second binding of FORM is gone!
  (* x y))

So do we consider that a bug in `thunk-let*'?  How much similar cases do
you think can we expect?


Thanks,

Michael.





^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Is `eval' allowed to modify its argument?
  2020-11-13 11:29   ` Michael Heerdegen
@ 2020-11-13 14:12     ` Stefan Monnier
  2020-11-13 18:56       ` Michael Heerdegen
  0 siblings, 1 reply; 8+ messages in thread
From: Stefan Monnier @ 2020-11-13 14:12 UTC (permalink / raw)
  To: help-gnu-emacs

> So do we consider that a bug in `thunk-let*'?

Yes.  Most likely a misuse of `nreverse` or something like that.


        Stefan




^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Is `eval' allowed to modify its argument?
  2020-11-13 14:12     ` Stefan Monnier
@ 2020-11-13 18:56       ` Michael Heerdegen
  2020-11-13 23:01         ` Stefan Monnier
  0 siblings, 1 reply; 8+ messages in thread
From: Michael Heerdegen @ 2020-11-13 18:56 UTC (permalink / raw)
  To: help-gnu-emacs

Stefan Monnier <monnier@iro.umontreal.ca> writes:

> > So do we consider that a bug in `thunk-let*'?
>
> Yes.  Most likely a misuse of `nreverse` or something like that.

Exactly that, yes.  AFAIR I used `nreverse' on purpose: back then I had
thought it would not matter.  Will commit a fix.

Thanks,

Michael.




^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Is `eval' allowed to modify its argument?
  2020-11-13 18:56       ` Michael Heerdegen
@ 2020-11-13 23:01         ` Stefan Monnier
  2020-11-13 23:14           ` Drew Adams
  0 siblings, 1 reply; 8+ messages in thread
From: Stefan Monnier @ 2020-11-13 23:01 UTC (permalink / raw)
  To: help-gnu-emacs

>> > So do we consider that a bug in `thunk-let*'?
>> Yes.  Most likely a misuse of `nreverse` or something like that.
> Exactly that, yes.  AFAIR I used `nreverse' on purpose: back then I had
> thought it would not matter.

Destructive operations on lists, like `nreverse` or `sort` should (as
a general rule) only ever be used on lists you yourself just constructed
(so you can be (almost) 100% sure you hold the one and only reference to the list
and nobody else will be able to witness the destructiveness).

Using it on something you received as an argument is basically always
a bug, unless it's clearly documented (as is done, for example, in the
doc of `nreverse`).


        Stefan


PS: The "almost" above is because in Elisp you can't really be sure of
    anything, thanks to things like advice.  That's why users of advice
    are warned that it's up to them to deal with any problem that may
    result of poor interaction between their code and the rest.




^ permalink raw reply	[flat|nested] 8+ messages in thread

* RE: Is `eval' allowed to modify its argument?
  2020-11-13 23:01         ` Stefan Monnier
@ 2020-11-13 23:14           ` Drew Adams
  0 siblings, 0 replies; 8+ messages in thread
From: Drew Adams @ 2020-11-13 23:14 UTC (permalink / raw)
  To: Stefan Monnier, help-gnu-emacs

> Destructive operations on lists, like `nreverse` or `sort` should (as
> a general rule) only ever be used on lists you yourself just
> constructed (so you can be (almost) 100% sure you hold the one
> and only reference to the list and nobody else will be able to
> witness the destructiveness).
> 
> Using it on something you received as an argument is basically always
> a bug, unless it's clearly documented (as is done, for example, in the
> doc of `nreverse`).
> 
> PS: The "almost" above is because in Elisp you can't really be sure of
>     anything, thanks to things like advice.  That's why users of advice
>     are warned that it's up to them to deal with any problem that may
>     result of poor interaction between their code and the rest.

+1.  I was going to say about the same thing.

Safest is local to a function or other context
(e.g. `let' lexical binding).

But there are use cases for modifying a part
of a global structure.

In that case, as in all cases, it's generally
more likely that you'll step on your own toes
than that someone else will step on them.  One
part of you or your code will forget or not
realize that something you use is susceptible
to your code modifying it ... gotcha!

IOW, modifying only stuff that _you_ create
doesn't guard against your own worst enemy -
yourself at another time or in a different
context.

And the effect isn't always easy to detect
immediately or the cause easy to localize.
Really modifying data (i.e., "destructively")
is a different world - not for the faint of
heart. ;-)



^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2020-11-13 23:14 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-11-12 21:06 Is `eval' allowed to modify its argument? Michael Heerdegen
2020-11-12 21:18 ` Michael Heerdegen
2020-11-12 22:13 ` Stefan Monnier
2020-11-13 11:29   ` Michael Heerdegen
2020-11-13 14:12     ` Stefan Monnier
2020-11-13 18:56       ` Michael Heerdegen
2020-11-13 23:01         ` Stefan Monnier
2020-11-13 23:14           ` Drew Adams

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).