From: Phil Armitage
Subject: generate :writer but provide :reader method
Date: 
Message-ID: <03aaadc6-5ca5-40a7-b3cc-0b91d25e91ef@m18g2000vbi.googlegroups.com>
Is it possible to let CLOS create a writer function for me while I
provide my own reader with the same name? The following doesn't work:

(defclass message ()
  ((timestamp :initform "" :initarg :timestamp :writer timestamp)))

(defmethod timestamp ((message message))
  (format nil "~A:~A:~A.~A"
    (subseq (slot-value message 'timestamp) 0 2)
    (subseq (slot-value message 'timestamp) 2 4)
    (subseq (slot-value message 'timestamp) 4 6)
    (subseq (slot-value message 'timestamp) 6 9)))

(let ((m (make-instance 'message :timestamp "101523427")))
  (print (timestamp m)))

With this, I get an incompatible lambda list, presumably because CLOS
has generated a SETF version for me with two arguments. If the best
option is simply to use a different method name, e.g. FORMATTED-
TIMESTAMP, then that's fine but I'm still interested if the above is
technically possible.

Thanks.

-- phil

From: Paul Donnelly
Subject: Re: generate :writer but provide :reader method
Date: 
Message-ID: <87tz25hn8n.fsf@plap.localdomain>
Phil Armitage <···············@gmail.com> writes:

> Is it possible to let CLOS create a writer function for me while I
> provide my own reader with the same name? The following doesn't work:
>
> (defclass message ()
>   ((timestamp :initform "" :initarg :timestamp :writer timestamp)))
>
> (defmethod timestamp ((message message))
>   (format nil "~A:~A:~A.~A"
>     (subseq (slot-value message 'timestamp) 0 2)
>     (subseq (slot-value message 'timestamp) 2 4)
>     (subseq (slot-value message 'timestamp) 4 6)
>     (subseq (slot-value message 'timestamp) 6 9)))
>
> (let ((m (make-instance 'message :timestamp "101523427")))
>   (print (timestamp m)))
>
> With this, I get an incompatible lambda list, presumably because CLOS
> has generated a SETF version for me with two arguments. If the best
> option is simply to use a different method name, e.g. FORMATTED-
> TIMESTAMP, then that's fine but I'm still interested if the above is
> technically possible.

A little messing around shows that if you use :ACCESSOR in your class
definition, then define your TIMESTAMP method, it will replace the
generated method as you might want. At least in SBCL. Intuitively it
seems like you won't run into problems doing this.

As for using another name, it seems better to me to do the above or to
manually define the setf expander as well as the TIMESTAMP method, if
the above proves flaky. Unless you decide that a better default for the
TIMESTAMP method is to provide an unformatted timestamp.
From: Phil Armitage
Subject: Re: generate :writer but provide :reader method
Date: 
Message-ID: <e12cddfa-e5e8-4a61-8c9d-254193a54cc5@j20g2000vbp.googlegroups.com>
On Jun 24, 12:42 pm, Paul Donnelly <·············@sbcglobal.net>
wrote:
> Phil Armitage <···············@gmail.com> writes:
> > Is it possible to let CLOS create a writer function for me while I
> > provide my own reader with the same name?
> A little messing around shows that if you use :ACCESSOR in your class
> definition, then define your TIMESTAMP method, it will replace the
> generated method as you might want.

Thanks to all those who replied.

Your suggestion also works in CCL but I've gone with the

  :writer (setf timestamp)

that Frode suggested as it clearly states what I want (but it's good
to know the available options).

-- phil
From: Frode V. Fjeld
Subject: Re: generate :writer but provide :reader method
Date: 
Message-ID: <8763elq2pb.fsf@disk.lan>
Phil Armitage <···············@gmail.com> writes:

> Is it possible to let CLOS create a writer function for me while I
> provide my own reader with the same name? The following doesn't work:
>
> (defclass message ()
>   ((timestamp :initform "" :initarg :timestamp :writer timestamp)))

Perhaps this is what you want?

  (defclass message ()
    ((timestamp
       :initform ""
       :initarg :timestamp
       :writer (setf timestamp))))


-- 
Frode Vatvedt Fjeld