comp.lang.ada
 help / color / mirror / Atom feed
* covariance and parameter modes (was: Re: Instantiating Generic Object)
       [not found]         ` <3468E43B.7BCFFF2C@munich.netsurf.de>
@ 1997-11-13  0:00           ` Karel Th�nissen
  1997-11-14  0:00             ` Graham Perkins
  0 siblings, 1 reply; 3+ messages in thread
From: Karel Th�nissen @ 1997-11-13  0:00 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1669 bytes --]


Joachim Durchholz wrote:

> I haven't read the Sather references too closely, but I think you can
> add superclasses in a post-hoc way. In fact I think Sather was created
> exactly because covariant parameter definition was considered to be the
> wrong way around; post-hoc superclasses are just a necessity if you
> accept contravariance as a premise.

I am always a bit puzzled if a language is deemed contravariant or
covariant in relation with typesafety.

The point is, that if in the parameter mechanism a distinction is made
among in-parameters, out-parameters and in-out-parameters (like in Ada),
contravariance and covariance can both be typesafe depending on the mode
of the parameter.

For in-parameters, contravariance is the typesafe approach. For
out-parameters, and hence function results, covariance is the typesafe
approach. For in-out-parameters, being a combination of the two, only
'invariance' is typesafe.

Unfortunately, many modern languages do not make the distinction among
parameter modes, and are, therefore, cursed with variancy problems. In
well-designed languages, the issue is not contravariance or covariance,
as they should both be provided by the language, but it is rather
typesafety or typebreakage. IIRC, this is okay in Sather.

BTW, I do not understand why not more languages make use of parameter
modes, because it catches a lot of other bugs as well 8-(

-- 
Groeten, Karel Th�nissen

-- mijn e-adres is versleuteld om junk-mailers op het net te verwarren
-- verwijder confusion om zo mijn echte adres te verkrijgen

-- my e-mail address is scrambled to confuse spammers
-- remove the confusion to obtain my true address




^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: covariance and parameter modes (was: Re: Instantiating Generic Object)
  1997-11-13  0:00           ` covariance and parameter modes (was: Re: Instantiating Generic Object) Karel Th�nissen
@ 1997-11-14  0:00             ` Graham Perkins
  1997-11-18  0:00               ` Karel Th�nissen
  0 siblings, 1 reply; 3+ messages in thread
From: Graham Perkins @ 1997-11-14  0:00 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1975 bytes --]


Karel Th�nissen wrote:
> For in-parameters, contravariance is the typesafe approach. For
> out-parameters, and hence function results, covariance is the typesafe
> approach. For in-out-parameters, being a combination of the two, only
> 'invariance' is typesafe.

ancestor--> whole_sqrt( n:NATURAL ) : NATURAL
descendant--> whole_sqrt( n:INTEGER ) : INTEGER

contravariant in-parameter for type safety.  But it aint
semantically safe, eg sqrt(-3)

contravariant "out" result not safe, but it could well
make more sense for programmer who doesn't want
his functions creating mixed-mode arithmetic.

DISCLAIMER  DISCLAIMER  DISCLAIMER  DISCLAIMER
this may not be a good example, please let's not go
down a long thread about how dreadful I am at designing
numerical libraries!

My point is this: foolproof type safety of any language feature
often has to be obtained at the cost of some expressive power.
In some casess it may be better to take a more pragmatic approach
and let programmers do things that make sense in terms of the
domain they are working with.

Eiffel's covariance originally gave high flexibility and 
created horrible (but solvable) validity problem.  New
CAT rules restrict it a little and make validity much
simpler (class rather than system level).

It's a trade-off and there obviously isn't one correct
answer.

---------

For domain argument concerning parameter/result variance,
simply think of an object with local container and exported
"put" and "get" methods.  You put something into the object,
or you take it out.

Now if you allow variance at all, a descendant object
should allow you to put and get something else.  Should the
"something else" be a descendant or ancestor of "something"?
I don't care.  Whichever rule you make, you end up
having the *same* variance policy for in-parameters
and out-results.

---------

  [Roger, was that a good disguise of my cow, herbivore,
   food, grass, example that we all got heartily sick of? ]




^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: covariance and parameter modes (was: Re: Instantiating Generic Object)
  1997-11-14  0:00             ` Graham Perkins
@ 1997-11-18  0:00               ` Karel Th�nissen
  0 siblings, 0 replies; 3+ messages in thread
From: Karel Th�nissen @ 1997-11-18  0:00 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 5651 bytes --]


Graham Perkins wrote:
> 
> Karel Th�nissen wrote:
> > For in-parameters, contravariance is the typesafe approach. For
> > out-parameters, and hence function results, covariance is the typesafe
> > approach. For in-out-parameters, being a combination of the two, only
> > 'invariance' is typesafe.
> 
> ancestor--> whole_sqrt( n:NATURAL ) : NATURAL
> descendant--> whole_sqrt( n:INTEGER ) : INTEGER

What are these classes INTEGER and NATURAL? Are they part of Eiffel? I
couldn't find them in the index of OOSC-2. From syntax, the example
certainly isn't Ada.

