guile-devel
[Top][All Lists]
Advanced

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

Re: goops - accessors, methods and generics


From: Daniel Hartwig
Subject: Re: goops - accessors, methods and generics
Date: Sat, 23 Feb 2013 08:37:22 +0800

On 23 February 2013 07:11, David Pirotte <address@hidden> wrote:
> Hi Daniel,
>
> thanks for your answer, but where i understand a strict name space will lead 
> to
> merging the generic(s) from/with the ones that comes from the modules you are
> importing [as opposed to a general 'goops' name space], i disagree that this 
> would be
> a 'pre limitation' that provides a proper handling of the problem we are 
> talking
> about.

Right, I had misread part of your initial message by focusing on the
lack of a superclass.  However, other comments still stand.

Indeed it would not pose any namespacing issues in this way that you
clarify.  However, by not declaring a base module with a superclass in
it you are needless complicating interaction with this set of modules.

>
>> Note that <generic> is a superclass of <accessor>, so these are
>> already generic functions.
>
> great, so the interface is defined, right?

: (eq? (@ (mg-1) dialog)
:      (@ (mg-2) dialog))
: =>
: #f

There is no *common* interface defined.  These modules merely provide
interfaces with the same names.  Both of the above bindings are
generics, yes, but they are not the same generic because you have not
taken care to share one generic with the other module.  This is the
root of your problems.

A generic is a generic, and can have multiple methods defined on it,
yes.  But scoping concerns must absolutely prevent automagically
assuming that a method in mg-2 should be added to a generic in mg-1.
mg-2 must explicitly import that generic if it wants to use it,
otherwise you get two.  Once you get two distinct generics you begin
to have the problems you see.

You later suggest to import multiple modules and use merge-generics,
but that is highly impractical for a user and yourself.  By doing so
you also risk subtle bugs hiding amongst yours and user modules.

Consider a user that only imports mg-2, but some how ends up receiving
a <widget-a>.  They will not be able to operate on that object without
subsequently importing mg-1 and taking care to merge the generics.

>> In your example the two classes share a common interface, but this
>> interface is never defined anywhere.
>
> you just said above that it is, at least for accessors:

No, the common interface is not *defined* anywhere.  They have similar
yet distinct interfaces.

Other than failure to use a superclass and share generics from a
common base module, your real problem with mg-4 lies in the failure to
re-export the binding of dialog.  Also, merge-generics is not required
there since it only applies to duplicate imports.

-- mg-4.scm:
(define-module (mg-4)
  :use-module (oop goops)
  :use-module (mg-1)

  :export (<widget-b>
            make-widget-b
            mg4/letstry)

  :re-export (dialog))

(define-class <widget-b> ()
  (dialog #:accessor dialog #:init-keyword #:dialog #:init-value #f))

(define (make-widget-b)
  (make <widget-b> #:dialog 'dialog-b))

(define (mg4/letstry)
  (pk "widget-a:" (dialog (make-widget-a)))
  (pk "widget-b:" (dialog (make-widget-b))))
--

> i am also defending the idea
> that it should always automatically create a generic function [for methods as 
> well]
> if none exists.

Methods are always for generic functions.  They operate no other way.

>
>> So if I have code that wants to  work with any widget, which module should be
>> imported to get the canonical interface definition?
>
> the canonical definition comes from the first imported module that [also] 
> defines
> the generic: this is what occurs in the mg-3.scm example, and that actually 
> works
> fine, as you know.

You are talking about merge-generics, I am talking about a publicly
defined common interface.  These are not the same.  As I mention
earlier, what should a user import when they want accessors for all
widgets?  With your example, they will have to specifically import
every widget-X module *and merge-generics* just to get at a common
enough interface.

With a base module making the common interface explicit, there is only
one module to import and you can handle widgets of any class.

> however in the mg-4 example, it does not, which i think is an implementation
> problem: since i am asking guile to merge... it should import mg-1 and merge 
> its own
> generics with the imported ones. there is no reason, and certainly not the 
> name
> space conservativness, why this is not properly implemented in guile.

See above.

Your issues are trivially avoided by using a superclass, which is
sound design practice anyway.  Within a family of modules, using
merge-generics immediately signals the presence of design issues.

Regards



reply via email to

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