* #:getter procedure returns unexpected value in GOOPS @ 2014-04-25 23:24 Diogo F. S. Ramos 2014-04-26 12:26 ` Neil Jerram ` (2 more replies) 0 siblings, 3 replies; 12+ messages in thread From: Diogo F. S. Ramos @ 2014-04-25 23:24 UTC (permalink / raw) To: guile-user When using GOOPS, if a class has a second slot, the #:getter procedure of the first slot returns the value of the second slot when applied to an instance of a subclass. --8<---------------cut here---------------start------------->8--- (use-modules (oop goops)) (define-class <foo> () (a #:init-form 'foo #:getter foo-a) (b #:init-form 42)) (define-class <bar> (<foo>) (a #:init-form 'bar)) --8<---------------cut here---------------end--------------->8--- (foo-a (make <foo>)) => foo (foo-a (make <bar>)) => 42 I expected: (foo-a (make <bar>)) => bar I'm not too familiar with GOOPS, so I'm not sure this is the right behavior. I'm using Guile 2.0.11. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: #:getter procedure returns unexpected value in GOOPS 2014-04-25 23:24 #:getter procedure returns unexpected value in GOOPS Diogo F. S. Ramos @ 2014-04-26 12:26 ` Neil Jerram 2014-04-26 17:35 ` Diogo F. S. Ramos 2014-04-27 1:15 ` Mark H Weaver 2015-03-09 21:58 ` Andy Wingo 2 siblings, 1 reply; 12+ messages in thread From: Neil Jerram @ 2014-04-26 12:26 UTC (permalink / raw) To: Diogo F. S. Ramos; +Cc: guile-user "Diogo F. S. Ramos" <dfsr@riseup.net> writes: > When using GOOPS, if a class has a second slot, the #:getter procedure > of the first slot returns the value of the second slot when applied to > an instance of a subclass. > > (use-modules (oop goops)) > > (define-class <foo> () > (a #:init-form 'foo #:getter foo-a) > (b #:init-form 42)) > > (define-class <bar> (<foo>) > (a #:init-form 'bar)) > > (foo-a (make <foo>)) => foo > (foo-a (make <bar>)) => 42 > > I expected: > > (foo-a (make <bar>)) => bar > > I'm not too familiar with GOOPS, so I'm not sure this is the right > behavior. Do you see this if you use #:init-value instead of #:init-form ? It sounds to me like #:init-value is what you really want, and I suspect you're seeing undefined behaviour that arises from giving an unparenthesized form ('42') to #:init-form. Neil ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: #:getter procedure returns unexpected value in GOOPS 2014-04-26 12:26 ` Neil Jerram @ 2014-04-26 17:35 ` Diogo F. S. Ramos 2014-04-26 22:19 ` David Pirotte 0 siblings, 1 reply; 12+ messages in thread From: Diogo F. S. Ramos @ 2014-04-26 17:35 UTC (permalink / raw) To: Neil Jerram; +Cc: guile-user > "Diogo F. S. Ramos" <dfsr@riseup.net> writes: > >> When using GOOPS, if a class has a second slot, the #:getter procedure >> of the first slot returns the value of the second slot when applied to >> an instance of a subclass. >> >> (use-modules (oop goops)) >> >> (define-class <foo> () >> (a #:init-form 'foo #:getter foo-a) >> (b #:init-form 42)) >> >> (define-class <bar> (<foo>) >> (a #:init-form 'bar)) >> >> (foo-a (make <foo>)) => foo >> (foo-a (make <bar>)) => 42 >> >> I expected: >> >> (foo-a (make <bar>)) => bar >> >> I'm not too familiar with GOOPS, so I'm not sure this is the right >> behavior. > > Do you see this if you use #:init-value instead of #:init-form ? It > sounds to me like #:init-value is what you really want, and I suspect > you're seeing undefined behaviour that arises from giving an > unparenthesized form ('42') to #:init-form. I tried changing all to `#:init-value', but the result was the same. --8<---------------cut here---------------start------------->8--- (use-modules (oop goops)) (define-class <foo> () (a #:init-value 'foo #:getter foo-a) (b #:init-value 42)) (define-class <bar> (<foo>) (a #:init-value 'bar)) (format #t "~a~%" (foo-a (make <foo>))) (format #t "~a~%" (foo-a (make <bar>))) --8<---------------cut here---------------end--------------->8--- Also, according to the documentation, it would not be what I want. INIT-VALUE specifies a fixed initial slot value (shared across all new instances of the class). I want a slot value that is exclusive to an instance. INIT-FORM specifies a form that, when evaluated, will return an initial value for the slot. The form is evaluated each time that an instance of the class is created, in the lexical environment of the containing ‘define-class’ expression. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: #:getter procedure returns unexpected value in GOOPS 2014-04-26 17:35 ` Diogo F. S. Ramos @ 2014-04-26 22:19 ` David Pirotte 2014-04-26 22:58 ` Diogo F. S. Ramos 0 siblings, 1 reply; 12+ messages in thread From: David Pirotte @ 2014-04-26 22:19 UTC (permalink / raw) To: Diogo F. S. Ramos; +Cc: guile-user Hello, > I tried changing all to `#:init-value', but the result was the same. Imo, using your definitions, guile should return 'foo, not 42. But note that you do not define a getter in <bar>. Still using your code the following will work: (foo-a (make <foo>)) (slot-ref (make <bar>) 'a) Then if you define a getter..., you also get the expected result Cheers, David ;; GNU Guile 2.0.11.2-0ece4 scheme@(guile-user)> scheme@(guile-user)> (use-modules (oop goops)) (define-class <foo> () (a #:init-value 'foo #:getter foo-a) (b #:init-value 42)) (define-class <bar> (<foo>) (a #:init-value 'bar #:getter foo-a)) (foo-a (make <foo>)) (foo-a (make <bar>)) $2 = foo $3 = bar scheme@(guile-user)> ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: #:getter procedure returns unexpected value in GOOPS 2014-04-26 22:19 ` David Pirotte @ 2014-04-26 22:58 ` Diogo F. S. Ramos 2014-04-27 22:14 ` David Pirotte 0 siblings, 1 reply; 12+ messages in thread From: Diogo F. S. Ramos @ 2014-04-26 22:58 UTC (permalink / raw) To: David Pirotte; +Cc: guile-user >> I tried changing all to `#:init-value', but the result was the same. > > Imo, using your definitions, guile should return 'foo, not 42. IMO it should return 'bar, as `foo-a' should return the value of the slot `a', which in the subclass <bar> of <foo> is 'bar. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: #:getter procedure returns unexpected value in GOOPS 2014-04-26 22:58 ` Diogo F. S. Ramos @ 2014-04-27 22:14 ` David Pirotte 0 siblings, 0 replies; 12+ messages in thread From: David Pirotte @ 2014-04-27 22:14 UTC (permalink / raw) To: Diogo F. S. Ramos; +Cc: guile-user Hello Diego, > > Imo, using your definitions, guile should return 'foo, not 42. > IMO it should return 'bar, as `foo-a' should return the value of the > slot `a', which in the subclass <bar> of <foo> is 'bar. I am sorry, I ment no-applicable-method, I'll answer Mark's answer to explain why. David ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: #:getter procedure returns unexpected value in GOOPS 2014-04-25 23:24 #:getter procedure returns unexpected value in GOOPS Diogo F. S. Ramos 2014-04-26 12:26 ` Neil Jerram @ 2014-04-27 1:15 ` Mark H Weaver 2014-04-27 22:14 ` David Pirotte 2015-03-09 21:58 ` Andy Wingo 2 siblings, 1 reply; 12+ messages in thread From: Mark H Weaver @ 2014-04-27 1:15 UTC (permalink / raw) To: Diogo F. S. Ramos; +Cc: guile-user "Diogo F. S. Ramos" <dfsr@riseup.net> writes: > When using GOOPS, if a class has a second slot, the #:getter procedure > of the first slot returns the value of the second slot when applied to > an instance of a subclass. > > (use-modules (oop goops)) > > (define-class <foo> () > (a #:init-form 'foo #:getter foo-a) > (b #:init-form 42)) > > (define-class <bar> (<foo>) > (a #:init-form 'bar)) > > (foo-a (make <foo>)) => foo > (foo-a (make <bar>)) => 42 > > I expected: > > (foo-a (make <bar>)) => bar Indeed, CLOS behaves as you expected, and GOOPS should probably behave the same way. However, it appears that overriding the attributes of slots in subclasses has not worked this way in a long time, if ever. I tried this example on both Guile 1.8 and Guile 1.6, and neither of them behave as you expected. Instead they complain that there's no applicable method for 'foo-a'. Can you please send a bug report to bug-guile@gnu.org? For now, I suggest adding an initialize method for <bar>, like this: --8<---------------cut here---------------start------------->8--- (use-modules (oop goops)) (define-class <foo> () (a #:init-form 'foo #:getter foo-a) (b #:init-form 42)) (define-class <bar> (<foo>)) (define-method (initialize (obj <bar>) args) (slot-set! obj 'a 'bar) (next-method)) (foo-a (make <foo>)) => foo (foo-a (make <bar>)) => bar --8<---------------cut here---------------end--------------->8--- Regards, Mark ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: #:getter procedure returns unexpected value in GOOPS 2014-04-27 1:15 ` Mark H Weaver @ 2014-04-27 22:14 ` David Pirotte 2014-04-28 1:12 ` Mark H Weaver 0 siblings, 1 reply; 12+ messages in thread From: David Pirotte @ 2014-04-27 22:14 UTC (permalink / raw) To: Mark H Weaver; +Cc: guile-user Hi Mark, > > When using GOOPS, if a class has a second slot, the #:getter procedure > > of the first slot returns the value of the second slot when applied to > > an instance of a subclass. > > > > (use-modules (oop goops)) > > > > (define-class <foo> () > > (a #:init-form 'foo #:getter foo-a) > > (b #:init-form 42)) > > > > (define-class <bar> (<foo>) > > (a #:init-form 'bar)) > > > > (foo-a (make <foo>)) => foo > > (foo-a (make <bar>)) => 42 > > > > I expected: > > > > (foo-a (make <bar>)) => bar > Indeed, CLOS behaves as you expected... Are you sure about that? I don't have a CLOS implementation 'at hand', and did not have the time to carefully (re)read the hyperspec doc (my knowledge of it is quite rusty now, it's been a very [very] long time since I studied it), but iirc, where the slot list of a subclass must be computed as being the union of ..., I am not sure it implies that a particular slot definition should result as the union of getters, setters, accessors and any of the previously defined slot option actually. Consider the following situation: (use-modules (oop goops)) (define-class <foo> () (a #:accessor blue #:allocation #:virtual #:slot-ref (lambda (obj) 'foo) #:slot-set! (lambda (obj val) (values)))) (define-class <bar> (<foo>) (a #:accessor red #:init-value 'bar)) (class-slots <bar>) (class-slots <foo>) (define foo (make <foo>)) (define bar (make <bar>)) (blue bar) (red bar) (set! (blue bar) 'the-blue-bar) (set! (red bar) 'the-red-bar) (blue bar) (red bar) ... > I tried this example on both Guile 1.8 and Guile 1.6, and neither of > them behave as you expected. Instead they complain that there's no > applicable method for 'foo-a'. To me it is the right answer, the slot must be (re)defined, and not inherit any previously defined slot options, but of course I might be wrong. Cheers, David ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: #:getter procedure returns unexpected value in GOOPS 2014-04-27 22:14 ` David Pirotte @ 2014-04-28 1:12 ` Mark H Weaver 2014-05-02 4:36 ` David Pirotte 0 siblings, 1 reply; 12+ messages in thread From: Mark H Weaver @ 2014-04-28 1:12 UTC (permalink / raw) To: David Pirotte; +Cc: guile-user David Pirotte <david@altosw.be> writes: > Hi Mark, > >> > When using GOOPS, if a class has a second slot, the #:getter procedure >> > of the first slot returns the value of the second slot when applied to >> > an instance of a subclass. >> > >> > (use-modules (oop goops)) >> > >> > (define-class <foo> () >> > (a #:init-form 'foo #:getter foo-a) >> > (b #:init-form 42)) >> > >> > (define-class <bar> (<foo>) >> > (a #:init-form 'bar)) >> > >> > (foo-a (make <foo>)) => foo >> > (foo-a (make <bar>)) => 42 >> > >> > I expected: >> > >> > (foo-a (make <bar>)) => bar > >> Indeed, CLOS behaves as you expected... > > Are you sure about that? Read this: http://clhs.lisp.se/Body/07_ec.htm In particular: "In general, more than one class among C and its superclasses can define a slot with a given name. In such cases, only one slot with the given name is accessible in an instance of C, and the characteristics of that slot are a combination of the several slot specifiers, computed as follows: [...]" Here's a transcript of an SBCL session I tried on Debian: --8<---------------cut here---------------start------------->8--- This is SBCL 1.0.57.0.debian, an implementation of ANSI Common Lisp. More information about SBCL is available at <http://www.sbcl.org/>. SBCL is free software, provided as is, with absolutely no warranty. It is mostly in the public domain; some portions are provided under BSD-style licenses. See the CREDITS and COPYING files in the distribution for more information. * (defclass foo () ((a :initform 'foo :reader foo-a) (b :initform 42))) #<STANDARD-CLASS FOO> * (defclass bar (foo) ((a :initform 'bar))) #<STANDARD-CLASS BAR> * (values (foo-a (make-instance 'foo)) (foo-a (make-instance 'bar))) FOO BAR --8<---------------cut here---------------end--------------->8--- Unknown_lamer on #guile tried the same thing with a different implementation of Common Lisp, and got the same answer. Mark ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: #:getter procedure returns unexpected value in GOOPS 2014-04-28 1:12 ` Mark H Weaver @ 2014-05-02 4:36 ` David Pirotte 0 siblings, 0 replies; 12+ messages in thread From: David Pirotte @ 2014-05-02 4:36 UTC (permalink / raw) To: Mark H Weaver; +Cc: guile-user Hi Mark, > Read this: > > http://clhs.lisp.se/Body/07_ec.htm Perfect, thanks for the link and the confirmation. Note that in the current implementation, guile's problem is not the [proper] initialization of the inherited slot, as I did show and as you can check, slot-ref works as expected on Diego's example. One can also use describe for that matter (oop goops describe) .. The problem is that getters, setters and accessors although [merely] inherited are not properly recomputed. Your temporary solution is nice, but only works if there is no need for a change of the inherited slot allocation option, and would not solve the 'quantum mechanic' slot states :) that my 'consider the following situation' example shows. Therefore, in the mean time, I personally would recommend goops users to redefine getters, setters and accessors they are using/plan to use on their subclasse's instances, since it is currently the only way to 'force' guile to do his job properly. > Here's a transcript of an SBCL session I tried on Debian: Yep, I've downloaded it too now, it's been a while I did not play with lisp :) I much prefer scheme and guile now. But then I am not surprised they got it right, for lispers clos is an old beast and lisp implementations have, by far, much much more code and many many more testers as well, indeed clos is so much more used by lispers then goops by schemers. Cheers, David ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: #:getter procedure returns unexpected value in GOOPS 2014-04-25 23:24 #:getter procedure returns unexpected value in GOOPS Diogo F. S. Ramos 2014-04-26 12:26 ` Neil Jerram 2014-04-27 1:15 ` Mark H Weaver @ 2015-03-09 21:58 ` Andy Wingo 2015-04-23 22:56 ` David Pirotte 2 siblings, 1 reply; 12+ messages in thread From: Andy Wingo @ 2015-03-09 21:58 UTC (permalink / raw) To: Diogo F. S. Ramos; +Cc: guile-user Hi! On Sat 26 Apr 2014 01:24, "Diogo F. S. Ramos" <dfsr@riseup.net> writes: > When using GOOPS, if a class has a second slot, the #:getter procedure > of the first slot returns the value of the second slot when applied to > an instance of a subclass. > > (use-modules (oop goops)) > > (define-class <foo> () > (a #:init-form 'foo #:getter foo-a) > (b #:init-form 42)) > > (define-class <bar> (<foo>) > (a #:init-form 'bar)) > > (foo-a (make <foo>)) => foo > (foo-a (make <bar>)) => 42 > > I expected: > > (foo-a (make <bar>)) => bar I realize this is really late :) But since this thread isn't linked to a bug, note that this is now fixed in stable-2.0 and master, to match the behavior in Guile 1.8 and previous, which is actually that: (foo-a (make <bar>)) => error! because <bar> doesn't just define a different init-value for the slot, it defines a different slot entirely. Andy -- http://wingolog.org/ ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: #:getter procedure returns unexpected value in GOOPS 2015-03-09 21:58 ` Andy Wingo @ 2015-04-23 22:56 ` David Pirotte 0 siblings, 0 replies; 12+ messages in thread From: David Pirotte @ 2015-04-23 22:56 UTC (permalink / raw) To: Andy Wingo; +Cc: guile-user, Diogo F. S. Ramos [-- Attachment #1: Type: text/plain, Size: 3826 bytes --] Hello Andy, Le Mon, 09 Mar 2015 22:58:20 +0100, Andy Wingo <wingo@pobox.com> a écrit : > Hi! > > On Sat 26 Apr 2014 01:24, "Diogo F. S. Ramos" <dfsr@riseup.net> writes: > > > When using GOOPS, if a class has a second slot, the #:getter procedure > > of the first slot returns the value of the second slot when applied to > > an instance of a subclass. > > > > (use-modules (oop goops)) > > > > (define-class <foo> () > > (a #:init-form 'foo #:getter foo-a) > > (b #:init-form 42)) > > > > (define-class <bar> (<foo>) > > (a #:init-form 'bar)) > > > > (foo-a (make <foo>)) => foo > > (foo-a (make <bar>)) => 42 > > > > I expected: > > > > (foo-a (make <bar>)) => bar > > I realize this is really late :) But since this thread isn't linked to > a bug, note that this is now fixed in stable-2.0 and master, to match > the behavior in Guile 1.8 and previous, which is actually that: > > (foo-a (make <bar>)) => error! > > because <bar> doesn't just define a different init-value for the slot, > it defines a different slot entirely. I'm late too :) I am afraid this was an unfortunate and quite terrible [design? I doubt] bug in Guile-1.8 then. Indeed, even Stklos does correctly implement subclass slot redefinition as specified by the clos protocol [*] ;;; subclass-slot-redefinition.scm starts here (define-class <person> () ((name :accessor name :init-keyword :name :init-form "") (age :accessor age :init-keyword :age :init-form -1))) (define-class <teacher> (<person>) ((subject :accessor subject :init-keyword :subject :init-form ""))) (define-class <maths-teacher> (<teacher>) ((subject :init-form "Mathematics"))) ;;; ends here david@capac:~/alto/projects/stklos 8 $ stklos * STklos version 1.10 * Copyright (C) 1999-2011 Erick Gallesio - Universite de Nice <eg@unice.fr> * * [Linux-3.16.0-4-amd64-x86_64/pthread/readline/utf8] stklos> (load "subclass-slot-redefinition.scm") stklos> (define p2 (make <maths-teacher> :name 'john :age 34)) ;; p2 stklos> (describe p2) #[<maths-teacher> b34420] is an an instance of class <maths-teacher>. Slots are: age = 34 name = john subject = "Mathematics" stklos> [*] In summary, the clos protocol says: [ this is a copy/paste from a clos tutorial, also pointed by [ the Stklos reference manual: [ http://www.aiai.ed.ac.uk/~jeff/clos-guide.html#slots When there are superclasses, a subclass can specify a slot that has already been specified for a superclass. When this happens, the information in slot options has to be combined. For the slot options listed above, either the option in the subclass overrides the one in the superclass or there is a union: :ACCESSOR - union :INITARG - union :INITFORM - overrides This is what you should expect. The subclass can change the default initial value by overriding the :initform, and can add to the initargs and accessors. However, the union for :accessor is just a consequence of how generic functions work. If they can apply to instances of a class C, they can also apply to instances of subclasses of C. (Accessor functions are generic.) Note that the last sentence, which applies to getters and setters of course, is of prime importance wrt our previous conversation and my reported bug about setters, which must be inherited: wrt setters not being inherited, the current situation not only creates technical problems [it forces users to a [bad imo] programming style to overcome the bug] but it introduced a dual semantic for define-method and breaks this fundamental [language designed] rule: "... If they can apply to instances of a class C, they can also apply to instances of subclasses of C..." Cheers, David [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 473 bytes --] ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2015-04-23 22:56 UTC | newest] Thread overview: 12+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2014-04-25 23:24 #:getter procedure returns unexpected value in GOOPS Diogo F. S. Ramos 2014-04-26 12:26 ` Neil Jerram 2014-04-26 17:35 ` Diogo F. S. Ramos 2014-04-26 22:19 ` David Pirotte 2014-04-26 22:58 ` Diogo F. S. Ramos 2014-04-27 22:14 ` David Pirotte 2014-04-27 1:15 ` Mark H Weaver 2014-04-27 22:14 ` David Pirotte 2014-04-28 1:12 ` Mark H Weaver 2014-05-02 4:36 ` David Pirotte 2015-03-09 21:58 ` Andy Wingo 2015-04-23 22:56 ` David Pirotte
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).