From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Andy Wingo Newsgroups: gmane.lisp.guile.devel Subject: Re: goops - guile-clutter unexpected bug while using #:virtual slot allocation for a subclass Date: Fri, 06 Feb 2015 14:33:35 +0100 Message-ID: <878ugb9nbk.fsf@pobox.com> References: <20141219174633.6efb845e@capac> <8761btfcni.fsf@pobox.com> <20150126230044.2d1e71de@capac> <87sieweie4.fsf@pobox.com> <20150127171115.6172ccea@capac> <87zj94c5rv.fsf@pobox.com> <20150130115015.5c8e3192@capac> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: ger.gmane.org 1423229636 18583 80.91.229.3 (6 Feb 2015 13:33:56 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Fri, 6 Feb 2015 13:33:56 +0000 (UTC) Cc: guile-devel To: David Pirotte Original-X-From: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Fri Feb 06 14:33:53 2015 Return-path: Envelope-to: guile-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1YJj2d-0006ON-Fa for guile-devel@m.gmane.org; Fri, 06 Feb 2015 14:33:51 +0100 Original-Received: from localhost ([::1]:48305 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YJj2c-0001Pl-RZ for guile-devel@m.gmane.org; Fri, 06 Feb 2015 08:33:50 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:54267) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YJj2X-0001Pc-Es for guile-devel@gnu.org; Fri, 06 Feb 2015 08:33:47 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YJj2R-0000Oo-Uk for guile-devel@gnu.org; Fri, 06 Feb 2015 08:33:45 -0500 Original-Received: from pb-sasl1.int.icgroup.com ([208.72.237.25]:62366 helo=sasl.smtp.pobox.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YJj2R-0000Nf-NM for guile-devel@gnu.org; Fri, 06 Feb 2015 08:33:39 -0500 Original-Received: from sasl.smtp.pobox.com (unknown [127.0.0.1]) by pb-sasl1.pobox.com (Postfix) with ESMTP id A9EC1325DD; Fri, 6 Feb 2015 08:33:38 -0500 (EST) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=pobox.com; h=from:to:cc :subject:references:date:in-reply-to:message-id:mime-version :content-type; s=sasl; bh=EKFLa4D/AQcwCQLPbQckYdaID4U=; b=KA32jO +hD3jWDw7ln5glwmla2E3TajEcz6GohClq8rHYHlD/f4WJC4wjyLsJ+P+WjwLWJ1 gQpTBNc4uERp2mn6cDhnGAJ7cyrPFZI9biwEWVXpVcODBypKULI2hnM4GTwM4/tm UjEKfm/9haqlFiscY6namjlfpeZJ36goNuPt4= DomainKey-Signature: a=rsa-sha1; c=nofws; d=pobox.com; h=from:to:cc :subject:references:date:in-reply-to:message-id:mime-version :content-type; q=dns; s=sasl; b=GTnZydqSeP5pI142AQtUPCuBy5CqqxYI gWIfM4LksAMu355YbZcZDCqtLr5q0frkPRWzg2ftlf0RaavXWcTRw46C2D8JsVZd nYEo+qSIeUFdSe5Co4h1LD/E75eJ85APeQQ8yy9UHgL0IgZeWqrzQBw/d9qRD+pu BKvt5oGb+pY= Original-Received: from pb-sasl1.int.icgroup.com (unknown [127.0.0.1]) by pb-sasl1.pobox.com (Postfix) with ESMTP id A1630325DC; Fri, 6 Feb 2015 08:33:38 -0500 (EST) Original-Received: from badger (unknown [88.160.190.192]) (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by pb-sasl1.pobox.com (Postfix) with ESMTPSA id C2AF9325DB; Fri, 6 Feb 2015 08:33:37 -0500 (EST) In-Reply-To: <20150130115015.5c8e3192@capac> (David Pirotte's message of "Fri, 30 Jan 2015 11:50:15 -0200") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.4 (gnu/linux) X-Pobox-Relay-ID: C19BD5C0-AE04-11E4-AEE7-B05EFC961345-02397024!pb-sasl1.pobox.com X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 208.72.237.25 X-BeenThere: guile-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Developers list for Guile, the GNU extensibility library" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Original-Sender: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.lisp.guile.devel:17650 Archived-At: Hello, May I first please reduce your test case. Here is an equivalent version: (use-modules (oop goops)) (define-class () (foo #:getter foo #:init-keyword #:foo)) (define-class ()) (define obj (make #:foo 34)) (define-method (foo (self )) (pk "ahoy!") (next-method)) (pk (foo obj)) It has nothing to do with modules or setters, and everything to do with GOOPS and accessors. Anyway, this has been a confusing thread, so let me summarize: It used to be, in Guile 1.8, that the test case didn't work at all: n guile> (pk (foo obj)) ;;; ("ahoy!") Backtrace: In current input: 18: 0* [peek ... 18: 1* [foo #< 7fc8898e0e20>] ?: 2 (let* ((next-method (goops:make-next-method self))) (pk "ahoy!") ...) : In expression (let* (#) (pk "ahoy!") ...): : No next method when calling #< foo (2)> with arguments (#< 7fc8898e0e20>) It is important to note what the behavior was in Guile 1.8 because it is the version that is closest to what Mikael originally wrote (or inherited from stklos); though there are many ways in which GOOPS could be better, I have been surprised again and again about the thoroughness of the original implementation. In Guile 2.0, I made an error that accidentally made this test case "work", in the sense that it would return the value of the slot "foo". scheme@(guile-user)> (pk (foo obj)) ;;; ("ahoy!") ;;; (34) $1 = 34 However it wouldn't always return the value of the slot "foo"; for example: scheme@(guile-user)> (define-class () (bar #:init-keyword #:bar)) scheme@(guile-user)> (define-class ( )) scheme@(guile-user)> (define obj2 (make #:foo 34 #:bar 42)) scheme@(guile-user)> (define-method (foo (self )) (pk "wat!!!") (next-method)) scheme@(guile-user)> (pk (foo obj2)) ;;; ("wat!!!") ;;; (42) $2 = 42 Here you see that it returns the value of the "bar" slot. Why? Because defining the (foo (self )) method *replaced* the accessor method for `foo' on instances of type with our new method, and then the next-method that applies is the accessor method that is specialized on values of type , which looks for the slot in field 0. I thought at first that this wasn't right, that really accessor methods need to specialize on the types that they actually see, not just their specializers; but that's not right, because not all subtypes of a type have all slots of all of their supertypes. That got me thinking and looking back, so I found the bug that I introduced. It turns out the GOOPS design is to add accessor methods for each subclass that has a given slot, and they are not designed to "inherit" -- i.e. an accessor method specialized on shouldn't be in the next-method list for . I have recently made a change to restore us to Guile 1.8 behavior, so as to fix the "wat" bug above in Guile 2.0 and 2.2. > This said and with that in mind, the implementation you say was in guile-1.8 and > that it appears you have reimplemented 'right now' breaks the specification and > afaiac makes goops totally unusable for any serious work: this is a catastrophy, > please reconsider! David, I would really appreciate it if you could tone down the hyperbole. Thanks in advance :) > When talking about goops, we should not refer to 1.8 (*), 1.6 or any guile version > for that matter, but to the clos language spec subset goops implements [appart from > the adaptation for it to be module protected, but that is not the point here]. (defclass () ((foo :reader foo :initarg :foo))) (defclass () ()) (defvar obj (make-instance ' :foo 34)) (defmethod foo ((self )) (write "ahoy!") (call-next-method)) (foo obj) Interestingly, in CLISP at least this works in the way you expect: it prints "ahoy" and then chains up and returns the value. I also note that it doesn't install accessor methods on each subtype; before defining the "ahoy" method, I got this: > (generic-function-methods #'foo) (#>)>) And that method worked on instances of just as well. I am not sure how to interpret this result. The slot definition protocol in CLOS is different; for example, compute-effective-slot-definition in CLOS logically *combines* slot definitions with the same name. Could it be that in CLOS, all instances of a type are considered to have all slots of all supertypes? That is not the GOOPS design, but perhaps that should change. Andy -- http://wingolog.org/