[plt-scheme] generics / modules
I've encountered the same problem.
My first approach was to make a `generics' module that simply defined
every generic function and have all the other modules include it. It was an
ok stopgap measure, but it obviously doesn't scale.
My second approach was to factor the code such that all methods to a
generic function could be defined within a single module (which exports
the generic). This, too, has obvious problems, but it turned out to work
ok in practice.
I think for `small' generic functions, that is, ones with one or two methods,
that the second approach is appropriate. I like the `interface' idea for the
generic functions that have lots of methods.
I don't know of a canonical solution.
On 10/20/05, Yoav Goldberg <yoav.goldberg at gmail.com> wrote:
> Another code organization question, this time really not music specific.
>
> I use multimethods / generics quite a bit in my code (I use my own
> lightweight system, but the question applies to systems like
> CLOS/swindle as well).
>
> The problem I have is with the use of both generics and the module
> system - where do I put the generic functions definition (which is the
> actual function)?
>
> In what I came up with there are "interface" modules, that contain
> (almost) only generic function definitions. These are grouped by type,
> for example I have the module
> "interfaces/arithmetics.scm" which defines the generics
> "add,sub,mul,div", as well as the comparison operators, and the min
> and max functions. Then I have the "interfaces/values.scm" module,
> which has a function named "get-value", and so on.
>
> When I want to implement some or part of the interface, I create a
> module that requires it, and adds methods to the functions defined in
> the interface.
> For example
> (module pitch-arithmetics mzscheme
> (require "../interfaces/arithmetics.scm")
> (def-method add (pitch? interval?)
> (lambda (p i) ...)
> ...))
> Note that this module does not provide anything.
>
> When one want to actually do pitch arithmetics, he needs to require
> both "interfaces/arithmetics" and "pitch-arithmetics".
>
> I am forced to do it this way, because if two modules implement the
> same interface and I want to require both of them, I will have to
> prefix one of them to avoid the name clash.. but I actually want the
> name clash to happen, so I just don't provide anything.
>
> So, my first problem is that multiple-require I'm forced to do.
>
> My second problem is with generic functions that are not as widespread
> or as easy to categorize as "arithmetics". For example, I implement
> various "time" objects (time-point, time-interval, duration). And
> there is a functionality which is required for all of them
> (number-of-wholes <time>), and a recognizer (time? <time>) that should
> work on all of them. Where do I put these two functions? Of course, I
> create another interface module - "time-interface", which defines
> them. And now, do I put this file under "interfaces/time-interface",
> or under "time/time-interface"? Where is it more natural? Where will
> it be most easily found? (remember, I can't just put it anywhere I
> want and have the "time" module provide it - it needs to be
> specifically required by the user, and he needs to find it.. I can
> create another module, called "all-interfaces", and let someone
> require only that, but I feel this is (a) wastefull (b) a mess. )
>
> Ok, so that was my second problem - where to put these very little
> interfaces that are used just once or twice anyhow.
>
> Now for the third, which is an elaboration of the second. I had a
> "number-of-wholes" generic function, defined in "time-interface". Now
> there is another type, completely unrelated to time, that also needs
> that "number-of-wholes" method. It is already defined in the
> "time-interface". Will users of the other type need to include
> "time-interface" in order to use the new type? I can't just add
> another interface, because then I can't require both (conflicting
> names), so I will have to change the place of the definition of
> "number-of-wholes". This is problematic - I have quite a bit of code
> that already require "time-interface" - this code will have to be
> changed. Also, I have no idea where to put this "number-of-wholes"
> definition now...
>
>
> Did anyone else encounter similar problems? Are there any well known solutions?
>
> Thanks,
>
> Yoav
> _________________________________________________
> For list-related administrative tasks:
> http://list.cs.brown.edu/mailman/listinfo/plt-scheme
>
--
~jrm