help-gnu-emacs
[Top][All Lists]
Advanced

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

Re: [Elisp][Question] How to modify a list by index while preserving val


From: Marcin Borkowski
Subject: Re: [Elisp][Question] How to modify a list by index while preserving value outside of scope?
Date: Sun, 20 Aug 2023 07:38:20 +0200
User-agent: mu4e 1.1.0; emacs 30.0.50

On 2023-08-20, at 05:46, Rodrigo Morales <moralesrodrigo1100@gmail.com> wrote:

> ----
> (defun my/f (foo bar)
>   (princ (format "(foo: %s) (bar: %s)\n" foo bar))
>   (cond
>    (foo (setf (nth 0 bar) "100"))
>    (t (my/f "apples" bar)
>       (my/f "bananas" bar))))
>
> (my/f nil (list 123))
> ----
>
> ---
> (foo: nil) (bar: (123))
> (foo: apples) (bar: (123))
> (foo: bananas) (bar: (100))
> ---
>
> I have some questions:
>
> + The second time my/f function is called (i.e. when "apples" is
>   passed), `bar' equals `123'. The third time `my/f' is called
>   (i.e. when "bananas" is passed), `bar' has a different value. We can
>   conclude that the modification to `bar' in the second call affected
>   the third call. How is this possible? `bar' is an argument of `my/f',
>   as far as I'm concerned, any modification to a variable that is a
>   function parameter only affects the scope of the function.
> + This is a minimal working example, in reality, the code I'm writing is
>   more complex. In the code that I'm writing, `bar' is a list and I want
>   to modify some of their elements by index. The only way I know is by
>   using `(setf (nth index my-list) new-value)'. However, using this
>   method seems to changes the value of the variable outside of the
>   function call. Are there any other ways to modify a list by index
>   without affecting its value outside of the function call?

Welcome to the rabbit hole of conses, lists etc.

In short: a "list" is in fact a "pointer", i.e., an "adress in memory"
where the first cons of that list lives.  (Read the chapter "How Lists
are Implemented" in the Elisp Intro for more info.)

If you want to work on a "local" version of a list, you can copy that
list yourself.  `append' is one way to do it; `cl-copy-list' is another.

Hth,

-- 
Marcin Borkowski
http://mbork.pl



reply via email to

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