GNU bug report logs - #40671
[DOC] modify literal objects

Previous Next

Package: emacs;

Reported by: Kevin Vigouroux <ke.vigouroux <at> laposte.net>

Date: Thu, 16 Apr 2020 20:40:02 UTC

Severity: normal

Tags: patch

Done: Paul Eggert <eggert <at> cs.ucla.edu>

Bug is archived. No further changes may be made.

Full log


Message #78 received at 40671 <at> debbugs.gnu.org (full text, mbox):

From: Michael Heerdegen <michael_heerdegen <at> web.de>
To: Paul Eggert <eggert <at> cs.ucla.edu>
Cc: Mattias EngdegÄrd <mattiase <at> acm.org>,
 40671 <at> debbugs.gnu.org, ke.vigouroux <at> laposte.net
Subject: Re: bug#40671: [DOC] modify literal objects
Date: Mon, 20 Apr 2020 02:53:35 +0200
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.




This bug report was last modified 5 years and 2 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.