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: Jerome.Vouillon@inria.fr (Jerome Vouillon)
Cc: caml-list@inria.fr (OCAML)
Subject: Re: subtyping and inheritance
Date: Mon, 18 Jan 1999 22:18:40 +0100 (MET)	[thread overview]
Message-ID: <199901182118.WAA09639@miss.wu-wien.ac.at> (raw)
In-Reply-To: <19990118205542.06048@pauillac.inria.fr> from "Jerome Vouillon" at Jan 18, 99 08:55:42 pm

Hello,

> So, you want to be able to select a method depending on two
> objets. This is not directly possible, but you can encode it using two
> successive method calls:
> 
>     class type symbol_t = object
>       method x : int
>     end and terminal_t = object
>       inherit symbol_t
>       method y : int
>     end;;
>     class symbol x = object (self : 'a)
>       method x = x
> 
>       method compare (other : symbol) =
>         other#compare_with_symbol (self :> symbol_t)
>       method compare_with_symbol other = self#x = other#x
>       method compare_with_terminal (other : terminal_t) = false
>     end;;
>     class terminal x y = object (self)
>       inherit symbol x
>       method y = y
> 
>       method compare (other : symbol) =
>         other#compare_with_terminal (self :> terminal_t)
>       method compare_with_symbol other = false
>       method compare_with_terminal other =
>         (self#x = other#x) && (self#y = other#y)
>     end;;

To solve this problem I've done something similar (defined an extra
comparison method for symbols in class symbol) - I don't know of any
better means. But as is obvious: this workaround unfortunately does not
really exhibit the virtues of code reuse...

Even worse (taking your example): if I add another kind of symbol (say,
a nonterminal symbol), I would have to write a comparison method for
each kind of symbol already in the class hierarchie. But not enough: I
would have to change all of the older classes to recognize the new one!
This all, although many of the comparison functions are (syntactically)
the same and would only have to be instantiated with another type in
the new class.

> > But "terminal" *has* a method "y"!!! The problem is that "compare" has
> > been instantiated in "symbol" with "symbol" as type parameter to "ord".
> > Thus, the method "compare" has type "symbol -> bool".  The compiler still
> > believes that "compare" should have this type, but wrongly takes the
> > type information provided in the declaration of "compare" in "terminal",
> > which declares "compare" to be of type "terminal -> bool". This results
> > in the incorrect error message that "terminal" has no method "y".
> 
> Here is an explanation of this error message. Just before typing the
> method "compare" in class "terminal", we know that its type must be
> "symbol -> bool". However, we don't know anything about the type
> "terminal" yet (this type will have to be a suitable instance of the
> type of self, but this can only be checked once the whole class body
> is typed). Then, the type constraint "(other : terminal)" tells the
> compiler that the type "terminal" must be the same as the type of the
> argument of the method, that is "symbol". This will not be possible,
> but the compiler does not know it yet. Then, the type checking fails
> because "other", of type "symbol" has no method "y".
> 
> I will try to provide a better error message.

Seems that my explanation was not totally wrong (I have not seen the code
yet). I didn't know that the compiler would have to know the whole body
of the class before it can emit the correct message. I (wrongly) believed
that the compiler incrementally extends the interface while interpreting
the type information of the methods. Hm, probably a stupid idea...

I am not sure, but I can imagine it's a bit tricky to delay the
message. The compiler knows that something is wrong, but might need
exactly the (inconsistent) type information from the incorrect part to
interpret the rest of the methods in the class definition. It would
have to ignore the resulting incorrectness of those methods without
"forgetting" the true source of the error.

[snip second error message]

> Here is how you should understand this error message.  The method
> "compare" in an object of class "terminal" has type "terminal ->
> bool". Therefore, it can make use of the method "terminal_order" of
> its argument. Thus, as the type "symbol" has no method
> "terminal_order", the method "compare" cannot be given the type
> "symbol -> bool". Hence, finally, the type "terminal" is not a subtype
> of type "symbol", and the coercion is not possible.

Ah! That's the way the compiler concludes! When I first encountered this
message, I always wondered what was wrong about method "terminal_order"
- I didn't look to deeply into the rest of the output...

It should take me some time to see that it's method "compare" that
causes the trouble - by invoking methods that do not exist in "symbol"
but are required there - yet I didn't come to this last conclusion.

If the compiler emits a huge bunch of class interfaces in error messages
the human user can often be overcharged with interpreting this amount
of information... ;-)

Best regards,
Markus

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




  reply	other threads:[~1999-01-19 16:55 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1999-01-11 18:52 Markus Mottl
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 [this message]
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=199901182118.WAA09639@miss.wu-wien.ac.at \
    --to=mottl@miss.wu-wien.ac.at \
    --cc=Jerome.Vouillon@inria.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