From: Larry Clapp
Subject: changing slots in an overloaded initialize-instance, and type checking
Date:
Message-ID: <i8vpva.67o.ln@127.0.0.1>
Hi, all,
I'm fiddling with classes. In Java and C++ one can write a
constructor that accepts, for example, a string, which it then
converts to an integer, and assigns to the appropriate slot. I've
done something similar with an :after method on initialize-instance:
* (defclass ch04-ex02 ()
((x :initarg :x :type fixnum)))
* (defmethod initialize-instance :after ((obj ch04-ex02) &rest initargs)
(declare (ignore initargs))
(format t "Created a ch04-ex02~%")
(with-slots (x) obj
(format t "obj.x is ~s of type ~a~%" x (type-of x))
(setf x
(ctypecase x
(fixnum x)
(string (parse-integer x))))
(format t "obj.x is ~s of type ~a~%" x (type-of x))))
* (let ((obj (make-instance 'ch04-ex02 :x "123")))
(declare (ignore obj))
(format t "finished creating a ch04-ex02~%"))
>> Created a ch04-ex02
>> obj.x is "123" of type (SIMPLE-BASE-STRING 3)
>> obj.x is 123 of type FIXNUM
>> finished creating a ch04-ex02
=> NIL
So this appears to work, so far.
I wonder, though, if anyone could comment on the initial value of
"123" (a string) for slot X, given that I specified :type fixnum.
To elaborate, CMUCL doesn't complain about this (or hasn't yet, at
least), but I've seen it complain about the initial value of NIL for Y
in:
(defun dummy ()
(let (y)
(declare (fixnum y))
(print y)))
(compile 'dummy)
so I wonder if other compilers check for stuff like slot types.
I know the HyperSpec entry under DEFCLASS says, "The consequences of
attempting to store in a slot a value that does not satisfy the type
of the slot are undefined", and that "No conforming code may depend on
the results or effects [of undefined code]". I read this to mean, I
couldn't rely on CMUCL checking it (if it did), but I also can't rely
on some other compiler NOT checking it.
So also, do any of you a) know of other compilers that check the type
of a slot's initial value, and b) try tricks like this that change a
slot value's type, and if so, how do you do it?
Thanks for your help!
-- Larry
From: Christophe Rhodes
Subject: Re: changing slots in an overloaded initialize-instance, and type checking
Date:
Message-ID: <sqsmvze5iw.fsf@lambda.jcn.srcf.net>
Larry Clapp <·····@theclapp.org> writes:
> * (defclass ch04-ex02 ()
> ((x :initarg :x :type fixnum)))
>
> [...]
>
> So also, do any of you a) know of other compilers that check the type
> of a slot's initial value, and b) try tricks like this that change a
> slot value's type, and if so, how do you do it?
I'm not sure how assiduously Gerd Moellmann reads comp.lang.lisp, so
let me just briefly say that I believe that the latest release of his
work on PCL for CMUCL checks :TYPE arguments to slots rather more
carefully than released versions of CMUCL do.
To "get round" this, would you not be better off defining an :AROUND
method on INITIALIZE-INSTANCE, and ensuring that initargs satisfying
the proper type invariants get passed to the primary method?
Cheers,
Christophe
--
http://www-jcsu.jesus.cam.ac.uk/~csr21/ +44 1223 510 299/+44 7729 383 757
(set-pprint-dispatch 'number (lambda (s o) (declare (special b)) (format s b)))
(defvar b "~&Just another Lisp hacker~%") (pprint #36rJesusCollegeCambridge)
From: Larry Clapp
Subject: Re: changing slots in an overloaded initialize-instance, and type checking
Date:
Message-ID: <58vqva.njo.ln@127.0.0.1>
In article <··············@lambda.jcn.srcf.net>, Christophe Rhodes wrote:
> Larry Clapp <·····@theclapp.org> writes:
>
>> * (defclass ch04-ex02 ()
>> ((x :initarg :x :type fixnum)))
>>
>> [...]
>>
>> So also, do any of you a) know of other compilers that check the
>> type of a slot's initial value, and b) try tricks like this that
>> change a slot value's type, and if so, how do you do it?
>
> I'm not sure how assiduously Gerd Moellmann reads comp.lang.lisp, so
> let me just briefly say that I believe that the latest release of
> his work on PCL for CMUCL checks :TYPE arguments to slots rather
> more carefully than released versions of CMUCL do.
>
> To "get round" this, would you not be better off defining an :AROUND
> method on INITIALIZE-INSTANCE, and ensuring that initargs satisfying
> the proper type invariants get passed to the primary method?
Probably. I started experimenting with a before method on
make-instance after I sent my initial query.
Thanks for the info on Gerd's changes!
-- Larry
From: Rahul Jain
Subject: Re: changing slots in an overloaded initialize-instance, and type checking
Date:
Message-ID: <87adi70xdp.fsf@localhost.localdomain>
Christophe Rhodes <·····@cam.ac.uk> writes:
> To "get round" this, would you not be better off defining an :AROUND
> method on INITIALIZE-INSTANCE, and ensuring that initargs satisfying
> the proper type invariants get passed to the primary method?
Or just not specifying the initarg in the class def and having the
initialize-instance :after method do the work, as it should.