Version française
Home     About     Download     Resources     Contact us    
Browse thread
[Caml-list] A question about classes and multiple inheritance
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Jacques Garrigue <garrigue@k...>
Subject: Re: [Caml-list] A question about classes and multiple inheritance
From: Frederic Tronel <Frederic.Tronel@inrialpes.fr>

> I have the following problem.
> If I define two classes like this:
> 
> class virtual behaviorSpecElement = object (this) 
> 
>     /* To be refined by subclasses */
>     method virtual localPreBehavior : (string,string) Hashtbl.t  ->
> specBehavior
>     /* Defined by  specElement */	
>     method virtual preBehavior  : (string,string) Hashtbl.t stack ->
> specBehavior
> end
> and
> virtual ['a] specElement =
> 
>   inherit behaviorSpecElement as super
>  
>   fun (synchroAccounting : 'a) ->
>   object (this)  
> 	<snip> ....
> 	method preBehavior bindings =
>       		let binding = bindings#top in
>       		let myPre = this#localPreBehavior binding in
>       		bindings#popSP ;
>       		let superPre = super#preBehavior bindings in
>       		bindings#pushSP ;
> 	<snip> ...
>   end

You cannot inherit outside an object, so something is wrong in the
above code. I suppose you just meant inherit inside the object.

> Is there a way to solve this problem ?
> "super" must be dynamically resolved at run-time, is it compatible with
> multiple inheritance ?

By definition super is statically resolved, and self is dynamically
resolved. This is actually the point. In ocaml you don't get two
independent hierarchies of methods with multiple inheritance: methods
with same name are merged, taking implementation from last one.
The only way to get dynamic resolution is to go through self ("this").

But this seems to be what you are doing anyway, calling
this#localPreBehaviour. So what's the point in calling
super#preBehaviour? You certainly don't want to call yourself.
There's certainly some way to do what you are trying to do, but we
have to know what you want.

If what you want is to call a localPreBehaviour for each superclass,
then it's difficult, because there's no real support for mixins, and
there's no keyword to say that a method should not appear in
subclasses.

A way to do it is:

class virtual specRecursor =
  object (this)  
        method private virtual localPreBehaviour : ...
        method private virtual superPreBehaviour : ...
	method preBehavior bindings =
      		let binding = bindings#top in
      		let myPre = this#localPreBehavior binding in
      		bindings#popSP ;
      		let superPre = this#superPreBehavior bindings in
      		bindings#pushSP ;
  end

And use it:

class child :
  object
    <declare all methods except localPreBehaviour and superPreBehaviour>
  end =
  object (this)
    inherit parent as super
    method private localPreBehaviour bindings = ...
    method private superPreBehaviour = super#preBehaviour
    inherit specRecursor
  end

The idea is to use localPreBehaviour and superPreBehaviour as
parameters to specElement, making them local to the class, and hide
them from descendants, so that they cannot be modified.

I think that some extension to the current object system might help in
such cases. Like a second abbreviation for self, so that we can bind
statically to its methods, and don't need all this hiding.

Currently it is simpler to redefine explicitly preBehaviour every time.

let preBehavior ~local ~super bindings =
  let binding = bindings#top in
  let myPre = local binding in
  bindings#popSP ;
  let superPre = super bindings in
  bindings#pushSP

class child =
  object (this)
    inherit parent as super
    method private localPreBehaviour bindings = ...
    method preBehavior =
      preBehaviour ~super:super#preBehaviour ~local:this#localPreBehaviour
  end


Jacques Garrigue
-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners