• Can someone explain to me how can I destructively modify subtrees?

    From Bigos@21:1/5 to All on Wed Mar 16 03:06:01 2022
    I am trying to modify a tree made of cons cells. Recursively I descend to the cons where I want to append a subtree like (cons 'header (cons 'name nil)).

    How do I do it so that the addition is seen when I later check the cons cell that is at the root of the tree?

    I do not want to change every tree element that matches certain criteria. I want to descent to the point where I append my subtree following a path similar to descending down the file system tree.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Spiros Bousbouras@21:1/5 to Bigos on Wed Mar 16 12:58:44 2022
    On Wed, 16 Mar 2022 03:06:01 -0700 (PDT)
    Bigos <ruby.object@googlemail.com> wrote:
    I am trying to modify a tree made of cons cells. Recursively I descend to
    the cons where I want to append a subtree like (cons 'header (cons 'name nil)).

    How do I do it so that the addition is seen when I later check the cons
    cell that is at the root of the tree?

    I do not want to change every tree element that matches certain criteria. I want to descent to the point where I append my subtree following a path similar to descending down the file system tree.

    It's not clear what your precise requirements are so I will give you some examples :

    (defvar tree1)
    TREE1
    (setq tree1 (list 1 (list 2 3 (list 4 5))))
    (1 (2 3 (4 5)))
    tree1
    (1 (2 3 (4 5)))
    (defvar tree2 (list 'a (list 'b 'c)))
    TREE2

    "Deep" in tree1 we have the subtree (4 5) so I will show examples where
    you can replace 4 or 5 or append to (4 5) the tree tree2 .There are various ways to descend to the right spot in tree1 , the following present just one way.

    (setf (first (caddr (car (cdr tree1)))) tree2)
    (A (B C))
    tree1
    (1 (2 3 ((A (B C)) 5)))
    (setq tree1 (list 1 (list 2 3 (list 4 5))))
    (1 (2 3 (4 5)))
    ; We return tree1 to its initial value.

    (setf (second (caddr (car (cdr tree1)))) tree2)
    (A (B C))
    tree1
    (1 (2 3 (4 (A (B C)))))
    [10]> (setq tree1 (list 1 (list 2 3 (list 4 5))))
    (1 (2 3 (4 5)))
    ; We return tree1 to its initial value.

    [11]> (setf (cdaddr (car (cdr tree1))) tree2)
    (A (B C))
    [12]> tree1
    (1 (2 3 (4 A (B C))))
    [13]> (setq tree1 (list 1 (list 2 3 (list 4 5))))
    (1 (2 3 (4 5)))
    ; We return tree1 to its initial value.

    [14]> (rplacd (cdaddr (car (cdr tree1))) tree2)
    (5 A (B C))
    [15]> tree1
    (1 (2 3 (4 5 A (B C))))

    --
    How do you know that a webpage belongs to a postmodernist philosopher ?
    It is constantly under deconstruction.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Bigos@21:1/5 to All on Wed Mar 16 07:47:18 2022
    This is my lame attempt. Only if I knew how to replace your cars and cdrs following the setf I would have my solution.


    (defparameter *bintree* '(((1) . (2)) (3 . 4)))

    (defun bintrav (tr)
    (format t "trying ~S~%" tr)
    (when (equal tr '(2))
    (progn
    (setf tr (cons 2222 nil))
    (format t "trying changed ~S~%" tr)))

    (if (atom tr)
    nil
    (progn
    (format t "trying with ~S~%" tr)
    (bintrav (car tr))
    (bintrav (cdr tr)))))

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Bigos@21:1/5 to All on Wed Mar 16 08:36:45 2022
    finally this one works.

    thank you very much for giving me the idea, but this still does feel hacky. Is there a better way to do it?

    (defun bintrav (tr &optional (p '*bintree*))
    (format t "trying ~S ~S~%" tr p)
    (when (equal tr '(2))
    (progn
    (eval (list 'setf p 2222))
    (format t "trying changed ~S >>> ~S~%" *bintree* p)))

    (if (atom tr)
    nil
    (progn
    (format t "trying with ~S~%" tr)
    (bintrav (car tr) (list 'car p))
    (bintrav (cdr tr) (list 'cdr p)))))

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Bigos@21:1/5 to All on Wed Mar 16 08:24:17 2022
    Trying to accumulate the car cdr path does not work
    (defparameter *bintree* '(((1) . (2)) (3 . 4)))

    (defun bintrav (tr &optional (p '*bintree*))
    (format t "trying ~S ~S~%" tr p)
    (when (equal tr '(2))
    (progn
    (eval (setf p 2222))
    (format t "trying changed ~S~%" *bintree*)))

    (if (atom tr)
    nil
    (progn
    (format t "trying with ~S~%" tr)
    (bintrav (car tr) (list 'car p))
    (bintrav (cdr tr) (list 'cdr p)))))

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Spiros Bousbouras@21:1/5 to Spiros Bousbouras on Wed Mar 16 16:48:56 2022
    On Wed, 16 Mar 2022 16:41:25 -0000 (UTC)
    Spiros Bousbouras <spibou@gmail.com> wrote:
    Instead I think you want
    something like

    (defun bintrav2 (arg &aux (tr arg))

    Make that
    (defun bintrav2 (tr)

    What I posted originally was part of an unsuccessful experiment.

    (format t "trying ~S~%" tr)
    (when (equalp tr '(2))
    (setf (car tr) (cons 2222 nil))
    (format t "trying changed ~S~%" tr))

    (if (atom tr)
    nil
    (progn
    (format t "trying with ~S~%" tr)
    (bintrav2 (car tr))
    (bintrav2 (cdr tr)))))


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Spiros Bousbouras@21:1/5 to Bigos on Wed Mar 16 16:41:25 2022
    On Wed, 16 Mar 2022 07:47:18 -0700 (PDT)
    Bigos <ruby.object@googlemail.com> wrote:
    This is my lame attempt. Only if I knew how to replace your cars and
    cdrs following the setf I would have my solution.


    (defparameter *bintree* '(((1) . (2)) (3 . 4)))

    (defun bintrav (tr)
    (format t "trying ~S~%" tr)
    (when (equal tr '(2))
    (progn
    (setf tr (cons 2222 nil))
    (format t "trying changed ~S~%" tr)))

    (if (atom tr)
    nil
    (progn
    (format t "trying with ~S~%" tr)
    (bintrav (car tr))
    (bintrav (cdr tr)))))

    A few general remarks first :

    1. It is much more useful if you specify what is the initial and final tree
    you want. Instead you are leaving us to guess that the initial tree is the value of *bintree* and for the final tree we must guess based on the code
    for bintrav which does not actually achieve what you want !

    2. If you are doing (bintrav *bintree*) then it's undefined behaviour
    because *bintree* is a quoted object and you are not supposed to modify those. So what you really want is

    (defparameter *bintree* (list (cons (list 1) (list 2)) (cons 3 4))))

    3. Note that
    (equalp '(((1) . (2)) (3 . 4)) '(((1) 2) (3 . 4)))

    returns T so your quoted object is more complicated than it needs to be.

    4. WHEN is an implicit PROGN so instead of

    (when (equal tr '(2))
    (progn
    (setf tr (cons 2222 nil))
    (format t "trying changed ~S~%" tr)))

    you can simply do

    (when (equal tr '(2))
    (setf tr (cons 2222 nil))
    (format t "trying changed ~S~%" tr))

    I didn't examine carefully your subsequent posts using EVAL because it is almost certain that you don't want EVAL for this. Instead I think you want something like

    (defun bintrav2 (arg &aux (tr arg))
    (format t "trying ~S~%" tr)
    (when (equalp tr '(2))
    (setf (car tr) (cons 2222 nil))
    (format t "trying changed ~S~%" tr))

    (if (atom tr)
    nil
    (progn
    (format t "trying with ~S~%" tr)
    (bintrav2 (car tr))
    (bintrav2 (cdr tr)))))

    --
    There are so many people coming out that they're not even gay , they're trendsexual.
    John Waters

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Bigos@21:1/5 to All on Wed Mar 16 09:52:11 2022
    It appears that (setf (car tr) 'whatever) was the answer I was looking for. I could not figure out why (setf tr 'whatever) was the wrong approach.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Madhu@21:1/5 to All on Thu Mar 17 17:45:09 2022
    * Bigos <72f9aea8-0c8a-45ad-8450-dfacc51c845cn @googlegroups.com> :
    Wrote on Wed, 16 Mar 2022 09:52:11 -0700 (PDT):

    It appears that (setf (car tr) 'whatever) was the answer I was looking
    for. I could not figure out why (setf tr 'whatever) was the wrong
    approach.

    is it still a problem? For SETF to mutate its first argument the first
    argument of SETF has to be a SETF'able "place". If it is not a place but
    a variable will merely modify the binding of the variable
    like (setq var val)

    [coming in late, havent caught up]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Bigos@21:1/5 to Madhu on Fri Mar 18 02:28:01 2022
    On Thursday, 17 March 2022 at 12:15:17 UTC, Madhu wrote:

    is it still a problem? For SETF to mutate its first argument the first argument of SETF has to be a SETF'able "place". If it is not a place but
    a variable will merely modify the binding of the variable
    like (setq var val)

    It is not a problem. But I must admit I did not understand the distinction. I thought the binding of the variable was a SETF'able place.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ben Bacarisse@21:1/5 to Bigos on Fri Mar 18 16:17:02 2022
    Bigos <ruby.object@googlemail.com> writes:

    On Thursday, 17 March 2022 at 12:15:17 UTC, Madhu wrote:

    is it still a problem? For SETF to mutate its first argument the first
    argument of SETF has to be a SETF'able "place". If it is not a place but
    a variable will merely modify the binding of the variable
    like (setq var val)

    It is not a problem. But I must admit I did not understand the
    distinction. I thought the binding of the variable was a SETF'able
    place.

    The variable is setfable, but what the variable is bound to is not (at
    least not directly). However if a variable, x, is bound to (i.e.
    "refers" to) a cons cell, then both (car x) and (cdr x) are setfable
    places.

    This is why you have to stop "one level up" from where you want to
    modify a tree (if you are doing it this way) and why you can't modify an
    empty tree this way (there is no one-level up!).

    --
    Ben.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Bigos@21:1/5 to Ben Bacarisse on Fri Mar 18 10:04:51 2022
    On Friday, 18 March 2022 at 16:17:07 UTC, Ben Bacarisse wrote:


    This is why you have to stop "one level up" from where you want to
    modify a tree (if you are doing it this way) and why you can't modify an empty tree this way (there is no one-level up!).


    Aha!

    That explains why I have cddr in accessing children and cdr in SETFing the tree.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Bigos@21:1/5 to Bigos on Fri Mar 18 10:10:13 2022
    On Friday, 18 March 2022 at 17:04:56 UTC, Bigos wrote:

    That explains why I have cddr in accessing children and cdr in SETFing the tree.

    https://pastebin.com/b0e6QJXk

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)