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=1.7 required=5.0 tests=HTML_MESSAGE, MAILTO_TO_SPAM_ADDR,SPF_NEUTRAL 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 86195BC69 for ; Wed, 14 Nov 2007 01:08:04 +0100 (CET) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Ah4FAMLKOUdIDsq1Y2dsb2JhbACCPTaLfhQFBRIR X-IronPort-AV: E=Sophos;i="4.21,412,1188770400"; d="scan'208";a="19251117" Received: from ro-out-1112.google.com ([72.14.202.181]) by mail4-smtp-sop.national.inria.fr with ESMTP; 14 Nov 2007 01:08:03 +0100 Received: by ro-out-1112.google.com with SMTP id k5so3370959rog for ; Tue, 13 Nov 2007 16:08:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=beta; h=domainkey-signature:received:received:message-id:date:from:sender:to:subject:cc:in-reply-to:mime-version:content-type:references:x-google-sender-auth; bh=h2sbSb916aMcSZme0KUq/Hv8ioDWrqpe7NEVgEScQKI=; b=dbg3+yBcTWFXZgD2s7aebg8c0HsaNQ7Pq2xSXbzd+ShqBZk2yxMmv+tcOlvBhGcAN2mGaftPJ+YVoJEJ01Agg5ro41102nLvV79GfkkFUjo1ag6RIJFzGRCWhIRjfiaFAFUiOAJ/JsWl3vzura12DPWJwjCZ0t+SbCw/+3lKtaU= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=beta; h=received:message-id:date:from:sender:to:subject:cc:in-reply-to:mime-version:content-type:references:x-google-sender-auth; b=ewdPWDaeupPZd/chKOKKha+kX2A3q2NP30mXt6c7c3upcUNBi0dAJD29qGF4j8rKJW26QHOkk/TOSzs+v8ppsQ+ep6Az9dRuCxpqEpfa3t7/ZQWt4Bk8g8VVU2fzrJbHPn3NhnK8b7uVOzPCsHU4ZRM0VnpLZcjfd8QP0IdD7Dk= Received: by 10.141.195.18 with SMTP id x18mr475932rvp.1194998881219; Tue, 13 Nov 2007 16:08:01 -0800 (PST) Received: by 10.141.87.4 with HTTP; Tue, 13 Nov 2007 16:08:01 -0800 (PST) Message-ID: <891bd3390711131608g48b584a4n6b0ccab95d7de3f3@mail.gmail.com> Date: Tue, 13 Nov 2007 19:08:01 -0500 From: "Yaron Minsky" Sender: yminsky@gmail.com To: "Edgar Friendly" Subject: Re: [Caml-list] Compiler feature - useful or not? Cc: caml-list In-Reply-To: <473A363F.2080301@gmail.com> MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="----=_Part_2419_27699295.1194998881241" References: <473A363F.2080301@gmail.com> X-Google-Sender-Auth: 10d81a0f2ee0ee8a X-Spam: no; 0.00; yaron:01 minsky:01 yminsky:01 compiler:01 sig:01 val:01 val:01 implements:01 ocaml:01 variants:01 functors:01 sig:01 functor:01 struct:01 abstraction:01 ------=_Part_2419_27699295.1194998881241 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline 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) 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 > ------=_Part_2419_27699295.1194998881241 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline 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)

y

On Nov 13, 2007 6:41 PM, Edgar Friendly <thelema314@gmail.com> 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

------=_Part_2419_27699295.1194998881241--