[
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: | David Allsopp <dra-news@m...> |
| Subject: | RE: [Caml-list] Converting variants with only constant constructors to integers |
Gabriel Scherer wrote: > Incidentally, the general function for getting a unique integer for a > variant type with non-constant constructors isn't that bad either: > > let int_of_gen x = > let x = Obj.repr x > in > if Obj.is_block x > then -1 * Obj.tag x - 1 > else (Obj.magic x : int) > > I consider that version much better. You could also write it in a more restrictive way : > > let to_int x = > let repr = Obj.repr x in > if Obj.is_int repr > then (Obj.obj repr : int) > else invalid_arg "to_int";; (that doesn't quite do the same thing but I don't think that was your point) My "problem" is that for each specific case where it's only constant constructors, I can't help but feel guilty that code will execute for the conversion of a value to the same value (%identity is a no-op most of the time). It's not that everything has to be pointlessly micro-optimised, but you know what I mean? > The good point about those is that they check that the memory representation is compatible > before casting (while the "%identity" does not). They're safer. Of course, they still break > parametricity if used polymorphically, so as you said type should be constrained. > I still would prefer the more direct pattern-matching definition : it may require code > generation not to be tedious, but the generated code is an honourable OCaml citizen. Of course, if you have the following: type t = A | B | C let int_of_t = function A -> 0 | B -> 1 | C -> 2 Then in fact I believe that the compiler already converts that to a hashtable lookup instead of a sequence of jumps so it would be fairly reasonable (and easy) to have the compiler spot that the match is exactly a conversion to the tag value and so remove the match completely (and given that the compiler already has two different strategies for match clauses, it's not even that inconsistent). camlp4 of course solves the generation problem (but there's no need to tell you that!!) David