caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Jacques Garrigue <garrigue@kurims.kyoto-u.ac.jp>
To: Frederic.Tronel@inrialpes.fr
Cc: caml-list@inria.fr
Subject: Re: [Caml-list] A question about classes and multiple inheritance
Date: Thu, 23 May 2002 18:52:48 +0900	[thread overview]
Message-ID: <20020523185248D.garrigue@kurims.kyoto-u.ac.jp> (raw)
In-Reply-To: <3CECAD94.69976221@inrialpes.fr>

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


  reply	other threads:[~2002-05-23  9:52 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-05-23  8:51 Frederic Tronel
2002-05-23  9:52 ` Jacques Garrigue [this message]
2002-05-23 11:04   ` Frederic Tronel
2002-05-24  0:29     ` Jacques Garrigue

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20020523185248D.garrigue@kurims.kyoto-u.ac.jp \
    --to=garrigue@kurims.kyoto-u.ac.jp \
    --cc=Frederic.Tronel@inrialpes.fr \
    --cc=caml-list@inria.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).