caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Jacques Garrigue <garrigue@math.nagoya-u.ac.jp>
To: tom.primozic@gmail.com
Cc: caml-list@yquem.inria.fr
Subject: Re: [Caml-list] Polymorphic Variants
Date: Thu, 18 Jan 2007 10:28:08 +0900 (JST)	[thread overview]
Message-ID: <20070118.102808.108741650.garrigue@math.nagoya-u.ac.jp> (raw)
In-Reply-To: <c1490a380701171313j7f54a420yd17d15164e52f9ac@mail.gmail.com>

From: Tom <tom.primozic@gmail.com>
> On 17/01/07, Jacques GARRIGUE <garrigue@math.nagoya-u.ac.jp> wrote:
> > From: Tom <tom.primozic@gmail.com>
> > > So... why actually are polymorphic variants useful? Why can't they
> > simply be
> > > implemented as normal, concrete (or how would you call them? ...)
> > variants?
> >
> > The original motivation was for the LablTk library, where some types
> > (index for instance) have lots of small variations. At that point
> > there where several options
> > * overloading (but ocaml loathes overloading, you could say that the
> >   total absence of overloading is essential to the language)
> 
> Is there a reason for that? Is it only hard to implement or are there any
> conceptual / strategical / theoretical reasons?

There are two kinds of theoretical reasons.

The most theoretical one is about semantics: with generic overloading,
all your semantics must take types into account. This is a problem as
most theoretical studies of lambda-calculus are based on so-called
erasure semantics, where types are discarded at execution. So this
means you must design your own, more complex semantics. Not that this
reason may not apply to constructor or record overloading, if you do
not allow the semantics to change according to the type.

The other one is about type inference. Basically, overloading has a
huge impact on overloading. The direct way to handle it, using types
alone, is deeply disruptive, as it means that some programs will be
refused for lack of type information. It is very hard to define a
clear criterion on which programs should be refused, notwithstanding
internal details of the compiler. This also applies to record and
constructor overaloading. There are other approach the problem, with
constrained type variables (either Haskell's type classes or G'Caml's
generic type variables,) but of course they add complexity to the type
system. And it is not clear that they solve the problem for
constructor and record overloading: in Haskell, records fields are not
overloaded, and constructor overloading has to be done by hand for
each type, through an explicit encoding into type classes.

Both reasons have practical impact. For the first one, using erasure
semantics means that the programmer also can discard types when
understanding the runtime behaviour of a program. For the second one,
you can write code that is maximally polymorphic, without too much
fear about the impact of performance (equality is overloaded, so
it still matters...) or strange ambiguity-related error messages.

So for the time being ocaml keeps to no overloading at all.

> > OCaml does not, as far as I know, have any structural typing for
> > records..

Not for records, but for objects. From a type-theoretic point of view
they are just equivalent.

> Hm... Actually, what I had in mind is nominal subtyping... similar to
> objects, in fact, objects in C++-like languages, just that they have no
> class methods.

Reading the description below, this all looks nice, independently of
the semantics limitation described above. However, you can kiss
farewell to type inference. With such an extensive overloading, you
would need type annotations all over the place.
By the way, this all looks likes the "used this feature in C++"
syndrome. Sure C++ is incredibly powerful. But it is built on rather
shaky theoretical fundations. So you can't expect to bring everything
from C++ to a new language. Why not think about new ways to solve
problems :-)
(To be completely honest, this also looks a bit like ML2000, and the
Moby language, which has a sound theoretical fundation, but never
really took off. You might want to go see for yourself.)

Jacques Garrigue
 
