From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Daniel Hartwig Newsgroups: gmane.lisp.guile.devel Subject: Re: goops - accessors, methods and generics Date: Sat, 23 Feb 2013 08:37:22 +0800 Message-ID: References: <20130221195139.59f41d13@capac> <20130222201110.0a9e715c@capac> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 X-Trace: ger.gmane.org 1361580262 2980 80.91.229.3 (23 Feb 2013 00:44:22 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sat, 23 Feb 2013 00:44:22 +0000 (UTC) Cc: guile-devel@gnu.org To: David Pirotte Original-X-From: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Sat Feb 23 01:44:43 2013 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 1U93EI-0008Qp-Ia for guile-devel@m.gmane.org; Sat, 23 Feb 2013 01:44:42 +0100 Original-Received: from localhost ([::1]:46817 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1U93Dx-0004nv-TQ for guile-devel@m.gmane.org; Fri, 22 Feb 2013 19:44:21 -0500 Original-Received: from eggs.gnu.org ([208.118.235.92]:36220) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1U93Dt-0004nH-BZ for guile-devel@gnu.org; Fri, 22 Feb 2013 19:44:20 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1U93Dr-00025a-It for guile-devel@gnu.org; Fri, 22 Feb 2013 19:44:17 -0500 Original-Received: from mail-ia0-x22a.google.com ([2607:f8b0:4001:c02::22a]:60546) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1U93Dr-00024m-BN for guile-devel@gnu.org; Fri, 22 Feb 2013 19:44:15 -0500 Original-Received: by mail-ia0-f170.google.com with SMTP id k20so1075038iak.29 for ; Fri, 22 Feb 2013 16:44:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:x-received:in-reply-to:references:date:message-id :subject:from:to:cc:content-type; bh=IN80js4Xg1bqfLdjqBwlaa2EHUZ+wV67D5udsnB0ZXo=; b=sI8vbMIBvJijfGWUe4yqEgWKW3Hdppux7POYl6IqoxBFmXSQ+0rXFl3Ks1MMXvnxF5 fzxdLHnykormLWzbIXmUcevFyBfps4jSqFTdgUc+rOhEuRZXXOmTIa5+DrzIovh+s6Ut cBEooUrmr++ugMQUA9jSvttewYX4HveJYYZW44K7CcLfr0+Yioh4S4+6SecAAS2wQgFo sh2cy9bEzDS7eG4Yt6n0Jtv++Tl1Zd8DPJKnr21kahCkVMPlK+QstJfbEmeh6fRoTvzu VsTqgAe40GCADRP8cUdMRPlx/6x7Tt5XgaGq9Eij5OaX2wkk5pvAXuDgfYstWrPEii/6 qNXg== X-Received: by 10.50.40.131 with SMTP id x3mr175432igk.10.1361579842330; Fri, 22 Feb 2013 16:37:22 -0800 (PST) Original-Received: by 10.64.26.168 with HTTP; Fri, 22 Feb 2013 16:37:22 -0800 (PST) In-Reply-To: <20130222201110.0a9e715c@capac> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2607:f8b0:4001:c02::22a 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:15806 Archived-At: On 23 February 2013 07:11, David Pirotte wrote: > Hi Daniel, > > thanks for your answer, but where i understand a strict name space will lead to > merging the generic(s) from/with the ones that comes from the modules you are > importing [as opposed to a general 'goops' name space], i disagree that this would be > a 'pre limitation' that provides a proper handling of the problem we are talking > about. Right, I had misread part of your initial message by focusing on the lack of a superclass. However, other comments still stand. Indeed it would not pose any namespacing issues in this way that you clarify. However, by not declaring a base module with a superclass in it you are needless complicating interaction with this set of modules. > >> Note that is a superclass of , so these are >> already generic functions. > > great, so the interface is defined, right? : (eq? (@ (mg-1) dialog) : (@ (mg-2) dialog)) : => : #f There is no *common* interface defined. These modules merely provide interfaces with the same names. Both of the above bindings are generics, yes, but they are not the same generic because you have not taken care to share one generic with the other module. This is the root of your problems. A generic is a generic, and can have multiple methods defined on it, yes. But scoping concerns must absolutely prevent automagically assuming that a method in mg-2 should be added to a generic in mg-1. mg-2 must explicitly import that generic if it wants to use it, otherwise you get two. Once you get two distinct generics you begin to have the problems you see. You later suggest to import multiple modules and use merge-generics, but that is highly impractical for a user and yourself. By doing so you also risk subtle bugs hiding amongst yours and user modules. Consider a user that only imports mg-2, but some how ends up receiving a . They will not be able to operate on that object without subsequently importing mg-1 and taking care to merge the generics. >> In your example the two classes share a common interface, but this >> interface is never defined anywhere. > > you just said above that it is, at least for accessors: No, the common interface is not *defined* anywhere. They have similar yet distinct interfaces. Other than failure to use a superclass and share generics from a common base module, your real problem with mg-4 lies in the failure to re-export the binding of dialog. Also, merge-generics is not required there since it only applies to duplicate imports. -- mg-4.scm: (define-module (mg-4) :use-module (oop goops) :use-module (mg-1) :export ( make-widget-b mg4/letstry) :re-export (dialog)) (define-class () (dialog #:accessor dialog #:init-keyword #:dialog #:init-value #f)) (define (make-widget-b) (make #:dialog 'dialog-b)) (define (mg4/letstry) (pk "widget-a:" (dialog (make-widget-a))) (pk "widget-b:" (dialog (make-widget-b)))) -- > i am also defending the idea > that it should always automatically create a generic function [for methods as well] > if none exists. Methods are always for generic functions. They operate no other way. > >> So if I have code that wants to work with any widget, which module should be >> imported to get the canonical interface definition? > > the canonical definition comes from the first imported module that [also] defines > the generic: this is what occurs in the mg-3.scm example, and that actually works > fine, as you know. You are talking about merge-generics, I am talking about a publicly defined common interface. These are not the same. As I mention earlier, what should a user import when they want accessors for all widgets? With your example, they will have to specifically import every widget-X module *and merge-generics* just to get at a common enough interface. With a base module making the common interface explicit, there is only one module to import and you can handle widgets of any class. > however in the mg-4 example, it does not, which i think is an implementation > problem: since i am asking guile to merge... it should import mg-1 and merge its own > generics with the imported ones. there is no reason, and certainly not the name > space conservativness, why this is not properly implemented in guile. See above. Your issues are trivially avoided by using a superclass, which is sound design practice anyway. Within a family of modules, using merge-generics immediately signals the presence of design issues. Regards