Thread View: comp.lang.clos
4 messages
4 total messages
Started by Jeffrey B Kane
Tue, 10 Nov 1992 02:10
Re: clos initforms'
Author: Jeffrey B Kane
Date: Tue, 10 Nov 1992 02:10
Date: Tue, 10 Nov 1992 02:10
51 lines
1846 bytes
1846 bytes
>Try using an :after method for initialize-instance on this class.
>E.g., (not tested),
>(defmethod initialize-instance :after ((new test-class) &key)
> (unless (slot-boundp new 'slot-2)
> (setf (slot-2 new) (slot-1 new))))
Dan,
This would work, however after looking at the various ways that I
should handle this, it looks like I should define a constructor
function, then check if various key words have been defined, i.e.
(defclass test-class ()
((slot-1 :initarg :slot-1
:accessor slot-1)
(slot-2 :initarg :slot-2
:accessor slot-2)))
(defun make-test-class (&key (slot-1 3) slot-2)
(unless (boundp slot2)
(setf slot-2 slot-1))
(make-instance 'test-class :slot-1 slot-1 :slot-2 slot-2))
The problem with this approach is that the function "boundp"
does not test if the user typed in a particular key word.
Calling:
(make-test-class :slot-2 4)
results in the error:
> Error: Unbound variable: SLOT2
> While executing: SYMBOL-VALUE
The reason I think that the constructor approach is bettter is than
using initialize-instance :after is that it allows other key word and
a higher level of abstraction. The the bottom line question is:
Other than defining a keyword with some kind of a value to flag it
hasn't been used, how can you test if it was used similar to slot-boundp
for slots?
Jeffrey
================
Jeffrey Kane, MD
Kane Biomedical Systems
Internet jbk@world.std.com
Re: clos initforms'
Author: kanderso
Date: Tue, 10 Nov 1992 04:32
Date: Tue, 10 Nov 1992 04:32
72 lines
3350 bytes
3350 bytes
To: comp.lang.clos@cis.ohio-state.edu
Date: Tue, 10 Nov 1992 02:10:29 GMT
Organization: The World Public Access UNIX, Brookline, MA
From: Jeffrey B Kane <jbk@world.std.com>
Sender: commonloops-request@cis.ohio-state.edu
Subject: Re: clos initforms'
>Try using an :after method for initialize-instance on this class.
>E.g., (not tested),
>(defmethod initialize-instance :after ((new test-class) &key)
> (unless (slot-boundp new 'slot-2)
> (setf (slot-2 new) (slot-1 new))))
While, i think the above is the right approach, for completeness, one could
also delay initializing slot-2 until it was accessed:
(defmethod slot-2 ((tc test-class))
(if (slot-boundp tc 'slot-2) (slot-value tc 'slot-2)
(if (slot-boundp tc 'slot-1) (setf (slot-value tc 'slot-2)
(slot-value tc 'slot-1))
(slot-value tc 'slot-2)))) ; Lose Lose.
Dan,
This would work, however after looking at the various ways that I
should handle this, it looks like I should define a constructor
function, then check if various key words have been defined, i.e.
(defclass test-class ()
((slot-1 :initarg :slot-1
:accessor slot-1)
(slot-2 :initarg :slot-2
:accessor slot-2)))
(defun make-test-class (&key (slot-1 3) slot-2)
(unless (boundp slot2)
(setf slot-2 slot-1))
(make-instance 'test-class :slot-1 slot-1 :slot-2 slot-2))
The problem with this approach is that the function "boundp"
does not test if the user typed in a particular key word.
Calling:
(make-test-class :slot-2 4)
results in the error:
> Error: Unbound variable: SLOT2
> While executing: SYMBOL-VALUE
The reason I think that the constructor approach is bettter is than
using initialize-instance :after is that it allows other key word and
a higher level of abstraction. The the bottom line question is:
I really think using a constructor and an initialize-instance :after are
separate issues. For example, your make-test-class constructor contains
knowledge about the class test-class. If you now defined a class
test-class-2 as a subclass of test-class, and built the corresponding
constructor make-test-class-2, you would have to duplicate that knowledge.
Using initialize-instance :after, lets you specify that knowledge in one place.
So, i'd recommend using the initialize-instance :after approach to concentrate
knowledge about your classes in one place, and also the constructor
approach if you wanted to hide everything from your users.
Other than defining a keyword with some kind of a value to flag it
hasn't been used, how can you test if it was used similar to slot-boundp
for slots?
(defun make-test-class (&key (slot-1 3) (slot-2 nil slot-2-bound-p)) ...
Re: clos initforms'
Author: Barry Margolin
Date: Tue, 10 Nov 1992 17:54
Date: Tue, 10 Nov 1992 17:54
56 lines
2396 bytes
2396 bytes
In article <BxHA1I.G6D@world.std.com> jbk@world.std.com (Jeffrey B Kane) writes:
>(defun make-test-class (&key (slot-1 3) slot-2)
> (unless (boundp slot2)
> (setf slot-2 slot-1))
> (make-instance 'test-class :slot-1 slot-1 :slot-2 slot-2))
>
>The problem with this approach is that the function "boundp"
>does not test if the user typed in a particular key word.
>
>Calling:
>
>(make-test-class :slot-2 4)
>
>results in the error:
>
>> Error: Unbound variable: SLOT2
>> While executing: SYMBOL-VALUE
The reason you got that error is because you mistyped the name of the
variable, leaving out the hyphen. However, had you spelled it correctly
you would probably have gotten something like:
>>Error: The value of S, 4, should be a SYMBOL
BOUNDP:
Required arg 0 (S): 4
The problem here is that you didn't quote the symbol argument to BOUNDP.
Fixing that, however, wouldn't solve your problem either. BOUNDP can only
be used to test dynamic variables, not lexical variables; the latter are
always bound. Also, the default value for unsupplied keyword arguments is
NIL, not unbound.
>Other than defining a keyword with some kind of a value to flag it
>hasn't been used, how can you test if it was used similar to slot-boundp
>for slots?
Use a supplied-p parameter (called "svar" on p.76-80 of CLtL2):
(defun make-test-class (&key (slot-1 3) (slot-2 nil slot-2-supplied-p))
(unless slot-2-supplied-p
(setf slot-2 slot-1))
(make-instance 'test-class :slot-1 slot-1 :slot-2 slot-2))
Also, the initform for optional and keyword parameters is evaluated in an
environment that includes the bindings of all the arguments preceding it in
the lambda list, so for this particular case you could write:
(defun make-test-class (&key (slot-1 3) (slot-2 slot-1))
(make-instance 'test-class :slot-1 slot-1 :slot-2 slot-2))
--
Barry Margolin
System Manager, Thinking Machines Corp.
barmar@think.com {uunet,harvard}!think!barmar
Supplied-p in lambda-list (was Re: clos initforms'
Author: Len Charest
Date: Thu, 12 Nov 1992 01:10
Date: Thu, 12 Nov 1992 01:10
30 lines
1738 bytes
1738 bytes
In article <BxHA1I.G6D@world.std.com>, jbk@world.std.com (Jeffrey B Kane) writes:
|> ... I should define a constructor
|> function, then check if various key words have been defined, i.e.
|>
|> (defclass test-class ()
|> ((slot-1 :initarg :slot-1
|> :accessor slot-1)
|> (slot-2 :initarg :slot-2
|> :accessor slot-2)))
|>
|> (defun make-test-class (&key (slot-1 3) slot-2)
|> (unless (boundp slot2)
|> (setf slot-2 slot-1))
|> (make-instance 'test-class :slot-1 slot-1 :slot-2 slot-2))
|>
|> Other than defining a keyword with some kind of a value to flag it
|> hasn't been used, how can you test if it was used similar to slot-boundp
|> for slots?
The lambda list of the function supports this kind of test. See page 76 of CLtL2.
(defun make-test-class (&key (slot-1 3) (slot-2 nil existp))
(unless existp
(setq slot-2 slot-1))
(make-instance 'test-class :slot-1 slot-1 :slot-2 slot-2))
..................................................
Len Charest, Jr.
JPL Artificial Intelligence Group
charest@aig.jpl.nasa.gov
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads