From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.1.3 (2006-06-01) on yquem.inria.fr X-Spam-Level: X-Spam-Status: No, score=0.4 required=5.0 tests=AWL,DNS_FROM_RFC_ABUSE autolearn=disabled version=3.1.3 X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from concorde.inria.fr (concorde.inria.fr [192.93.2.39]) by yquem.inria.fr (Postfix) with ESMTP id 61D3CBC0B for ; Wed, 17 Jan 2007 03:19:36 +0100 (CET) Received: from rabbit.math.nagoya-u.ac.jp (rabbit.math.nagoya-u.ac.jp [133.6.130.5]) by concorde.inria.fr (8.13.6/8.13.6) with ESMTP id l0H2JYOd009283 for ; Wed, 17 Jan 2007 03:19:35 +0100 Received: from localhost (rabbit-172 [172.16.254.254]) by rabbit.math.nagoya-u.ac.jp (8.12.11/3.7W) with ESMTP id l0H2JRIv007549; Wed, 17 Jan 2007 11:19:27 +0900 (JST) Date: Wed, 17 Jan 2007 11:19:27 +0900 (JST) Message-Id: <20070117.111927.2004173151.garrigue@math.nagoya-u.ac.jp> To: tom.primozic@gmail.com Cc: caml-list@yquem.inria.fr Subject: Re: [Caml-list] Polymorphic Variants From: Jacques GARRIGUE In-Reply-To: References: X-Mailer: Mew version 4.2 on Emacs 21.4 / Mule 5.0 (SAKAKI) Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Miltered: at concorde with ID 45AD87B6.000 by Joe's j-chkmail (http://j-chkmail . ensmp . fr)! X-Spam: no; 0.00; variants:01 variants:01 labltk:01 overloading:01 ocaml:01 overloading:01 constructors:01 constructors:01 polymorphism:01 orthogonal:01 structurally:01 ocaml:01 bool:01 bool:01 idioms:01 From: Tom > 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) * refinement types: define a type with all constructors, and have restricted versions of it where only some constructors are allowed * full polymorphism, i.e. polymorphic variants If you eliminate the first option, then the choice is between refinement types and polymorphic variants. Refinement types are rather attractive: they combine precise typing with explicit declarations. The arguments in favour of polymorphic variants are * they were somehow easier to add, as they are an orthogonal extension of the type system * one can add new cases afterwards. * they are defined structurally: two identical definitions in two different modules are equivalent. This can be pretty handy at times. * you don't need to open a module to use them: mixes nicely with ocaml programming style >>From modularity considerations, it ends up being nicer to write type t = [`A of int |`B of bool] type u = [t | `C of char] than type u = A of int | B of bool | C of char type t = u[A B] Afterwards I discovered that, using some idioms, they also allow extensible programs in a very concise way. (Much more concise than objects, when they are relevant.) > Doesn't the use of polymorphic variants just mess up the function type? What do you mean by "mess up the function type"? If you mean that, without type annotations, types and errors become very hard to read, this is true, but the manual explicitely encourages to add type annotations :-) > I'm not orthogonally against polymorphic variants, it's just that I am > looking for an alternative concept that could be used instead... Maybe > subtyped records? In terms of expressiveness, you can simulate polymorphic variants using objects (which are subtyped records,) but this is often much more verbose, and requires higher order types. I have some code using objects (visitor pattern), recursive modules, lazyness, and private row types, in an utterly non trivial way, just to do what can be done by standard recursive function definitions using polymorphic variants... Jacques Garrigue