This is the mail archive of the guile@cygnus.com mailing list for the guile project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Any examples of modules using GOOPS?


Marius Vollmer <mvo@zagadka.ping.de> writes:

> I like to take a few issues with your argumentation below.  If you
> don't feel like discussing this, that's fine.  I haven't even looked
> at the code yet.

It is of course good to discuss these things as early as possible.

> ?  If that is the case, I think the parens should be kept, because the
> real definition is:
> 
>     (defclass NAME (BASE ...)
>       (SLOT ...)
>       OPTION ...)
> 
> Even if there are no options now, there will be in the future,
> especially when we have a MOP.

The code has options and a MOP.

The syntax is

  (define-class NAME (SUPER ...) SLOT ... CLASS-OPTION ...)

Since

  SLOT ::= SYMBOL | (SYMBOL SLOT-OPTION ...)
  CLASS-OPTION ::= KEYWORD VALUE

it is unambiguous where the options start.  (One could even allow
intermixed slot definitions and options.)

I would like the syntax to be as simple as possible.  99% of the users
won't use class options, so it's really a pity to make those 99% have
to type a seemingly superfluous pair of parenthesis, especially when
they in fact *are* superfluous.  ;-)

> > #:initform is passed an expression which will be evaluated in the
> > environment of the class every time an instance is initialized.
> > This requires the implementation to 1. store a pointer to the class
> > environment, and 2. use `local-eval'.
> 
> Why is that?  Can't you just construct a init-thunk from the
> init-form?

Yes, you're right that this is possible.  However, this means that the
define-class macro needs to scan through all slot options, looking for
#:initform.  In the original STKlos implementation this was avoided by
postponing the creation of the closure until the getters-and-setters
computation inside the MOP.

However, in my efforts to make GOOPS more Schemey, I decided to let
the define-class macro expand into multiple defines, defining all
getters, setters, accessors, and, the class.  This makes it necessary
to scan the slot options anyway, so, looking for #:initform won't add
much extra cost.

This means that the arguments in my previous letter were weak.  (I'm
not completely up-to-date with GOOPS right now, sorry.)

> I think the CLOS behaviour is entirely implementable with standard
> lexical closures.  Very Schemey, in fact.  :init-form could be an
> abbreviation for your :init-thunk, where you give just the body.

I agree that it is implementable, but I question whether it is
Schemey.  Now, I should say that I'm not arguing about something
definite here.  It's more about taste and feeling.

The only time you normally see a closure being created around an
expression is in lambda (and define).  I think it is nice to make it
explicit in the code when you're creating a closure.

I introduced #:init because, normally, the init value is constant for
all instances, and in these cases it is most convenient if the
expression is evaluated once and for all at the site of the class
definition.  (It will also be more efficient in the interpreter, since
it isn't necessary to call apply for each slot.)

Note that #:init can be used in most cases where #:init-form is used
in STklos code.

In the few cases where you want to evaluate a closure for every
instance initialization, it's no big trouble to write the lambda
expression.

Also, I would like to have a simple rule for evaluation of slot-option
arguments.  Currently it is: All slot-option arguments are evaluated
at class-definition, except for getter, setter, and accessor names.
I think it's nice not to have to add #:init-form to those exceptions.

/mdj