Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to achieve side effect in functions

2 views
Skip to first unread message

Eqbal Z

unread,
Dec 15, 2002, 7:08:22 PM12/15/02
to
Hi,

I need to write a lisp function rev(lst revlist) which reverses the
list lst and stores it in revlist.
I am able to write the rev(lst) function but how do I write the
function so the result is stored in one of its arguments?

Thanks

Jochen Schmidt

unread,
Dec 15, 2002, 7:19:00 PM12/15/02
to
Eqbal Z wrote:

Lisp has call-by-value. You can simulate what you want by making "rev"
a macro.

Having said that you should definitely look up some information about
returning multiple values in Common Lisp.

ciao,
Jochen

--
http://www.dataheaven.de

Simon András

unread,
Dec 16, 2002, 7:59:03 AM12/16/02
to
eza...@pioneer-usa.com (Eqbal Z) writes:

If you're willing to pass a cons as the second argument, then you can
(but shouldn't) do this by setf-ing its car and cdr to that of the
reversed list. But note that CL is not C, so only do this if it's a
homework assignment and you're desperate.

Andras

Erik Naggum

unread,
Dec 16, 2002, 9:46:27 AM12/16/02
to
* eza...@pioneer-usa.com (Eqbal Z)

| I need to write a lisp function rev(lst revlist) which reverses the
| list lst and stores it in revlist.

Why do you think you need this?

--
Erik Naggum, Oslo, Norway

Act from reason, and failure makes you rethink and study harder.
Act from faith, and failure makes you blame someone and push harder.

Kaz Kylheku

unread,
Dec 16, 2002, 2:41:41 PM12/16/02
to
eza...@pioneer-usa.com (Eqbal Z) wrote in message news:<3b440a00.02121...@posting.google.com>...

> Hi,
>
> I need to write a lisp function rev(lst revlist) which reverses the

You don't have to call list variables LST in Lisp. Even though there
is a function named LIST, you can still use it as a variable name.

> list lst and stores it in revlist.
> I am able to write the rev(lst) function but how do I write the

Lisp already has a REVERSE function, so you wasted your time.

> function so the result is stored in one of its arguments?

Try writing:

(setf revlist (reverse list))

If you want a special notation for this, write a macro which
translates that notation into the above, e.g.

(defmacro reverse-into (source-list target-place)
`(setf ,target-place (reverse ,source-list)))

I can't think of any good reason for wanting this, but there you have
it.

Eqbal Z

unread,
Dec 16, 2002, 3:20:50 PM12/16/02
to
asi...@math.bme.hu (Simon Andr s) wrote in message news:<vcdbs3m...@tarski.math.bme.hu>...


Yes this is a homework assignment. How do you pass cons as an argument?

Simon András

unread,
Dec 16, 2002, 8:46:28 PM12/16/02
to
eza...@pioneer-usa.com (Eqbal Z) writes:

(rev this-is-your-list (list nil))

(list nil) is a cons. But any cons, that is, anything (call it x) for
which (typep x 'cons) returns T would do.

But see the other replies. Mine was just an attempt to show that you
can do what you want to with a function, depending on how you're going
to use it.

Andras

Simon András

unread,
Dec 17, 2002, 1:26:01 AM12/17/02
to
asi...@math.bme.hu (Simon András) writes:

> > Yes this is a homework assignment. How do you pass cons as an argument?
>
> (rev this-is-your-list (list nil))

Perhaps I should add that although this answers your quoted question,
considering the wider context, I should've written

(let ((this-will-be-the-reversed-list (list nil)))
(rev this-is-your-list this-will-be-the-reversed-list)
;; here this-will-be-the-reversed-list is already the reversed list
;; you do whatever you want with it
)

Andras

Pascal Bourguignon

unread,
Dec 19, 2002, 7:19:48 PM12/19/02
to
eza...@pioneer-usa.com (Eqbal Z) writes:


Since you want probably recover the modified value after the call, you
need to keep a reference to the cons. So first, you assign it to a
variable (theta in my case) then you call the function passing that
variable 'by value'. Just that a cons contains two pointers, so you
effectively passed a reference to the function. Note that in my case I
only modify the cdr of the cons but both the car and the cdr can be
used.


(defun fun (n output)
(do ((i 0 (1+ i)))
((> i n))
(push i (cdr output))))

(show
(let ((theta (cons nil nil)))
(fun 3 theta)
(cdr theta))
)

==> (3 2 1 0)

Of course, instead of having an 'output' or 'inout' parameter that
needs such a special initialization before calling, you may want to
have a input parameter and recover an output as result, maybe a
multiple result if the function must return other values too.

So, instead of writting:
(setq inout (cons nil variable))
(setq result (fun n inout))
(setq variable (cdr inout))

and using (setf (cdr inout) ...) and (cdr inout) in the function fun,

(defun fun (n inout)
;; ...
(setf (cdr inout) (f (cdr inout)))
;; ...
result)

[ note the equivalence with C:

result=fun(n,&variable);

result_t fun(int n,variable_t* inout)
{
/* ... */
(*inout)=f(*inout);
/* ... */
return(result);
}

]

you may also write:

(multiple-value-bind (res out) (fun n variable)
(setq result res)
(setq variable out))

and use (setq inout) and inout in the function fun and (values result
inout) at the end:

(defun fun (n inout)
;; ...
(setq inout (f inout))
;; ...
(values result inout))


[ note the equivalence with C: oops, you can only return one result here...

variable=fun(n,variable);

variable_t fun(int n,variable_t inout)
{
/* ... */
inout=f(inout);
/* ... */
return(inout);
}

]


--
__Pascal_Bourguignon__ http://www.informatimago.com/
----------------------------------------------------------------------
There is a fault in reality. do not adjust your minds. -- Salman Rushdie

0 new messages