I have a few questions about destructive functions. Can anybody explain why setf doesn't work with passed values ? It may return correct value, but it doesn't change the variable itself.
PS maybe it would be better if I describe full problem:
I need to edit branches or / and leafs inside a tree. I wanted to pas the branch as a parameter to my changing function, and process it with destructive pop and push functions, but it doesn't work. Is there a right way to do this?
destructive functions & trees
destructive functions & trees
Last edited by incogn1to on Sun May 01, 2011 5:13 am, edited 2 times in total.
Sibi imperare maximum imperum est
-
- Posts: 388
- Joined: Thu May 08, 2008 1:24 am
- Location: Croatia
- Contact:
Re: destructive functions
It works for local variables
> (let((x 1))(setf x 7)(* 2 x))
14
> (local(x)(setf x 8)(+ x 1))
9
What exactly do you dislike?
> (let((x 1))(setf x 7)(* 2 x))
14
> (local(x)(setf x 8)(+ x 1))
9
What exactly do you dislike?
Re: destructive functions
It doesn't work with passed values.
This won't change the variable.
Code: Select all
(set 'x '(0 1 2 '(3 4)))
(define (destruct lst) (setf (lst 3 0) 1))
(destruct x)
-> 1
This won't change the variable.
Sibi imperare maximum imperum est
Re: destructive functions & trees
According to the manual,
http://www.newlisp.org/downloads/newlis ... l#pass_big
Then x is not changed.
And according to the same chapter in manual.
http://www.newlisp.org/downloads/newlis ... l#pass_big
Note that there is no quote before (3 4).
http://www.newlisp.org/downloads/newlis ... l#pass_big
Variable's lst in function destruct is not x, but the copy of x.newLISP passes parameters by value copy.
Then x is not changed.
And according to the same chapter in manual.
http://www.newlisp.org/downloads/newlis ... l#pass_big
For example:Strings and lists, which are packed in a namespace using default functors, are passed automatically by reference:
Code: Select all
> (set 'y:y '(0 1 2 (3 4)))
(0 1 2 (3 4))
> (define (destruct lst) (setf (lst 3 0) 1))
(lambda (lst) (setf (lst 3 0) 1))
> y:y
(0 1 2 (3 4))
> (destruct y)
1
> y:y
(0 1 2 (1 4))
>
-
- Posts: 388
- Joined: Thu May 08, 2008 1:24 am
- Location: Croatia
- Contact:
Re: destructive functions & trees
Without using contexts, demonstrated by johu, if you want pass by reference, you should really pass the reference of the structure (not the structure itself), and make your function dereference it:
(set 'x '(0 1 2 (3 4)))
(define (destruct lst) (setf ((eval lst) 3 0 0) 1)) ; eval is dereference
(println x) ; =>(0 1 2 (3 4))
(setf (x 3 0) 4)
(println x) ; =>(0 1 2 (4 4))
(destruct 'x) ; passes symbol x, which is reference of the list stored as value of x
(println x) ; =>(0 1 2 (1 4))
Another way for dereference (if you want to do it once in larger blocks) is
(set 'x '(0 1 2 (3 4)))
(define (destruct lst) (setf ((eval lst) 3 0 0) 1)) ; eval is dereference
(println x) ; =>(0 1 2 (3 4))
(setf (x 3 0) 4)
(println x) ; =>(0 1 2 (4 4))
(destruct 'x) ; passes symbol x, which is reference of the list stored as value of x
(println x) ; =>(0 1 2 (1 4))
Another way for dereference (if you want to do it once in larger blocks) is
Code: Select all
(define (destruct lst)
(letex((lst lst))
(setf (lst 3 0 0) 1)
(setf (lst 3 0 1) 2)))
Re: destructive functions & trees
Thank you fro the answers, that solved the problem.
Sibi imperare maximum imperum est