Mailing list for all users of the OCaml language and system.
 help / color / mirror / Atom feed
From: John Max Skaller <skaller@ozemail.com.au>
To: caml-list@inria.fr
Subject: [Caml-list] Polymorphic variants
Date: Wed, 17 Apr 2002 19:49:23 +1000	[thread overview]
Message-ID: <3CBD4523.6080707@ozemail.com.au> (raw)

I've been using polymorphic variants for a little while, and am
interested in their current status. Here are some comments. The 
executive summary is:
they're definitely worth using, and definitely worth continued
development.

My project is a compiler. The main reason I switched to
polymorphic variants is that term desugaring and reductions
would appear to be best handled by a single large term type,
and a various subsets appropriate to context. For example,
a type expression is a subset of an expression: it admits
addition, multiplication and exponentiation, but no
subtraction.

Unfortunately, this doesn't work out as well as I'd expected
because of recursion:

type a = [`A of a  | `B]
type b = [`A of  b]

The second type is a subtype of the first,
but this fails:

let f (x:a) =
match x with
  #b -> ()

with the message:

This pattern matches values of type [< b] = [< `A of b]
but is here used to match values of type a = [ `A of a | `B];;

Ocaml understands subtyping by subsets of variants,
but the constructor arguments must be invariant.
The work around is to decode the argument manually,
but then one wonders what the gain over standard variants is.
Here is another example:

 type x = [`A of int | `A of float];;
This variant type contains a constructor [ `A of float] which should be
[ `A of int]

No, I meant what I said! I can write both:

`A 1

and also

`A 1.1

and I am trying  to tell the compiler they both belong
to type x. It has no right to complain here. Of course,
this does lead to a problem:

 match x with | `A a -> ..

what type is a? It's 'a initially,
and bound on the first use. Which makes
matching on first `A 1 and then `A 1.1
impossible.  This is a problem with the ocaml type
inference mechanism not my type declaration!
[So it can't deduce the type of a .. but I could specify it
if there were syntax like

| `A (a:int) -> ...

[It seems to me that the type of the argument
is taken *incorrectly* as the intersection
type int & float, when it is actually a sum..
in the case of a sum the constraint would be
enough to fix the type correctly .. on the other hand,
intersections would correctly solve the covariance
problem .. ??]

In fact I found the type inference
engine stumbled around over legitimate matches,
and some extra help in the form of function argument
type  constraints was necessary (a small price to pay,
but worth noting an example in the manual).

In any case, polymorphic variant constructors really
ARE overloaded, but when it comes to declaring
types, overloading isn't allowed. This is an anomaly ..
and it hit me quite hard initially, because of the natural
attempt to try to use covariant arguments.

A second problem I found is the verbose error messages.
When you have 20 variants, a mismatch is a real pain
to decypher. It would be useful if variants HAD to be
declared like:

variant `A of int
variant `A of float
variant `B of long

so that spelling mistakes and type errors in constructor
arguments could be more easily pinpointed .. but of course,
this can't work due to recursion ... hmmm...

One thing that *definitely* needed improvement is the syntax
for declaring types: having to repeat all the cases every time
is an error prone tedium. It appears this HAS been done in
ocaml 3.04! THANK YOU!! One can now write:

type a = [`A]
type b = [`B]
type c = [a | b]

[#types were previously allowed in pattern matches but not
type declarations ..]

Well, are polymorphic variants worth the effort?
I think they are: they're not perfect, they're certainly
more error prone than standard variants .. but they're
also a lot more expressive and save considerable
coding, and in many cases they're much faster as well.
[In particular, injecting a subset of cases into a supertype
is a no-operation, whereas standard variants require
actually building new values]


-- 
John Max Skaller, mailto:skaller@ozemail.com.au
snail:10/1 Toxteth Rd, Glebe, NSW 2037, Australia.
voice:61-2-9660-0850



-------------------
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:[~2002-04-17  9:49 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-04-17  9:49 John Max Skaller [this message]
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
2002-04-24  6:55   ` [Caml-list] How to compare recursive types? John Max Skaller
2002-04-24  9:07     ` Andreas Rossberg
2002-04-24  9:26       ` Haruo Hosoya
2002-04-24 13:14       ` John Max Skaller
2002-04-24 15:04         ` Andreas Rossberg
2002-04-25  1:11           ` John Max Skaller
2002-04-25  4:41             ` John Max Skaller
2002-04-25  7:03               ` [Caml-list] How to compare recursive types? Solution! John Max Skaller
2002-04-25 13:31                 ` Jerome Vouillon
2002-04-27  4:11                   ` John Max Skaller
2002-04-25  8:54             ` [Caml-list] How to compare recursive types? Andreas Rossberg
2002-04-25 13:20     ` Jerome Vouillon
2002-04-27  3:43       ` John Max Skaller
2007-01-16 20:32 Polymorphic Variants 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
2007-01-18 21:43       ` Christophe TROESTLER
2007-01-18  1:28     ` Jacques Garrigue
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

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=3CBD4523.6080707@ozemail.com.au \
    --to=skaller@ozemail.com.au \
    --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