So I assume that NATURAL and INTEGER are taken from mathematics and
stand for {0, 1, 2, 3, .....} ('N') and {...., -3, -2, -1, 0, 1, 2, 3,
...} ('Z') respectively. Mathematically, N is a subset of Z, and in OO,
NATURAL is a subtype INTEGER with a strengthened invariant.

So either your ancestors and descendants are mixed up, or I didn't fully
understand you :-). 
 
> contravariant in-parameter for type safety.  But it aint

Your example uses a covariant in-parameter and a covariant
out-parameter, as both change with their classes from NATURAL to
INTEGER.
 
> semantically safe, eg sqrt(-3)

But neither was the ancestor, if the ancestor and the decendant hadn't
been mixed up.

> contravariant "out" result not safe, but it could well
> make more sense for programmer who doesn't want
> his functions creating mixed-mode arithmetic.

I do not like the idea that typesafety should be traded for this
convenience.

> DISCLAIMER  DISCLAIMER  DISCLAIMER  DISCLAIMER
> this may not be a good example, please let's not go
> down a long thread about how dreadful I am at designing
> numerical libraries!

Accepted.
 
> My point is this: foolproof type safety of any language feature
> often has to be obtained at the cost of some expressive power.

Quite possible indeed.

> In some casess it may be better to take a more pragmatic approach
> and let programmers do things that make sense in terms of the
> domain they are working with.

Okay. But why allow the programmer to silently mess up the typing
system, push the compiler into system-wide inference mode, and create
code where the bugs creep out at the next round of redesign or
maintenance? Why not have typesafety by default and deviations when
explicitly indicated by the programmer?

Making sense in terms of the problem domain sounds good, but that
presupposes 1) a good understanding of the problem domain, 2) a good
understanding of OO, and 3) a good understanding of how to map from OO
to the problem domain. The latter is the thing that really worries me if
I read OO-literature. Okay, I am a semanticist by profession/education,
I confess. Now execute me 8-).

> Eiffel's covariance originally gave high flexibility and
> created horrible (but solvable) validity problem.  New
> CAT rules restrict it a little and make validity much
> simpler (class rather than system level).

Sorry, but I think it is a mess. Fortunately enough for Eiffel, most
languages do even worse. Eiffel goes at great length with DBC, weakening
preconditions, strengthening postconditions and invariants, so for me
this CAT-talk is a Fremdk�rper.

> It's a trade-off and there obviously isn't one correct
> answer.

I doubt that.
 
> For domain argument concerning parameter/result variance,
> simply think of an object with local container and exported
> "put" and "get" methods.  You put something into the object,
> or you take it out.

Do I hear a cow eating grass and producing milk here?
 
> Now if you allow variance at all, a descendant object
> should allow you to put and get something else.  Should the
> "something else" be a descendant or ancestor of "something"?
> I don't care.  Whichever rule you make, you end up
> having the *same* variance policy for in-parameters
> and out-results.

Correct, so in this example we would like to have interface inheritance
and possibly implementation inheritance, but not type inheritance (and
thus loose LSP).

[Going back to COWs and ANIMALs, because it is less abstract:] It is
useful to have ANIMALs eating FOOD in genernal and to have the
descendant COWs eating GRASS in particular. So the convariant
in-parameter breaks the typesafety rules. This now can indicate an error
in our design of COW: it should eat any food not just grass, or it can
indicate that COW is not a _subtype_ of ANIMAL. Your choice. If you
chose the latter, you loose the ability the pass a cow as a parameter to
a routine that assumes an ANIMAL, because the routine may start feeding
the cow with any food, including MICE and RATS.

Now people may at first wonder when they arrive at the conclusion that
COW should not be a subtype of ANIMAL. But this paradox stems from the
fact that most people are semantically confused about OO and even
propose OO as a formalism to describe 'the 'world'.

If we look very carefully at what we wrote in our specification of
ANIMAL, then it says that ANIMALs eat any FOOD. So if that is the
definition of ANIMAL, then COWs are definitely not ANIMALs, because they
will not eat _any_ FOOD. However, with our contrived mapping of
semantics and formal semantics we read the specification of ANIMALs so
that they eat _some_kind_of_ FOOD, which it doesn't say.

>   [Roger, was that a good disguise of my cow, herbivore,
>    food, grass, example that we all got heartily sick of? ]

8-) yes, with permission

-- 
Groeten, Karel Th�nissen

-- mijn e-adres is versleuteld om junk-mailers op het net te verwarren
-- verwijder confusion om zo mijn echte adres te verkrijgen

-- my e-mail address is scrambled to confuse spammers
-- remove the confusion to obtain my true address




^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~1997-11-18  0:00 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <646g1b$avs@solaria.cc.gatech.edu>
     [not found] ` <3466EBB8.61AE@stratus.com>
     [not found]   ` <EJFy23.47o@ecf.toronto.edu>
     [not found]     ` <slrn66f65r.f80.kennel@lyapunov.ucsd.edu>
     [not found]       ` <EJHnM4.H97@ecf.toronto.edu>
     [not found]         ` <3468E43B.7BCFFF2C@munich.netsurf.de>
1997-11-13  0:00           ` covariance and parameter modes (was: Re: Instantiating Generic Object) Karel Th�nissen
1997-11-14  0:00             ` Graham Perkins
1997-11-18  0:00               ` Karel Th�nissen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox