Browse thread
RE: [Caml-list] strange behaviour with variants and "cannot be g eneralized"
[
Home
]
[ Index:
by date
|
by threads
]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
| Date: | -- (:) |
| From: | skaller <skaller@o...> |
| Subject: | RE: [Caml-list] strange behaviour with variants and "cannot be g eneralized" |
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