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?

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

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.

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