Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!swrinde!zaphod.mps.ohio-state.edu!sdd.hp.com!decwrl!shelby!neon!michaelg From: michaelg@Neon.Stanford.EDU (Michael Greenwald) Newsgroups: comp.lang.lisp Subject: Re: (not (equalp 'flet objects)) Message-ID: <1990Aug15.221853.12292@Neon.Stanford.EDU> Date: 15 Aug 90 22:18:53 GMT References: <1990Aug4.001913.22597@Neon.Stanford.EDU> <1990Aug13.201712.19721@Neon.Stanford.EDU> <3201@skye.ed.ac.uk> <1990Aug14.235816.11255@Neon.Stanford.EDU> Organization: Computer Science Department, Stanford University Lines: 103 gumby@Cygnus.COM (David Vinayak Wallace) writes: > Date: Tue, 14 Aug 90 23:58:16 GMT > From: michaelg@Neon.Stanford.EDU (Michael Greenwald) > jeff@aiai.ed.ac.uk (Jeff Dalton) writes: > >If there was better support for it in Common Lisp implementations, > >I might want to write "modules" like this (perhaps with the aid of > >some macros): > > (let (...) ; private variables > > (labels (...) ; private functions > > (defun ...) ; public functions > > ... )) > >So the "parent" might be quite large. > It's possible I'm not understanding you clearly. Why isn't what you > describe simply a single instance of a class? The private variables > are slots, the private functions are GENERIC-LABELS (or in pre-CLOS > flavors, DEFUN-IN-FLAVOR's) and the DEFUNs are DEFMETHODs? It was > certainly the case that you did not have to recompile the > DEFUN-IN-FLAVORs every time you recompiled a defmethod. I assume > (hope) that GENERIC-LABELS is similar. >Because the generic functions would have to recieve the single >instance of an argument, while under Jeff's scheme (and in Scheme) the >sole discriminator is the name. Of course in scheme, unlike cl, the >defun-ed/define-ed names would not be apparent outside the bounding >let. I thought of that, but I decided "Nah, he couldn't have meant that" since he said "(perhaps with the aid of some macros)". Since there's a single instance of this class, it wouldn't be hard to write the macrology he wants like (defmacro (&rest arglist) `( *single-instance* . ,arglist)) so he must want to do something more complicated that I don't understand. With this macrology is the sole discriminator. In Scheme you're doing the same thing - the name is bound to a closure: the function and the environment (in our case, the instance). In Scheme the language does it under the covers, in CL you have to do it explicitly. Here's the outline of what I mean in SCLese (i.e. flavors, and not CLOS. I assume that the translation is straightforward). (DEFFLAVOR is DEFCLASS, DEFUN-IN-FLAVOR I think is like GENERIC-LABELS, DEFMETHOD is the same in CLOS and New Flavors, and STRING-APPEND is sort of this: (DEFUN STRING-APPEND (STRING1 &REST STRINGS) (IF STRINGS (CONCATENATE 'STRING (STRING STRING1) (APPLY #'STRING-APPEND STRINGS)) (STRING STRING1))) ) ;; inside the *module-package* (defun cons-name (type name) (intern (concatenate (string type) *module-separator* name) *module-package*)) (defmacro defmodule (name bindings) `(progn (flavor:defflavor ,name ,bindings ()) (defvar ,(cons-name "INSTANCE" name) (make-instance ',name)))) (defmacro define-private-function ((f module) arglist &body body) `(flavor:defun-in-flavor (,f ,module) ,arglist ,@body)) (defmacro define-public-function ((f module) arglist &body body) `(progn (defmethod (,(cons-name module f) ,module) ,arglist ,@body) ,(list 'defmacro f '(&rest arglist) `(apply #',(cons-name module f) ,(cons-name "INSTANCE" module) arglist)))) You can do the same thing passing around an explicit environment instead of the instance, but accessing slots is probably faster than any home grown environment you'd construct. It's ugly, but I think it's what he wants. But my real question (which was elided in your response) was: Why is this such a problem anyway? In PASCAL (the original example?) you'd have to recompile the parent in order to determine the environment for the public (or private) function. Why is this such a terrible penalty in CL? (Are there Scheme implementations where the compiler wouldn't recompile the whole lexical environment?). In short, classes provide a way to do modules without recompiling. But is the requirement of recompilation of the whole module the only "lack of support" in CL? If so, why is this more of a problem in CL than in other languages? If this isn't the only problem you were alluding to, then I missed (or misunderstood) your (Jeff's) original complaint.