emacs-devel
[Top][All Lists]
Advanced

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

Re: inverse of add-to-list: remove-from-list


From: Teemu Likonen
Subject: Re: inverse of add-to-list: remove-from-list
Date: Wed, 14 Oct 2020 08:28:15 +0300

* 2020-10-13 15:34:00-04, Boruch Baum wrote:

>      (let ((aa '(1 2 3 1 4 1 2)))
>        (delete 2 aa)
>        aa)

In Lisp world it is not recommended to use destructive operations like
DELETE for literal objects like list created with QUOTE operator '(1 2)
or a string created with quotation marks ("abc"). Compilers can create a
single object for all literally defined object. Emacs Lisp manual
"(elisp) Equality Predicates" says:

    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.

For example:

    (defvar foo '(1 2 3))

    (let ((bar '(1 2 3)))
      (eq foo bar)               ; This may return T.
      (setq bar (delete 3 bar))) ; This may also modify FOO.

So, using a destructive operation for a literal object may change it
everywhere. To create a modifiable objects we should use LIST,
MAKE-LIST, MAKE-STRING, COPY-SEQUENCE, CL-COPY-SEQ, for example.

>    And note that the fine distinction made in the docstring for the
>    `delete' function:
>
>      "If SEQ is not a list, deletion is never performed destructively;
>       instead this function creates and returns a new vector or string.
>
>       Write ‘(setq foo (delete element foo))’ to be sure of correctly
>       changing the value of a sequence ‘foo’.
>
>    So, in the case of SEQ being a list, there is no need to `setq foo'.

In Lisp manuals "destructive" means that the operation may modify the
original object given as an argument. It doesn't promise anything else.
Sometimes the original object is modified, sometimes it is not. Even if
the original object is modified it doesn't promise that it's the same as
the return value of a destructive function. The original object and the
return value can be partially the same: lists may share some cons cells.
We must always use the return value of a destructive function.

-- 
/// Teemu Likonen - .-.. https://www.iki.fi/tlikonen/
// OpenPGP: 4E1055DC84E9DFF613D78557719D69D324539450

Attachment: signature.asc
Description: PGP signature


reply via email to

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