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: GOOPS todo Date: Sat, 19 Apr 2008 19:02:45 +0200 Message-ID: NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: ger.gmane.org 1208636520 19722 80.91.229.12 (19 Apr 2008 20:22:00 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sat, 19 Apr 2008 20:22:00 +0000 (UTC) To: guile-devel Original-X-From: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Sat Apr 19 22:22:35 2008 connect(): Connection refused Return-path: Envelope-to: guile-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1JnJZx-0003yz-8T for guile-devel@m.gmane.org; Sat, 19 Apr 2008 22:22:33 +0200 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1JnJZI-0000YN-3S for guile-devel@m.gmane.org; Sat, 19 Apr 2008 16:21:52 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1JnJZ7-0000Vd-JD for guile-devel@gnu.org; Sat, 19 Apr 2008 16:21:41 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1JnJZ6-0000Un-2N for guile-devel@gnu.org; Sat, 19 Apr 2008 16:21:41 -0400 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1JnJZ5-0000Uj-Pu for guile-devel@gnu.org; Sat, 19 Apr 2008 16:21:39 -0400 Original-Received: from a-sasl-fastnet.sasl.smtp.pobox.com ([207.106.133.19] helo=sasl.smtp.pobox.com) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1JnJZ5-0006T8-Mn for guile-devel@gnu.org; Sat, 19 Apr 2008 16:21:39 -0400 Original-Received: from localhost.localdomain (localhost [127.0.0.1]) by a-sasl-fastnet.sasl.smtp.pobox.com (Postfix) with ESMTP id 0988A479F; Sat, 19 Apr 2008 16:21:38 -0400 (EDT) Original-Received: from unquote (96.Red-83-44-188.dynamicIP.rima-tde.net [83.44.188.96]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by a-sasl-fastnet.sasl.smtp.pobox.com (Postfix) with ESMTP id 052AC479E; Sat, 19 Apr 2008 16:21:33 -0400 (EDT) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.0.60 (gnu/linux) X-detected-kernel: by monty-python.gnu.org: Solaris 10 (beta) X-BeenThere: guile-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Developers list for Guile, the GNU extensibility library" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Errors-To: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.lisp.guile.devel:7175 Archived-At: Hi all, Mikael has mentioned on a number of occasions that GOOPS has some unfinished pieces. I couldn't find any information on this in the workbook, so I decided to write down a summary of the things that I've seen. Please add to this list if you know of more things, or if I am mistaken or miss something fundamental. I'll be poking at some of these over time, but any help is appreciated! incompleteness * Slot access compilation in compute-getter-method / compute-setter-method assumes that slots are SCM objects, whereas if they are implemented as subclasses of they are raw machine words. * Generic application only works for instances of , or for instances of a couple of other specially blessed classes. This is because for these classes, the C code knows how the objects will be laid out in memory, and can access memory directly instead of using slot-ref. In general in GOOPS (and in MOPs in general) there is a tension between extensibility and efficiency; the former is expressed in protocols of generic functions, and the latter in invariants and possibilities for direct memory access. The evaluator really needs to be able to do direct memory access, if possible. So for that reason the existing bits of generic function dispatch that are wired into eval.c check instances of those blessed clases, via checks like (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC). This "direct memory access" also has repercussions in tail recursion; that if the code to dispatch a method can't bottom out in eval.c, we lose tail recursion. So, we need to add support for instances of subclasses of , without losing efficiency. Apparently there is some code for this, see goops.scm:apply-generic. * We have no :before or :after methods. I don't know if STKlos had these either. * GOOPS should define a with-accessors macro. cruft * define-method, if it finds that a variable is defined with its generic name, then verifies that the value is not #f, with the note "*fixme* Temporary hack for the current module system". This appears to be completely unnecessary. * use of the (apply append (map ...)) idiom instead of mapappend or the like in a few places * objects.[ch] seems to be an unnecessary abstraction, now that GOOPS is in the core. It purports to define procedures that deal in classes, metaclasses, generics, etc., but in fact very little of this code is used, AFAICT. documentation * What is an ? Seems to have to do with the module system's generics merging foo. * What is an ? What is the goal of set-object-procedure! ? * GOOPS reference should be folded into Guile's reference, as it is now part of Guile. * A description of the method dispatch process, including the optimizations, would be really, really helpful. The interfaces that a MOP provides are carefully coded around potential optimizations that are not expressed in the specification, and not immediately obvious (to me). So some understanding of this "negative specification" would really help when hacking on this code. * Possibly the worst section of Guile's manual: 5.15 Objects ============ -- Scheme Procedure: entity? obj -- C Function: scm_entity_p (obj) Return `#t' if OBJ is an entity. -- Scheme Procedure: operator? obj -- C Function: scm_operator_p (obj) Return `#t' if OBJ is an operator. -- Scheme Procedure: set-object-procedure! obj proc -- C Function: scm_set_object_procedure_x (obj, proc) Set the object procedure of OBJ to PROC. OBJ must be either an entity or an operator. -- Scheme Procedure: make-class-object metaclass layout -- C Function: scm_make_class_object (metaclass, layout) Create a new class object of class METACLASS, with the slot layout specified by LAYOUT. -- Scheme Procedure: make-subclass-object class layout -- C Function: scm_make_subclass_object (class, layout) Create a subclass object of CLASS, with the slot layout specified by LAYOUT. optimization possibilities * mutation of the method cache causes a full copy of the cache, so that it doesn't disturb other threads -- we should look to see what e.g. CLOS does about this * method cache code could be rewritten in C (dispatch.scm), although I have never had a problem with it -- it doesn't show up on my profiles. nastiness * method compilation (e.g. the process of going from a define-method to a procedure -- basically, making sure that next-method does the right thing) is hacky, involving manual manipulation of the data structure describing the procedure's environment, calling procedure-source, etc. Also, the procedure-source call means that you can't make a subr implement a method. I do not understand the comment in compile.scm about next-method inlining -- what does this mean? (Why isn't compile-method run at macro-expansion (e.g. define-method) time?) * GOOPS mucks around too much with the module system. Instead of having define-class expand out to a (begin ..) block in which getters, setters, and the class are all defined separately, (define-class () (bar #:getter bar)) actually mucks with the module system to define the `bar' getter generic. Similarly, if a getter was already defined but not a generic, GOOPS actually modifies that binding, replacing the original definition with the result of calling ensure-generic, potentially modifying imported bindings. * GOOPS uses procedure->memoizing-macro instead of define-macro. * Relatedly, define-class is only allowed at the top level. There is no reason for this, if the module system mucking is fixed to use normal macro expansion with the `begin' splice. * Classes store a pointer to their environment, for no reason. Regards, Andy -- http://wingolog.org/