Mailing list for all users of the OCaml language and system.
 help / color / mirror / Atom feed
From: Jacques Garrigue <garrigue@kurims.kyoto-u.ac.jp>
To: william.newman@airmail.net
Cc: caml-list@inria.fr
Subject: Re: [Caml-list] difficulties narrowing OO types
Date: Thu, 15 Nov 2001 10:05:57 +0900	[thread overview]
Message-ID: <20011115100557Y.garrigue@kurims.kyoto-u.ac.jp> (raw)
In-Reply-To: <20011114111708.A14071@rootless>

From: William Harold Newman <william.newman@airmail.net>

> OCaml seems generally reluctant to narrow OO types.
OCaml is reluctant to do anything unsafe.

> E.g., dynamically casting from a base class to a subclass is
> unsupported (though I've seen the hack to work around this in Jason
> Hickey's online introduction).
No surprise, this is unsafe. Work arounds are available, but they may
all fail at runtime. The technical reason for not having it as a
construct in the language is that checking casts for parametric
classes is much harder than for classes without parameters.

> And as far as I can tell, it's
> impossible for a method on a subclass to guarantee that it returns a
> narrower type than the method on the base class.

That's actually a quite different problem. Having a method in a
subclass return a narrower type is type-safe, and is allowed by OCaml
subtyping rules. Unfortunately, OCaml inheritance rules does not allow
it.

[Snipped lots of goods reason why one would want to narrow methods in
subclasses]

> If there really are systematic obstacles to narrowing OO types in
> OCaml, not just beginner confusion on my part, is there some deep
> reason? Perhaps because it causes problems with type inference? At
> first I thought it might be because it tends to be strongly correlated
> with typecase operations which miss the point of OO, but that doesn't
> explain why I can't narrow the return type of a subclass method.

You pointed it: type inference. Inferring class types is already
pretty complicated, it would become nightmarish if method types can
change with inheritance. Type inference is based on unification, which
doesn't play well with subtyping.

Since the problem is with inheritance, and not with subtyping, there
are workarounds to define such classes. Basically the idea is to keep
the type of self as a parameter to the class.

class ['a] base_t ~pos ~friends =
  object
    method pos : int = pos
    method friends : 'a list = friends
  end

class base = [base] base_t

class ['a] extended_t ~pos ~friends ~name =
  object
    inherit ['a] base_t ~pos ~friends
    method name : string = name
end

class extended = [extended] extended_t

Here are the types:
class ['a] base_t :
  pos:int ->
  friends:'a list -> object method friends : 'a list method pos : int end
class base : pos:int -> friends:base list -> [base] base_t
class ['a] extended_t :
  pos:int ->
  friends:'a list ->
  name:string ->
  object method friends : 'a list method name : string method pos : int end
class extended :
  pos:int -> friends:extended list -> name:string -> [extended] extended_t

The point is that extended is actually a subtype of base:
# let b = new base ~pos:1 ~friends:[(e : extended :> base)];;
val b : base = <obj>

Note that this only works as long as base has no contravariant
method. If base_t contained an add_friend : 'a -> unit method, then
subtyping would break.


It might be possible to add method narrowing in the language with a
special syntax, but again parametric classes are hard to handle.

Cheers,

Jacques Garrigue
-------------------
Bug reports: http://caml.inria.fr/bin/caml-bugs  FAQ: http://caml.inria.fr/FAQ/
To unsubscribe, mail caml-list-request@inria.fr  Archives: http://caml.inria.fr


  reply	other threads:[~2001-11-15  1:06 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2001-11-14 17:17 William Harold Newman
2001-11-15  1:05 ` Jacques Garrigue [this message]
2001-11-15  6:43   ` 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=20011115100557Y.garrigue@kurims.kyoto-u.ac.jp \
    --to=garrigue@kurims.kyoto-u.ac.jp \
    --cc=caml-list@inria.fr \
    --cc=william.newman@airmail.net \
    /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