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

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

Re: List not getting filled up


From: Yuri Khan
Subject: Re: List not getting filled up
Date: Mon, 31 Jul 2023 00:42:30 +0700

On Sun, 30 Jul 2023 at 22:11, uzibalqa <uzibalqa@proton.me> wrote:

> Use this as a test
>
> (setq collection '())
> (permute "abc" 0 3 collection)
> (message "%s" collection)
>
> I should get
>
> collection (abc acb bac bca cba cab)
>
> But I get
>
> Collection (abc abc abc abc abc abc)

You have a function that builds a list of strings.

Initially, you have an initial string value, "abc". Along the way, you
modify its contents, but ultimately there is only one string instance
in your program.

Each time you ‘push’ that string into your ‘result’ list, you are
storing one more reference to the same string object. In
box-and-pointer diagrams:

    ┌───┬───┐   ┌───┬───┐   ┌───┬───┐   ┌───┬───┐   ┌───┬───┐   ┌───┬───┐
    │ * │ *─┼──→│ * │ *─┼──→│ * │ *─┼──→│ * │ *─┼──→│ * │ *─┼──→│ * │nil│
    └─┼─┴───┘   └─┼─┴───┘   └─┼─┴───┘   └─┼─┴───┘   └─┼─┴───┘   └─┼─┴───┘
      │┌──────────┘           │           │           │           │
      ││┌─────────────────────┘           │           │           │
      │││┌────────────────────────────────┘           │           │
      ││││┌───────────────────────────────────────────┘           │
      │││││┌──────────────────────────────────────────────────────┘
      ↓↓↓↓↓↓
      ┌──────────────────┐
      │ (mutable string) │
      └──────────────────┘

This explains why you get a list that looks like it contains 6
identical strings — they are *the same* string.

Instead, you should be avoiding in-place string mutation and building
new string instances as you go, perhaps by redefining ‘swap-chars’ to
be non-destructive:

    (defun swap-chars (string p q)
      "Swap chars in STRING at positions P and Q."
      (cond
       ((= p q) string)
       ((> p q) (swap-chars string q p))
       (t (concat
           (substring string 0 p)
           (substring string q (1+ q))
           (substring string (1+ p) q)
           (substring string p (1+ p))
           (substring string (1+ q))))))

(This is likely not the fastest way to build a string with two
characters swapped. Do not let that distract you from the goal. Your
first goal is to get your program working correctly. When and if that
happens, and when and if your working solution is deemed too slow,
only then you start optimizing.)

(Adjusting the ‘permute’ function to non-destructive behavior of
‘swap-chars’ is left as an exercise. Hint 1: in your first
‘swap-chars’ call, you need to arrange for the return value to be
passed to the recursive invocation of ‘permute’. Hint 2: your second
‘swap-chars’ call is only there to undo the modification made by the
first call, so it could be avoided by introducing a local variable to
hold the result of the modification.)

reply via email to

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