From: skaller <skaller@ozemail.com.au>
To: "Beck01, Wolfgang" <BeckW@t-systems.com>
Cc: caml-list@inria.fr
Subject: RE: [Caml-list] strange behaviour with variants and "cannot be g eneralized"
Date: 10 Sep 2003 19:48:42 +1000 [thread overview]
Message-ID: <1063187322.2119.118.camel@localhost.localdomain> (raw)
In-Reply-To: <ADD42C8394EBD4118A3D0003470C18F00950F3D8@G9JJT.mgb01.telekom.de>
On Wed, 2003-09-10 at 17:10, Beck01, Wolfgang wrote:
> Didier Remy [mailto:remy@morgon.inria.fr] wrote:
>
> > Here is some explanation of
> >
> > 1) what happened in version 3.06 and
> > 2) how this is related to a relaxed form of value restriction,
> > 3) which is actually orthogonal to the solution implemented in 3.07
> >
> > [detailed explanation omitted]
>
> well, I was not aware that compilation of polymorphic variants is an area
> of ongoing research. In the OCaml manual, they are not mentioned under
> "Language extensions" but as a section in the chapter "An introduction to
> Objective Caml". There is a statement
>
> "In programs, polymorphic variants work like usual ones. You just
> have to prefix their names with a backquote character `."
>
> and this is not true, at least in 3.06. After spending another evening
> with weird type errors, I replaced polymorphic variants with ordinary
> ones. My project looks uglier now since I had to split up some files,
> but at least it compiles and runs.
I use polymorphic variants extensively. Technically, you have to add
the backquote ` and also [] in the type definitions:
type x = X of int
becomes
type x = [ `X of int ]
If you do both these changes, everything should work, plus
or minus some casts. Occasionally, you will have to
cast some value using single or double coercions:
(a:t) (* annotation only *)
(a:>t) (* conversion *)
(a:u:>t) (* double conversion *)
This is quite rare, but it is sometimes necessary
when you have wildcard matches like:
let f e =
match e with
| `A -> ..
| _ -> ...
How can the compiler know what the type here really is
supposed to be? Unlike ordinary variants, the tag `A can
occur in any number of types.
if you now use that expression in a context requiring
type [`A | `B] you'll get an error. Perhaps e contained
the tag `C?
So with polymorphic variants, because the typing is so
flexible, you have to use type
annotations and casts a bit more often than ordinary variants.
The situation is entirely different if your code has an
error in it! In this case, you will often get
vvvvvvvveeeeeeeerrrrrrrryyyyyyy long error messages:
in my case hundreds of lines long usually.
This really is a problem, particularly when the source
of the problem could easily be diagnosed in some
cases: for example a missing tag, or a tag with
an incompatible argument. The compiler *does* detect
some of these cases (but not enough yet).
You are therefore advised to make smaller changes to
your program before recompiling, since then you know
the error is in a place you just changed.
Are polymorphic variants worth it?
For simple uses, the answer is no. However,
in a complex program such as a compiler which
can benefit from a large number of types which
are typing different subsets of a universal term
type, polymorphic variants are indispensible.
They not only allow more accurate typing,
they're also *faster*. For example,
consider a restriction of a term type
in which rewriting rules reduce some
sugars to lower level primitive
(for example macro expansion).
Either you forgoe a typing in which macros
cannot be in the output type of the rewriting,
or you have to convert all the terms from one
variant type to another like
match e with
| A -> AA
| B -> BB
| C i -> CC i
| Macro x -> f x..
which is slower than the polymorphic variant version:
match e with
| `Macro x -> f x
| #nonmacro as x -> x
since there is no need deconstruct and reconstruct
the isomorphic terms, since the isomorphism is
represented by value equality: the same tags
`A, `B, `C of int
can occur in both the input and output types.
-------------------
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
next prev parent reply other threads:[~2003-09-10 9:49 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-09-10 7:10 Beck01, Wolfgang
2003-09-10 8:12 ` Fernando Alegre
2003-09-10 8:18 ` Jacques Garrigue
2003-09-10 10:39 ` skaller
2003-09-10 9:48 ` skaller [this message]
2003-09-10 11:34 ` Frederic De Jaeger
-- strict thread matches above, loose matches on Subject: below --
2003-09-09 14:13 Beck01, Wolfgang
2003-09-09 19:17 ` Didier Remy
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=1063187322.2119.118.camel@localhost.localdomain \
--to=skaller@ozemail.com.au \
--cc=BeckW@t-systems.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