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.