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.9 required=5.0 tests=AWL,MAILTO_TO_SPAM_ADDR, SPF_SOFTFAIL autolearn=disabled version=3.1.3 Received: from mail4-relais-sop.national.inria.fr (mail4-relais-sop.national.inria.fr [192.134.164.105]) by yquem.inria.fr (Postfix) with ESMTP id 52218BC69 for ; Wed, 14 Nov 2007 01:22:06 +0100 (CET) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AgAAADrOOUdCbwQanmdsb2JhbACOewEBAQEHBAYRGA X-IronPort-AV: E=Sophos;i="4.21,412,1188770400"; d="scan'208";a="19251403" Received: from out2.smtp.messagingengine.com ([66.111.4.26]) by mail4-smtp-sop.national.inria.fr with ESMTP; 14 Nov 2007 01:22:05 +0100 Received: from compute1.internal (compute1.internal [10.202.2.41]) by out1.messagingengine.com (Postfix) with ESMTP id 095A446E7B; Tue, 13 Nov 2007 19:22:04 -0500 (EST) Received: from heartbeat1.messagingengine.com ([10.202.2.160]) by compute1.internal (MEProxy); Tue, 13 Nov 2007 19:22:04 -0500 X-Sasl-enc: 7+amVlvmLdBCdxczItMtMdRhdPSB5ZUJVc6Sxgx36tCJ 1194999723 Received: from [192.168.1.11] (unknown [90.46.66.162]) by mail.messagingengine.com (Postfix) with ESMTP id 078F3DC93; Tue, 13 Nov 2007 19:22:02 -0500 (EST) Date: Wed, 14 Nov 2007 01:21:53 +0100 (CET) From: Martin Jambon X-X-Sender: martin@martin.ec.wink.com To: Yaron Minsky Cc: Edgar Friendly , caml-list Subject: Re: [Caml-list] Compiler feature - useful or not? In-Reply-To: <891bd3390711131608g48b584a4n6b0ccab95d7de3f3@mail.gmail.com> Message-ID: References: <473A363F.2080301@gmail.com> <891bd3390711131608g48b584a4n6b0ccab95d7de3f3@mail.gmail.com> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed X-Spam: no; 0.00; ens-lyon:01 compiler:01 yaron:01 minsky:01 sig:01 val:01 val:01 implements:01 ocaml:01 ocaml:01 variants:01 functors:01 sig:01 functor:01 struct:01 On Tue, 13 Nov 2007, Yaron Minsky wrote: > There's a simple trick that Steven Weeks introduced to us and that we now > use at Jane Street for this kind of thing. > > You write down a signature: > > module type Abs_int : sig > type t > val to_int : t -> int > val of_int : int <- t > end > > And then you write concrete module Int that implements this signature. You > can then write: > > module Row : Abs_int = Int > module Col : Abs_int = Int > > You can now use Row.t and Col.t as abstract types. The boilerplate is > written once, but can be used over and over. I've personally seen more > use-cases for this with strings than with ints (to separate out different > kinds of identifiers) That's the best solution I've seen so far. Otherwise there's still the following: http://martin.jambon.free.fr/ocaml.html#opaque which in theory doesn't require new module or type declarations, but it adds type parameters, which can be confusing. Martin > y > > On Nov 13, 2007 6:41 PM, Edgar Friendly wrote: > >> When one writes >> >> type row = int >> type col = int >> >> This allows one to use the type names "row" and "col" as synonyms of >> int. But it doesn't prevent one from using a value of type row in the >> place of a value of type col. OCaml allows us to enforce row as >> distinct from int two ways: >> >> 1) Variants: >> type row = Row of int >> type col = Col of int >> >> Downside: unnecessary boxing and tagging >> conversion from row -> int: (fun r -> match r with Row i -> i) >> conversion from int -> row: (fun i -> Row i) >> >> 2) Functors: >> module type RowCol = >> sig >> type row >> val int_of_row : row -> int >> val row_of_int : int -> row >> type col >> val int_of_col : col -> int >> val col_of_int : int -> col >> end >> >> module Main = functor (RC: RowCol) -> struct >> (* REST OF PROGRAM HERE *) >> end >> >> Any code using rows and cols could be written to take a module as a >> parameter, and because of the abstraction granted when doing so, type >> safety is ensured. >> >> Downside: functor overhead, misuse of functors, need to write >> boilerplate conversion functions >> conversion from row -> int, int -> row: provided by RowCol boilerplate >> >> IS THE FOLLOWING POSSIBLE: >> Modify the type system such that one can declare >> >> type row = new int >> type col = new int >> >> Row and col would thus become distinct from int, and require explicit >> casting/coercion (2 :> row). There would be no runtime overhead for use >> of these types, only bookkeeping overhead at compilation. >> >> Downside: compiler changes (hopefully not too extensive) >> conversion from row -> int: (fun r -> (r :> int)) (* might need (r : row >> :> int) if it's not already inferred *) >> conversion from int -> row: (fun i -> (i :> row)) >> >> Thoughts? Do any of you use Variants or Functors to do this now? Do >> you find this style of typing useful? >> >> E. >> >> _______________________________________________ >> Caml-list mailing list. Subscription management: >> http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list >> Archives: http://caml.inria.fr >> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners >> Bug reports: http://caml.inria.fr/bin/caml-bugs >> > -- http://wink.com/profile/mjambon http://martin.jambon.free.fr