> Now... close your eyes (but try to continue reading this ;) ) and imagine
> you're in a dreamworld. You are programming in a language that has
>   * function overloading that allows you to have
>        length "abcd" + length [1; 2; 3]
>   * Constructor overloading, eliminating the need of
>        type parse_expression =
>            Pexp_name of string
>          | Pexp_constant of constant
>          | Pexp_let of (pattern * parse_expression) * parse_expression
>          | Pexp_apply of parse_expression * parse_expression list
>          | Pexp_try of parse_expression * (pattern * parse_expression) list
> 
>        type typed_expression =
>            Texp_ident of ident
>          | Texp_constant of constant
>          | Texp_let of (pattern * typed_expression) * typed_expression
>          | Texp_apply of typed_expression * typed_expression list
>          | Texp_try of typed_expression * (pattern * typed_expression) list
>     as it can be coded as
>        type parse_expression =
>            Name of string
>          | Constant of constant
>          | ...
> 
>        type typed_expression =
>            Ident of ident
>          | Constant of constant
>          | ...
> 
>   * nominal subtyping of records, with overloaded field names:
>        type widget = {x : float; y : float; width: float; height: float} (*
> top-level type *)
>        type button = {widget | text : string }
>        type checkbox = {button | checked : bool}
>        type image = {widget | url : string}
> 
>        type vector = {x : float; y : float}
>        type document {url : url}
> 
>     so subtypes could be applied to a function
>        fun move : widget -> (float * float) -> unit
> 
>        let chk = {x = 0.0; y = 0.0; width = 10.0; height = 12.0; text =
> "Check me!"; checked = false}
>        move chk (3.0, 3.0)
>     and types could be "discovered" at runtime:
>        let draw widget =
>          typematch widget with
>              w : widget -> draw_box (w.x, w.y, w.height, w.width)
>            | b : button -> draw_box (b.x, b.y, b.height, b.width); draw_text
> b.text
>            | i : image -> draw_image i.url (i.x, i.y)
>            | ...
> 
> Do you think you would be "satisfied" even without polymorphic variants?
> 
> I am not saying this just for fun... I want to create a language with
> overloading, but I kinda don't really like polymorphic variants... thou if
> they turn out to be really useful, I would probably start to like them.
> 
> Any comments?
> 
> - Tom


  parent reply	other threads:[~2007-01-18  1:28 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-01-16 20:32 Tom
2007-01-16 20:49 ` [Caml-list] " Seth J. Fogarty
2007-01-16 21:05   ` Tom
2007-01-16 21:23     ` Seth J. Fogarty
2007-01-16 21:45       ` Edgar Friendly
2007-01-16 22:18       ` Lukasz Stafiniak
2007-01-17  5:55       ` skaller
2007-01-17  0:30 ` Jonathan Roewen
2007-01-17  2:19 ` Jacques GARRIGUE
2007-01-17  3:24   ` Christophe TROESTLER
2007-01-18  2:12     ` Jacques Garrigue
2007-01-17  6:09   ` skaller
2007-01-17 13:34     ` Andrej Bauer
2007-01-17 21:13   ` Tom
2007-01-17 22:53     ` Jon Harrop
2007-01-17 23:07       ` Tom
     [not found]         ` <200701172349.53331.jon@ffconsultancy.com>
     [not found]           ` <c1490a380701180407j670a7cccyb679c71fde20aa4b@mail.gmail.com>
2007-01-18 16:23             ` Fwd: " Tom
2007-01-18 21:14               ` Jon Harrop
2007-01-19  9:26                 ` Dirk Thierbach
2007-01-19 10:35                   ` Tom
2007-01-19 11:14                     ` Dirk Thierbach
2007-01-19 12:03                       ` Tom
2007-01-18 21:43       ` Christophe TROESTLER
2007-01-18  1:28     ` Jacques Garrigue [this message]
2007-01-18  1:46       ` Jon Harrop
2007-01-18  4:05       ` skaller
2007-01-18  6:20         ` Jacques Garrigue
2007-01-18  9:48           ` skaller
2007-01-18 12:23       ` Tom
  -- strict thread matches above, loose matches on Subject: below --
2002-04-17  9:49 [Caml-list] Polymorphic variants John Max Skaller
2002-04-17 10:43 ` Remi VANICAT
2002-04-17 23:49   ` John Max Skaller
2002-04-18  1:23     ` Jacques Garrigue
2002-04-18  9:04       ` John Max 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=20070118.102808.108741650.garrigue@math.nagoya-u.ac.jp \
    --to=garrigue@math.nagoya-u.ac.jp \
    --cc=caml-list@yquem.inria.fr \
    --cc=tom.primozic@gmail.com \
    /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).