Mailing list for all users of the OCaml language and system.
 help / color / mirror / Atom feed
From: Markus Mottl <mottl@miss.wu-wien.ac.at>
To: caml-list@inria.fr (OCAML)
Subject: subtyping and inheritance
Date: Mon, 11 Jan 1999 19:52:57 +0100 (MET)	[thread overview]
Message-ID: <199901111852.TAA00822@miss.wu-wien.ac.at> (raw)

Hello again,

this time a question about inheritance and subtyping...
Let's consider the following code snippet:

---------------------------------------------------------------------------
class foo =
object (self:'self)
  method x = "x"
  method eq (other:'self) = if self#x = other#x then true else false
end

class bar =
object
  inherit foo
  method y = "y"
end

let f = new foo
and b = new bar
;;

print_string (string_of_bool (f #eq f)); print_newline ();
print_string (string_of_bool (b #eq b)); print_newline ();
---------------------------------------------------------------------------

So far no problem. Class "bar" inherits from "foo" and adds a method.
The program will print out two times "true", because objects of type
"foo" can be tested for equivalence within their class and objects of type
"bar" as well.

But now, I would really like to compare objects of type "foo" with
objects of type "bar" as in:

---------------------------------------------------------------------------
print_string (string_of_bool (f #eq (b :> foo))); print_newline ();
---------------------------------------------------------------------------

This is, of course, not possible, because "bar" is not a subtype of
"foo" and thus, cannot be coerced to "foo".

But "bar" inherits everything from "foo" so I think it would be safe
to call methods ** as they are defined in "foo" **. I think the problem
occurs because of the following rule taken from the OCAML manual:

  Only the last definition of a method is kept: the redefinition in a
  subclass of a method that was visible in the parent class overrides
  the definition in the parent class.

This rule prohibits that definitions as they appear in the parent
class may be reused in case that an object of a subclass (in terms of
inheritance, not subtyping!) shall be seen from the parent's "point
of view". In the upper case, method "eq" is automatically redefined,
because it has the type "'self" in its signature.  Actually, *this*
is the problem, not the additional method "y" as is stated at the end
of the error message generated on the last "print_string...".

My specific problem is: I have a program with classes for "terminal"
and "nonterminal" symbols. Both inherit from a base class "symbol". The
symbol class inherits from a class "ord", which defines a virtual method
"compare". This allows me to compare terminals with terminals and
nonterminals with nonterminals, but it also allows comparison between
symbols (all three classes redefine "compare").

Look at this graph:

         ord                ->  defines virtual method "compare"
          |
        symbol              ->  redefines "compare"
       /      \
   terminal  nonterminal    ->  both redefine "compare"

But the problem is: I will never be able to compare terminals and
nonterminals with each other, because the appropriate comparison method
as defined in "symbol" has been "forgotten" - it is redefined in all
child classes. Thus, I am not able to coerce them to "symbol".

I have worked around this with the following inheritance scheme:

    ---- ord -----          ->  defines virtual method "compare"
    |            |
    |   symbol   |          ->  has a method "compare_symbol"
    |  /      \  |
   terminal  nonterminal    ->  both redefine "compare"

Although it is now possible to coerce terminals and nonterminals
to symbols and have them thus compared via "compare_symbol", I am not
content with this scheme: I would really like to have all methods from
"ord" in "symbol", which all make use of the virtual "compare" method.

I am neither sure whether I am overlooking some clever trick to get the
result I want, nor whether a change in the handling of coercions ("memory"
for methods of parent classes) is really safe. But at the moment I cannot
think of any way to circumvent type safety. Comments on this welcome!

Best regards,
Markus

-- 
Markus Mottl, mottl@miss.wu-wien.ac.at, http://miss.wu-wien.ac.at/~mottl




             reply	other threads:[~1999-01-12  9:45 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1999-01-11 18:52 Markus Mottl [this message]
1999-01-15 15:02 ` Jerome Vouillon
1999-01-15 17:37   ` Markus Mottl
1999-01-18 19:55     ` Jerome Vouillon
1999-01-18 21:18       ` Markus Mottl
1999-01-20 11:50         ` Hendrik Tews
1999-01-25  0:08           ` Markus Mottl
1999-01-25 15:06             ` Musings on Obj.magic (Was: subtyping and inheritance) David Monniaux
1999-01-27 14:18             ` subtyping and inheritance Jerome Vouillon
1999-01-27 14:45               ` Markus Mottl
1999-01-28 19:40               ` Hendrik Tews
1999-01-27 14:28           ` Jerome Vouillon
1999-04-15 12:18 Giuseppe Castagna
1999-04-15 16:02 ` Markus Mottl
1999-04-20 12:38 ` Didier Remy
1999-04-20 15:06   ` Giuseppe Castagna
1999-04-21 12:18     ` Didier Remy

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=199901111852.TAA00822@miss.wu-wien.ac.at \
    --to=mottl@miss.wu-wien.ac.at \
    --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