guile-devel
[Top][All Lists]
Advanced

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

Re: New module system option :duplicates


From: Greg Troxel
Subject: Re: New module system option :duplicates
Date: 08 Mar 2003 09:38:57 -0500
User-agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.2

   That's what I just thought about too.  i.e. I'd guess that merging
   (open <file>) and (open <gripper>) would be just fine, but what about
   merging (open <file>) from module-1 with (open <file>) from module-2?
   Personally, I'd probably want to see an error in the latter case, but
   the question is in general, how would a "conflict" be defined?

If one thinks of all procedures as generics, then adding a method with
specializers that does not conflict is different from one that does
conflict.  But, the definition of conflict has two interesting
wrinkles:

  If one defines two methods, and one is more specialized than the
  other, but they are not disjoint, then the second definition will
  modify the result of using the first definitions generic function.
  For example:
    guile> (use-modules (oop goops))
    guile> (define-method (f (a <number>)) (+ a 1))
    guile> (f 1)
    2
    guile> (f 1.0)
    2.0
    guile> (define-method (f (a <integer>)) (+ a 2))
    guile> (f 1)
    3
    guile> (f 1.0)
    2.0
  Here, the methods do not 'conflict' in the sense of specifying
  different behaviors for the same provided specializers, but they are
  not disjoint either.

The proposal of an extended generic which finds methods from several
generics seems nice.  In the case that Mikael talked about, it seemed
the methods were all disjoint, so this works cleanly.  With
non-disjoint methods, perhaps an error should be signalled, or this
should be treated the same way as an export-export conflict.

Mikael's proposal of merging methods but not modifying values also
avoids another nasty issue:

  define-generic overwrites previous generic function values and
  non-procedure values, but not previous simple procedures.  So if
  either module uses define-generic, there is no way to merge the
  values into a single generic function.

All that said, it troubles me somewhat to have a new extended-generic
type.  Is it possible to just

  construct a new generic function

  add all the methods from each of the generics in the modules to the
  new generic function

and be done with special treatment?

Finally, I did not understand

  This implies that x in (math 2D-vectors) can see the methods of x in
  (my-module) and vice versa, while x in (math 2D-vectors) doesn't see
  the methods of x in (math 3D-vectors), thus preserving modularity.

Why would any method in (math 2D-vectors), or use of gf x, ever see
methods defined in my-module?  This seems like a clear modularity
violation, but I suspect I'm confused.

I think a core underlying issue is that define-method is a mutator on
the gf (perhaps it needs a ! :-):

  guile> f
  #<<generic> f (2)>
  guile> (generic-function-methods f)
  (#<<method> (<integer>) 80902b0> #<<method> (<number>) 8090310>)
  guile> (define-method (f (a <complex>)) (+ a 3))
  guile> (generic-function-methods f)             
  (#<<method> (<complex>) 80905a0> #<<method> (<integer>) 80902b0>
  #<<method> (<number>) 8090310>)

So, perhaps _always_ exporting generic functions by creating a new
generic and adding the methods is the proper path.  Normally modules
only export procedures, and they are immutable - I would expect
calling set! on the exported name to rebind the name in the using
module, and not affect the used module.  Exporting variables of course
can lead to mutation, but this is far clearer and less likely to lead
to unexpected trouble.

        Greg Troxel <address@hidden>




reply via email to

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