[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: macros, procedure->macro

From: Dirk Herrmann
Subject: Re: macros, procedure->macro
Date: Wed, 10 Jul 2002 23:54:18 +0200 (CEST)

On 7 Jul 2002, Marius Vollmer wrote:

> We need to restrict this redefining behavior of 'define-class' et all
> to the top-level.  Local class definitions should not redefine classes
> outside of their scope (that would lead to a funny version of dynamic
> scoping of classes, eew), and redefinitions directly in one scope
> should be an error, just like any other definitions.
> For example,
>     (let ((foo (find-class "<moo>")))
>       (define-class foo ...)
>       ...)
> should not try to redefine the class that is the value of the location
> bound to foo by the let.  It should simply shadow the outer foo.

Just a side note:  define-class cannot be used other than on top-level.
The reason is, that define-class will define generic functions for
accessors that are not defined yet.  Getting this right in non-top-level
scopes seems quite difficult (if not impossible) to do cleanly.

> Redefinitions on the top-level do make sense and can be supported by a
> normal macro via explicit module manipulations, i.e.
>     (define-class foo ...)
>     =>
>     (module-define-class (current-module) 'foo ...)
> with
>     (define (module-define-class mod sym ...)
>       (let* ((var (module-ensure-local-variable! mod 'foo))
>              (class (make-class ...)))
>         (if (variable-bound? var)
>             (redefine-class (variable-ref var) class))
>         (variable-set! var class)))

I am currently changing the definition of define-class accordingly.
However, I am not sure which of the following solutions to choose:

* use a helper function module-define-class.  This would have to be
  exported.  And, it could not be used like define-class, since you
  would not be able to pass an empty combination for an empty list
  of supers:  (module-define-class some-module some-name () ...)
  would not be allowed, since you would have to quote the ().

* use a helper macro module-define-class.  This would have to be
  exported as syntax.

* change the expanded code of define-class to hold all necessary
  instructions to do the module manipulations.  In this case, the
  mmacro would return the following:

     ;; define accessors
     ,@(pre-definitions (slots exp) env)
     ;; update the current-module
     (let ((class (class ,@(cddr exp) #:name ',name)))
       (let* ((var (module-ensure-local-variable!
                   (current-module) ',name))
              (old (and (variable-bound? var)
                   (variable-ref var))))
         (if (and old
                  (is-a? old <class>)
                  (memq <object> (class-precedence-list old)))
             (variable-set! var (class-redefinition old class))
             (variable-set! var class))))))))))))

Which solution should be used?  I will try to update define-generic and
define-accessor accordingly.

Best regards,
Dirk Herrmann

reply via email to

[Prev in Thread] Current Thread [Next in Thread]