changing argument variables
changing argument variables
if I have a function like....
(defun hello (x)
(setf x 6)
)
and then I ran...
(setf y 3)
(hello y)
How can I make it so that so that the value of y is changed to 6???
(defun hello (x)
(setf x 6)
)
and then I ran...
(setf y 3)
(hello y)
How can I make it so that so that the value of y is changed to 6???
Re: changing argument variables
Code: Select all
(defun new (&optional value)
(cons value nil))
(defun value-of (ptr)
(car ptr))
(defun (setf value-of) (new-value ptr)
(setf (car ptr) new-value))
;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;
(defun blah (x)
(setf (value-of x) 4321))
(defun test ()
(let ((my-ptr (new 1234)))
(blah my-ptr)
(value-of my-ptr)))
;; (test) => 4321
Re: changing argument variables
In Lisp, you can't pass the variable by reference, you can only pass the value (which might itself be a reference). You can wrap the variable in a structure or in a cons cell, or you can pass the setter function.LispProgrammer wrote:if I have a function like....
(defun hello (x)
(setf x 6)
)
and then I ran...
(setf y 3)
(hello y)
How can I make it so that so that the value of y is changed to 6???
Code: Select all
;; Implementation of reference-to-variable
(defmacro make-reference (x)
(let ((y (gensym)))
`(cons (lambda () ,x)
(lambda (,y) (setf ,x ,y)))))
(defun dereference (ref) (funcall (car ref)))
(defun (setf dereference) (value ref) (funcall (cdr ref) value))
(defun hello (x)
(setf (dereference x) 6))
(let ((y 3))
(hello (make-reference y))
(print y))
=> 6
-
- Posts: 148
- Joined: Wed Jul 30, 2008 11:26 pm
Re: changing argument variables
Why do you want to do this? How about:LispProgrammer wrote:if I have a function like....
(defun hello (x)
(setf x 6)
)
and then I ran...
(setf y 3)
(hello y)
How can I make it so that so that the value of y is changed to 6???
Code: Select all
(defun hello (x) (* x 6)) ; For example
(setf x (hello x))
Code: Select all
(hello (+ 1 2))
(hello 3)
(mapcar #'hello (list 1 2 3 4))
Re: changing argument variables
Dynamic variables would be one solution, should you really want to do this.
Code: Select all
(defun hello (name)
(set name 6))
=> HELLO
(defun test ()
(let ((*a* 4))
(declare (special *a*))
(hello '*a*)
*a*))
=> TEST
(test)
=> 6
Re: changing argument variables
The most intuitive thing to do is to treat the argument as the «place» (generalized reference, see http://www.lispworks.com/documentation/ ... /05_aa.htm). E.g., (hello (car x)) should change the car of x, (hello (slot-value some-object 'some-slot)) should change the slot of the object.Paul Donnelly wrote:And what if the argument you pass to HELLO isn't a variable?
But the same syntax is impossible to use (unless hello is a macro), so argument should be wrapped into some other form (that creates the reference).
-
- Posts: 148
- Joined: Wed Jul 30, 2008 11:26 pm
Re: changing argument variables
What when the argument is the result of a more complex computation, or is constant, or is supplied by a higher-order function rather than explicitly by the programmer? My point is that while OP might like modifying the argument, it's less generally useful than the way it is normally done. Of course if you do have a good reason, places are fine for their purpose.dmitry_vk wrote:The most intuitive thing to do is to treat the argument as the «place» (generalized reference, see http://www.lispworks.com/documentation/ ... /05_aa.htm). E.g., (hello (car x)) should change the car of x, (hello (slot-value some-object 'some-slot)) should change the slot of the object.Paul Donnelly wrote:And what if the argument you pass to HELLO isn't a variable?
But the same syntax is impossible to use (unless hello is a macro), so argument should be wrapped into some other form (that creates the reference).
Re: macros
This operates on a place, so it would be a macro:LispProgrammer wrote:How can I make it so that so that the value of y is changed to 6???Code: Select all
(defun hello (x) (setf x 6)) (setf y 3) (hello y)
Code: Select all
CL-USER> (defmacro setf-6 (place) `(setf ,place 6))
SETF-6
CL-USER> (let ((x 3))
(setf-6 x)
x)
6
--Dan B.
Re: changing argument variables
If you're doing this because you want to return multiple values (that being a common use case for pass-by-reference in C++), try (values) instead.LispProgrammer wrote:How can I make it so that so that the value of y is changed to 6???
Re: changing argument variables
Why not do this:
It looks like what your doing is describing an object that has three functions. A a reset, setter, and a getter.
Code: Select all
(let ((y 6))
(defun reset-y ()
(setf y 6))
(defun set-y (x)
(setf y x))
(defun get-y ()
y))