Browse thread
Compiler feature - useful or not?
[
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: | Martin Jambon <martin.jambon@e...> |
| Subject: | Re: [Caml-list] Compiler feature - useful or not? |
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 <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 >> > -- http://wink.com/profile/mjambon http://martin.jambon.free.fr