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

Key arguments and DEFCLASS

2 views
Skip to first unread message

Vladimir Zolotykh

unread,
Mar 3, 2002, 6:18:35 AM3/3/02
to
Is it safe to write FOO in the following way

(defun foo (&key a b c)
(multiple-value-setq (a b c) (bar))
(list a b c))

?

Or maybe more safer would be

(defun foo (&key a b c)
(let ((a a) (b b) (c c))
(multiple-value-setq (a b c) (bar))
(list a b c)))

Semantically, I want latter, e.g. pure local variables within FOO.

Also I have question some aside. Is possible to eliminate consequences
of DEFCLASS (in the way makunbound, fmakunbound do for vars,
functions, macros, GF).


--
Vladimir Zolotykh

Kent M Pitman

unread,
Mar 3, 2002, 7:01:49 AM3/3/02
to
Vladimir Zolotykh <gsm...@eurocom.od.ua> writes:

> Is it safe to write FOO in the following way
>
> (defun foo (&key a b c)
> (multiple-value-setq (a b c) (bar))
> (list a b c))
>
> ?

Yes. (It's kind of a bizarre thing to take arguments and then discard
them without using it. Especially keyword arguments, which are a pain
[read: "computationally more expensive"] to extract. But it's certainly
quite valid.)

> Or maybe more safer would be
>
> (defun foo (&key a b c)
> (let ((a a) (b b) (c c))
> (multiple-value-setq (a b c) (bar))
> (list a b c)))

This reduces the stress on the compiler to do correct lifetime analysis
of variables, but most compilers are going to reach the same conclusion
regardless of which way you write it.

> Semantically, I want latter, e.g. pure local variables within FOO.

They are local in either case. Are you worried that arguments might be
call-by-reference and that the caller might be affected?? That definitely
can't happen.



> Also I have question some aside. Is possible to eliminate consequences
> of DEFCLASS (in the way makunbound, fmakunbound do for vars,
> functions, macros, GF).

I can't understand this sentence well enough to answer it. Can you
elaborate or even just restate your question in different words? Thanks.

Vladimir Zolotykh

unread,
Mar 3, 2002, 7:51:48 AM3/3/02
to
Kent M Pitman wrote:
>
> ........... Are you worried that arguments might be

> call-by-reference and that the caller might be affected?? That definitely
> can't happen.

Exactly that, and my example was rather incomplete. Of course at first the
args were used and only then altered.

> I can't understand this sentence well enough to answer it. Can you
> elaborate or even just restate your question in different words? Thanks.

Probably my poor knowledge of English is the cause. I meant the following.
When I made a function say FOO and some time after decided it isn't needed any
more I can do (fmakunbound 'foo). But I don't know is something could be done
if I don't want class for example BAR any more (which was introduced by myself some
earlier). Symbols can be uninterned, GFs - fmakunbounded, methods on GF - removed
and so on. Does something similar exist for DEFCLASS ?

--
Vladimir Zolotykh

Kent M Pitman

unread,
Mar 3, 2002, 8:19:44 AM3/3/02
to
Vladimir Zolotykh <gsm...@eurocom.od.ua> writes:

> Kent M Pitman wrote:
> >
> > ........... Are you worried that arguments might be
> > call-by-reference and that the caller might be affected?? That definitely
> > can't happen.
>
> Exactly that, and my example was rather incomplete. Of course at first the
> args were used and only then altered.

Arguments are passed by pointer, but the pointer is to the object, not
to the variable.

You can modify the structure of an argument within a function call,
but making a variable binding won't protect you from that. You cannot
modify the location from which an object that is an argument came.

> > I can't understand this sentence well enough to answer it. Can you
> > elaborate or even just restate your question in different words? Thanks.
>
> Probably my poor knowledge of English is the cause. I meant the
> following. When I made a function say FOO and some time after
> decided it isn't needed any more I can do (fmakunbound 'foo). But I
> don't know is something could be done if I don't want class for
> example BAR any more (which was introduced by myself some
> earlier). Symbols can be uninterned, GFs - fmakunbounded, methods on
> GF - removed and so on. Does something similar exist for DEFCLASS ?

Is this for interactive debugging or for programmatic use?

You can use SETF of FIND-CLASS to set the name-to-class mapping to
NIL, but I don't know if this means the class will be GC'd because
it's probably still linked into the class hierarchy and may still have
instances that are pointed to.

I'm not sure offhand if there is a MOP way to disconnect the class; there
isn't a way in ANSI CL proper.

Erik Naggum

unread,
Mar 3, 2002, 8:23:00 AM3/3/02
to
* Vladimir Zolotykh <gsm...@eurocom.od.ua>

| Semantically, I want latter, e.g. pure local variables within FOO.

May I suggest multiple-value-bind instead of multiple-value-setq?
Memory is not so scarce that you need to re-use variables or arguments.

