caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Markus Mottl <markus@oefai.at>
To: Clemens Hintze <cle-ocaml@qiao.in-berlin.de>
Cc: caml-list@inria.fr
Subject: Re: [Caml-list] Re: [Q]: Co(ntra)variance and subtyping?
Date: Mon, 19 Nov 2001 13:03:15 +0100	[thread overview]
Message-ID: <20011119130314.B29501@chopin.ai.univie.ac.at> (raw)
In-Reply-To: <20011119082446.B79776@qiao.in-berlin.de>; from cle-ocaml@qiao.in-berlin.de on Mon, Nov 19, 2001 at 08:24:46 +0100

Clemens Hintze schrieb am Montag, den 19. November 2001:
> I want to thank you all, who have contributed to answer my questions
> about co(ntra)variance. Now I will have to read it all for a few times
> (I guess a dozent will enough ;-) to try to understand what you gurus
> tried to tell me ;-))

Maybe a small excursion to logic makes things easier to understand. Just
consider types as propositions about values, for example "x is an integer"
or "f maps a foo to a bar". Let's focus on the latter case:

  foo -> bar  (1)

Whenever we find a case where "foo" holds (whenever we have a value of
type "foo"), then this implies "bar" (the result of function "f" will be
"bar").

We now add further elements to the type "bar", getting type "super_bar"
(it is a super type of the former by definition). Logically speaking,
this means:

  bar -> super_bar  (2)

Together with proposition (1), this allows us to derive:

  foo -> super_bar  (3)

One can prove this easily (e.g. using truth tables) by showing that the
following is a tautology (holds irrespective of our interpretation of
"foo" and "bar"):

  (foo -> bar) /\ (bar -> super_bar) -> (foo -> super_bar)  (4)

Therefore, if some context expects a function of type "foo -> super_bar",
(expects that "foo -> super_bar" holds), then it is sound to substitute
a function of type "foo -> bar" in it, given that "bar -> super_bar"
holds. The term that applies here is "covariance", because making
the proposition "bar" weaker (letting it apply to additional cases,
i.e. making it less strict) also makes "foo -> bar" weaker (and
vice-versa).

Let's consider adding elements to "foo" now, getting super type
"super_foo":

  foo -> super_foo  (5)

Would it be sound to assume the following? -

  (foo -> bar) /\ (foo -> super_foo) -> (super_foo -> bar)  (6)

Just try to prove this a tautology, and you'll quickly find out
that it isn't! It is also not an invalid argument (i.e. not false in
general), its satisfiability "depends". Surely, nobody would want to have
computer programs whose correctness "depends" on possibly unpredictable
eventualities!

In which cases can we safely assume that (6) holds? This is only the
case when our value of type "super_foo" is still a "foo" (which actually
means that "super_foo" must be a subtype of "foo"!):

  super_foo -> foo  (7)

But together with (5) this means that both types must be equivalent:

  super_foo <-> foo  (8)

Not very interesting a case for programmers. But this one looks much
nicer:

   (sub_foo -> foo) /\ (foo -> bar) -> (sub_foo -> bar)  (9)

Because we can easily prove that this is valid, we see that we have to
make the proposition "foo" stronger (apply to a subset only) to make
"foo -> bar" weaker (apply more generally).  We call this requirement of
making something "stronger" to get something "weaker" (and vice-versa)
"contravariance" as opposed to "covariance", which goes with weaker/weaker
(more general / more general) and stronger/stronger (more specific /
more specific).

Some OO-languages (e.g. Eiffel) assume that (6) always holds (is a
tautology). But this is unsound as we have seen, and one can therefore
find cases, where static type safety will break, which will either crash
the program or require expensive runtime checks.

I hope the logicians among you will now clean out all flaws in my
example... :-)

Regards,
Markus Mottl

-- 
Markus Mottl                                             markus@oefai.at
Austrian Research Institute
for Artificial Intelligence                  http://www.oefai.at/~markus
-------------------
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-19 12:50 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2001-11-16 19:37 [Caml-list] " Clemens Hintze
2001-11-17 14:18 ` Mark Wotton
2001-11-17 14:55   ` Mark Wotton
2001-11-17 17:50   ` [Caml-list] " Clemens Hintze
2001-11-17 23:17     ` Mark Wotton
2001-11-18  9:16       ` Clemens Hintze
2001-11-18 13:18         ` Alain Frisch
2001-11-19  9:54           ` Remi VANICAT
     [not found]       ` <9t7v4d$gij$1@qrnik.zagroda>
2001-11-18 11:57         ` Marcin 'Qrczak' Kowalczyk
2001-11-18 13:34 ` [Caml-list] " Andreas Rossberg
2001-11-18 21:22   ` Pixel
2001-11-19  0:33     ` Jacques Garrigue
2001-11-18 22:35       ` David Gurr
2001-11-19  7:24         ` [Caml-list] " Clemens Hintze
2001-11-19 12:03           ` Markus Mottl [this message]
2001-11-19  8:29         ` [Caml-list] " Xavier Leroy
2001-11-19 11:03       ` Alain Frisch
2001-11-20  9:58         ` Didier Remy
2001-11-19 11:14       ` Pixel
2001-11-18 22:30   ` [Caml-list] Re: variance, subtyping and monads... oh, my! james woodyatt
2001-11-19  8:11     ` Francois Pottier
2001-11-19  9:02       ` james woodyatt
2001-11-19  9:58         ` Markus Mottl
2001-11-19 20:47           ` james woodyatt
2001-11-19 12:56       ` Frank Atanassow
2001-11-19 10:39     ` Andreas Rossberg
2001-11-19 12:21       ` Markus Mottl
2001-11-19 13:43         ` [Caml-list] Kylix and OCaml Christophe Raffalli
2001-11-20  2:05           ` Vitaly Lugovsky
2001-11-20  8:51             ` Christophe Raffalli
2001-11-22  1:42               ` Vitaly Lugovsky
2001-11-20 10:00             ` Benjamin Monate
2001-11-20 10:24               ` [Caml-list] [Bug in an interface between C++ and OCAML due to some pointer encapsulation] Sylvain Kerjean
2001-11-20 12:14             ` [Caml-list] Kylix and OCaml Maxence Guesdon

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=20011119130314.B29501@chopin.ai.univie.ac.at \
    --to=markus@oefai.at \
    --cc=caml-list@inria.fr \
    --cc=cle-ocaml@qiao.in-berlin.de \
    /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).