From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: Mikael Djurfeldt Newsgroups: gmane.lisp.guile.devel Subject: Re: where to put generics? Date: Mon, 14 Jul 2003 18:42:35 +0200 Sender: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Message-ID: References: <20030712103036.GB4329@lark> Reply-To: djurfeldt@nada.kth.se NNTP-Posting-Host: main.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: main.gmane.org 1058201050 27400 80.91.224.249 (14 Jul 2003 16:44:10 GMT) X-Complaints-To: usenet@main.gmane.org NNTP-Posting-Date: Mon, 14 Jul 2003 16:44:10 +0000 (UTC) Cc: djurfeldt@nada.kth.se Original-X-From: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Mon Jul 14 18:44:06 2003 Return-path: Original-Received: from monty-python.gnu.org ([199.232.76.173]) by main.gmane.org with esmtp (Exim 3.35 #1 (Debian)) id 19c6Pr-00073T-00 for ; Mon, 14 Jul 2003 18:43:07 +0200 Original-Received: from localhost ([127.0.0.1] helo=monty-python.gnu.org) by monty-python.gnu.org with esmtp (Exim 4.20) id 19c6Qe-0002EA-OY for guile-devel@m.gmane.org; Mon, 14 Jul 2003 12:43:56 -0400 Original-Received: from list by monty-python.gnu.org with tmda-scanned (Exim 4.20) id 19c6Pj-0000sJ-J9 for guile-devel@gnu.org; Mon, 14 Jul 2003 12:42:59 -0400 Original-Received: from mail by monty-python.gnu.org with spam-scanned (Exim 4.20) id 19c6Pf-0000jL-Q9 for guile-devel@gnu.org; Mon, 14 Jul 2003 12:42:56 -0400 Original-Received: from kvast.blakulla.net ([213.212.20.77]) by monty-python.gnu.org with esmtp (Exim 4.20) id 19c6PM-0008KZ-DL for guile-devel@gnu.org; Mon, 14 Jul 2003 12:42:36 -0400 Original-Received: from h45n1fls34o867.telia.com ([213.65.223.45] helo=witch) by kvast.blakulla.net with esmtp (Exim 3.36 #1 (Debian)) id 19c6PL-0006UG-00; Mon, 14 Jul 2003 18:42:35 +0200 Original-Received: from mdj by witch with local (Exim 3.35 #1 (Debian)) id 19c6PL-0000cw-00; Mon, 14 Jul 2003 18:42:35 +0200 Original-To: guile-devel@gnu.org In-Reply-To: <20030712103036.GB4329@lark> (Andy Wingo's message of "Sat, 12 Jul 2003 11:30:36 +0100") User-Agent: Gnus/5.1002 (Gnus v5.10.2) Emacs/21.3 (gnu/linux) X-BeenThere: guile-devel@gnu.org X-Mailman-Version: 2.1.2 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 Xref: main.gmane.org gmane.lisp.guile.devel:2626 X-Report-Spam: http://spam.gmane.org/gmane.lisp.guile.devel:2626 Andy Wingo writes: > I figured while I was emailing I could get something else off my chest > -- what is the best way for two modules that do not want to know about > each other to add methods to the same generic? The problem there is that > such a generic might not exist in the 'stock' top-level environment. The > generic would need to be created and then exported, but only one time -- > if both modules export generics, the generics from recent modules will > replace those from previous modules. > > So, if the generics are only exported once, where should they be put? > I'm hacking around this for the moment by putting them in the root > module, but that's not exactly an elegant solution. What's the thought > on this? Has anyone else had to deal with these issues in the past? Firstly, Gregor Kiczales, the author of CLOS, has discussed issues related to this in his paper "Issues In the Design and Specification of Class Libraries", OOPSLA92 (http://kvast.blakulla.net/mdj/kiczales92.pdf). It is a very elucidating read. The way to think about it is that a module is publishing an interface with certain functionality and a generic function can be used to provide part of this functionality. If one follows certain rules listed in his paper when extending generic functions, most problems will disappear. Secondly, I've made an attempt at another kind of solution. Let's assume that module A exports a generic foo which both modules B and C want to add methods to, but B don't want to be confused by C's methods and vice versa. You can then do this: (define-module (A) :export (foo)) (define-method (foo ...) ...) (1) (define-module (B) :use-module ((A) :prefix A:)) (define-extended-generic foo A:foo) (define-method (foo ...) ...) (2) and a similar code for module C. The extended generic function foo becomes a descendant of A:foo and A:foo becomes an ancestor of foo, but they are still distinct generic functions. Methods added to foo in module B will belong to foo only, but can be accessed from all descendants and ancestors. Conversely, any generic function can access the methods added to all of its descendants and ancestors. This means that module A can run methods from modules B and C, while B and C won't be able to access eachother's methods. The second operand of define-extended-generic can also be a list of generic functions. This can be used to "merge" generic functions from different modules. There is also a recent addition to the module system which can do this automagically. Search for "merge-generics" in the NEWS file. M _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://mail.gnu.org/mailman/listinfo/guile-devel