Mailing list for all users of the OCaml language and system.
 help / color / mirror / Atom feed
From: John Prevost <j.prevost@gmail.com>
To: caml-list <caml-list@inria.fr>
Subject: Re: [Caml-list] Narrowing class's public interface
Date: Wed, 13 Oct 2004 02:39:10 -0400	[thread overview]
Message-ID: <d849ad2a0410122339ec207d3@mail.gmail.com> (raw)
In-Reply-To: <1097634426.19740.152.camel@pelican.wigram>

On 13 Oct 2004 12:27:07 +1000, skaller <skaller@users.sourceforge.net> wrote:
  {...}
> Hence OO is useless as a general paradigm. {...}
  {...}
> Don't even both trying to make the character type polymorphic
> because the theory says it can't be done. The reason is
> also easy to see, as John Provost described, but another
> view of the same thing: you'd need one method for every
> driver kind/character kind combination. In other words
> the number of methods needed is quadratic in the subtypes,
> but OO only supports linear -- you can supply a new method
> for each derived 'main object' type .. which is why the method
> arguments can't also be polymorphic.

Er.  You're overstating the case here.  First, note that OO
programming and subtyping-based polymorphism don't have to go
together.  It's perfectly reasonable, for example, to have a container
class that is invariant in the type of its content.

And your IO example is flawed as well.  The fixed data type is only an
issue if you mix input and output in a single object.  Example:

exception Producer_Empty

class type ['a] producer = object
  method get : unit -> 'a
end

class type ['a] consumer = object
  method put : 'a -> unit
end

class type ['a] producer_consumer = object
  inherit ['a] producer
  inherit ['a] consumer
end

class file_char : filename:string -> char producer_consumer
class file_char_input_stream : filename:string -> char producer
class char_to_line_stream : char producer -> string producer
class map_producer : ('a -> 'b) -> 'a producer -> 'b producer

val iter_over_producer : ('a -> unit) -> 'a producer -> unit

class type bovine = object
  method moo : unit -> unit
end

class type cow = object
  inherit bovine
  method milk : unit -> milk
end

class type supercow = object
  inherit cow
  method fly : unit -> unit
end


val cows : cow producer_consumer


The first thing to notice is that you can have a wide variety of I/O
oriented classes (and functions over those classes, and classes over
those classes) without worrying about the type of the item being
produced or consumed.

The second thing I want to point out is about "cows" above.  cows
cannot be used as a bovine producer_consumer or as a supercow
producer_consumer.  It can, however, be used as either a bovine
producer, or a supercow consumer.    Just because an object type is
invariant does not mean that it cannot be cast to a covariant or
contravariant type.


In other words: you go too far to extend this argument to this level.


When binary methods exist, things are indeed trickier.  They are not,
however, impossible.  Again, remember that casting out the
problemmatic methods can always restrict you down to a type with
simpler constraints.  In the RV example, you can think in terms of a
complicated part of the program which manipulates and creates the RV
objects, fully understanding that when manipulating those objects, the
types must be maintained.  But it can feed the objects it creates into
a collection of restricted RV objects, which only carry the methods
needed to use them, not the methods needed to manipulate them.  No
more binary methods, no problem having them all be the same type.


I have to admit that I don't use the OO features of O'Caml very
much--I generally don't need the flexibility.  But these features are
very very powerful, for a variety of uses.  The trick is to get out of
the *class* oriented mindset, and back into a mindset where the
objects are what matters.  After that, it's all a matter of learning
what constraints type safety imposes, and the right way to work within
those constraints.  There are a few odd cases--like the constructor
issue we saw on this list fairly recently, with the SQL connection
pool--but if you understand the type system, it mostly all just makes
sense.

John.

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


  reply	other threads:[~2004-10-13  6:39 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-10-12 22:16 Tony Edgin
2004-10-13  0:49 ` Jacques Garrigue
2004-10-13  1:43   ` John Prevost
2004-10-13  2:27     ` skaller
2004-10-13  6:39       ` John Prevost [this message]
2004-10-13  7:34         ` skaller

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=d849ad2a0410122339ec207d3@mail.gmail.com \
    --to=j.prevost@gmail.com \
    --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