Version française
Home     About     Download     Resources     Contact us    
Browse thread
OO programming
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Dirk Thierbach <dthierbach@g...>
Subject: Re: [Caml-list] OO programming
On Thu, Feb 21, 2008 at 10:31:42AM +0100, Tiphaine Turpin wrote:
> After a few unsuccessfull tries with using the object oriented features 
> of ocaml, I have been looking for ways to write classes that have a 
> chance to typecheck. 

The way I handle this is the following:

> The usual problem is that objects refer to other objects, 

I avoid this as much as possible. Instead of "connecting" objects
to other objects, I "connect" an objects to "actions" (functions),
which may be closures that include other objects. The typical example
which has already been given is the observer-pattern, which I use
as follows:

class ['a] observer = 
object(self)
  val mutable actions = []
  method register action =
    actions <- action :: actions
  method notify (arg : 'a) = 
    List.iter (fun f -> f arg) actions
end;;

No class for subject needed. Many of the objects I use in the GUI layer 
just inherit from observer, and it's also handy if the action you want
doesn't refer to an explicit object in the OCaml layer (because the
state is kept in the external GUI layer)

If possible, I try to make each object as independently from the rest
of the world as I can (after all, grouping a related part of the world
state together is very central to OO), and then I "plug together" all
these objects at a higher level.

> those objects may refer back to objects referring to them, 

No problem with the above way of using "actions". 

> then objects refer to different objects, some of them having more
> methods than others (subtyping),

I also use objects as parameters, both for classes and functions.
That all works as it is intended, the type just collects any method
calls that are used in the parameter. The only disadvantage is that
a type error is then usually discovered only at the time when I "plug"
all these things together. That's somewhat annoying, and if I really
cannot figure out what's going on, introducing type declarations into
a few places usually helps.

> etc. and finally the programmer has to give a type to all those
> beautifull mutable fields that are not fully specified, or make them
> parametric.

That problem often goes away if these fields are initialized, or used
in a method (which can be annoying if the class is not yet completely
written, but you want to test the stuff you have so far).

And of course, I try to use as little mutable state as possible (after
all, it's a functional programming language :-)

Much more annoying is that one also has to give types to arguments in
methods that are unused (they are present make them compatible with
another class, which uses them; or they are required by the GUI
layer), and that OCaml has now way to seperate method/function
declaration and type declaration (unless one uses a mli file, which is
again inconvenient because it splits information that belongs together
into two complete different places). I'd really appreciate it if one
could just mix "val" type declcarations with "let" or "method" code
declarations.

> Of course, the resulting classes should be reusable, that is, one
> should be able to extend a collection of related classes
> simultaneously, such that the fields now have the relevant subtype
> instead of the type they had before.

Not sure what exactly you mean here. Could you give an example?

> The best guidelines that I found are in the following course from
> Didier Remy [...] For example if a class refer to a method provided
> by a related class, this way of writing them does not guarantee that
> the method is actually defined. Only when creating and linking the
> objects together will the type-checker reject the program, if for
> example, the method has been misspelled in one class. So for me this
> coding scheme has the drawback that it unplugs the type-checker and
> just call it at the end.

Yes, see above. You can use class types to get around this problem,
but if you keep the classes small, one can live with.

> For me the "ideal" use of objects would use mutually recursive
> classes with fields defined with a type referring to the name of the
> other class.

Ugh. No, thanks :-)

- Dirk