[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Guile-2.2 - goops setters should be inherited, no matter what :)
From: |
David Pirotte |
Subject: |
Re: Guile-2.2 - goops setters should be inherited, no matter what :) |
Date: |
Fri, 17 Mar 2017 05:46:18 -0300 |
Hello Andy,
> > 1- setters, as in (define-method ((setter ...) (self <...>) ...) ...)
> > should (also :)) be inherited
> As you mention this is https://debbugs.gnu.org/cgi/bugreport.cgi?bug=19770.
Yep, but after carefully (re)reading your answer and the manual, doing some more
tests, I came to the conclusion stated in my message (the newly sent message),
which
in summary says:
our documentation says it will create the accessor, unless already
created
=> this, to me, means that:
(a) if the expansion code creates the accessor, it should be possible
for
users to use it on both <a> and <b> instances;
(b) from the text of the manual itself, the user should be able to
create
the accessor him/herself, then redefine the (setter foo) method
_without_
altering any semantic wrt to the situation users faces when they are in
the
(a) situation
In other words, once a user defines a setter, both the setter and getter (auto
created or not) should be available upon the class they belong to and all
subclasses
> I think we have an understanding about why things are the way they are
> in GOOPS ...
Good! And I understand you mostly have, if ot entirely inherited and not
redefined
the <situation> :)
> In this case though I don't know how to make a consistent system with
> the semantics you are looking for and without losing some of the speed
> of the current system.
I'm sorry to hear that, but then we should change the manual, since goops does
not
implement what is described...
note that on a semantic ground, it does not make much sense to define a
setter upon a inexistent 'variable location', so, to me, it makes more
sense to implement what the manual says;
I would definitely not consider speed here, not again semantic anyway,
but
instead implement what the manual says, maybe with a special note in the
manual to explain, if there is?, a way to achieve the same result with
better
speed... (like using #:getter then define-method (setter foo) ... ?)
> In short I think I just don't agree with this change as part of standard
> GOOPS, so I propose the second solution: to make sure you can implement
> the behavior you want as a user. What about using a wrapper define-class
> macro
> that removes "#:accessor foo" from its slot definitions and translates those
> to
> issue definitions like this:
>
> (define-method (foo (x <obj>)) (slot-ref x 'foo))
> (define-method ((setter foo) (x <obj>) val) (slot-set! x 'foo val))
Sure. Do you mean making such a wrapper available in 2.2.x (as opposed to each
of
us would have to write his own?
By the way that is exactly what the clos protocol says defclass should be
expanded
to when using :accessor, see [2] for an sbcl session upon the same 'case'
(adapted
for syntax and argument order (setf method first argument _must_ be the value
...))
just in case you'd like to play with again, I have made the example
code even
simpler see [1] (comment/uncomment the definition of the slot
with/without
the #:accessor and reload, to see how guile 'behaves' in both case...
To make it short :):), I'm fine to use the second solution, though allow me to
insist upon the fact that it is 'weird', to me, that the actual implementation
properly inherits the setter if the user does not define the accessor, but then
there is no getter, and if the user defines the accessor, then the setter is not
inherited anymore.
Cheers,
David
[1]
(define-class <a> ()
(width #:accessor width #:init-value 0)
#;(width #:init-value 0))
(define-method ((setter width) (self <a>) val)
;; here comes complex code, computing earth orbit, captain's age...
(pk "this is <a> !width setter method, hello!")
(slot-set! self 'width val)
val)
(define-class <b> (<a>))
(define a1 (make <a>))
(define b1 (make <b>))
(set! (width a1) 10)
(width a1)
(set! (width b1) 10)
(width b1)
[2]
(defclass <a> ()
((width :accessor width :initform 0)))
(defmethod (setf width) (val (self <a>))
;; here comes complex code, computing earth orbit, captain's age...
(format t "this is <a> (setf width) method, hello!")
(setf (slot-value self 'width) val)
val)
(defclass <b> (<a>) ())
(defvar a1 (make-instance '<a>))
(defvar b1 (make-instance '<b>))
=>
* (setf (width a1) 10)
this is <a> (setf width) method, hello!
10
* (width a1)
10
* (setf (width b1) 10)
this is <a> (setf width) method, hello!
10
* (width b1)
10
*
pgp8jrlvfoNjq.pgp
Description: OpenPGP digital signature