English version
Accueil     Ŕ propos     Téléchargement     Ressources     Contactez-nous    

Ce site est rarement mis ŕ jour. Pour les informations les plus récentes, rendez-vous sur le nouveau site OCaml ŕ l'adresse ocaml.org.

Browse thread
Converting variants with only constant constructors to integers
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: 2010-06-08 (09:14)
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

> 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!!)