/
--
In a fight against something, the fight has value, victory has none.
In a fight for something, the fight is a loss, victory merely relief.

Ralf Kleberhoff

unread,
Mar 3, 2002, 8:46:31 AM3/3/02
to
Hi!

Vladimir Zolotykh schrieb:
> ...


> (defun foo (&key a b c)
> (multiple-value-setq (a b c) (bar))
> (list a b c))

> ...
> --
> Vladimir Zolotykh

Besides all the in-depth discussion of assignment to parameters,
may I simply suggest using multiple-value-list instead?

(defun foo (&key a b c)

(multiple-value-list (bar))

Then there's no need to modify any variable.

Regards,
--- Ralf

Vladimir Zolotykh

unread,
Mar 3, 2002, 9:09:06 AM3/3/02
to
Kent M Pitman wrote:
>
> Is this for interactive debugging or for programmatic use?
For interactive debugging only.

BTW now I know the correct form for my question: 'How to make class GC'd ?'.
--
Vladimir Zolotykh

Kent M Pitman

unread,
Mar 3, 2002, 9:14:58 AM3/3/02
to
Erik Naggum <er...@naggum.net> writes:

> * Vladimir Zolotykh <gsm...@eurocom.od.ua>
> | Semantically, I want latter, e.g. pure local variables within FOO.
>
> May I suggest multiple-value-bind instead of multiple-value-setq?
> Memory is not so scarce that you need to re-use variables or arguments.

Moreover, in most compilers,

(let ((x 1) (y 2))
... use x, y... ; code block A
(let ((x 3) (y 4))
... use x, y...)) ; code block B

will be compiled the same as

(let ((x 1) (y 2))
... use x, y... ; code block A
(setq x 3 y 4)
... use x, y...) ; code block B

because the compiler will do lifetime analysis in the former and will see
that the lifetime of variables x0, y0 is done as code block A ends, and so
will recycle that register or stack location for use by x1, y1 in a manner
that is computationally the same as if a setq had occurred. (It would also
do this if you had used different inner variable names, of course.)

So the real purpose of nesting the LETs is just to cue human readers (who
are not doing exhaustive analysis with their respective eyes as they scan)
that they can let go of the "baggage" of worrying about the outer x and y
while doing the inner one; further, the indentation will tell people visually
that it's a "tail call" into the inner binding and so the baggage will not
be grabbed later. This is one reason I prefer to do:

(let ((result blah))
...
(let ((foo (foo)) (bar (bar)))
... accumulate result ...
result))

rather than

(let ((result blah))
...
(let ((foo (foo)) (bar (bar)))
... accumulate result ...)
result)

The compiler is likely to compile both of these the same, but the former makes
it visually easier to see that the inner LET can discard any outer FOO and BAR
(not that there is any in this case, because subsequent lines do not "back up"
indentationally. Consider that

(let ((foo 'foo) (bar 'bar))
(let ((result blah))
...
(let ((foo (foo)) (bar (bar)))
... accumulate result ...)
result))

loses that rightward flow visually, making you fight more visually when you
see the second foo and bar to assure yourself that the outer ones no longer
matter than would happen if you do

(let ((foo 'foo) (bar 'bar))
(let ((result blah))
...
(let ((foo (foo)) (bar (bar)))
... accumulate result ...
result)))

But maybe it's just me.

Vladimir Zolotykh

unread,
Mar 3, 2002, 9:17:59 AM3/3/02
to
Erik Naggum wrote:
>
> * Vladimir Zolotykh <gsm...@eurocom.od.ua>
> | Semantically, I want latter, e.g. pure local variables within FOO.
>
> May I suggest multiple-value-bind instead of multiple-value-setq?
> Memory is not so scarce that you need to re-use variables or arguments.

You're right. I had not seen that myself. Anyway this is one of the
most beautiful things of Common Lisp (at least to me). One thing could
be done in countless ways. But some time needed to become familiar with
such vast freedom.

--
Vladimir Zolotykh

Hannah Schroeter

unread,
Mar 3, 2002, 3:54:39 PM3/3/02
to
Hello!

In article <3C82068B...@eurocom.od.ua>,


Vladimir Zolotykh <gsm...@eurocom.od.ua> wrote:
>Is it safe to write FOO in the following way

>(defun foo (&key a b c)
> (multiple-value-setq (a b c) (bar))
> (list a b c))

>?

>Or maybe more safer would be

>(defun foo (&key a b c)
> (let ((a a) (b b) (c c))
> (multiple-value-setq (a b c) (bar))
> (list a b c)))

>Semantically, I want latter, e.g. pure local variables within FOO.

Why not

(defun foo ()
(multiple-value-bind (a b c) (bar)
(list a b c)))
?

>[...]

Kind regards,

Hannah.

0 new messages