Version française
Home     About     Download     Resources     Contact us    
Browse thread
Obj.magic
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Daniel de Rauglaudre <daniel.de_rauglaudre@i...>
Subject: Re: Obj.magic
Hello,

On Fri, Jun 09, 2000 at 10:57:28AM +0200, David Chemouil wrote:

> I'd like to get information about Obj.magic. I know it is some kind of
> identity function `a -> `b, but I'd like to know how it can be used, why
> it can be interesting and why, also, it is sometimes dangerous
> (considering some older posts on this mailing-list).

I use Obj.magic:

1/ In Camlp4 in extensible grammars to type parsing trees
2/ In GeneWeb in my data base system to optimize disk access

  ---

1/ Camlp4 provides a system of extensible grammars.

When I write a code like this (Camlp4 syntax):

   EXTEND
     expr:
       [ [ x = expr; "+"; y = expr -> x + y
         | z = int -> z ] ];
   END

It is converted into something like this:

   extend expr
     [ ([Nterm expr; Term "+"; Nterm expr], fun x y -> x + y);
       ([Nterm int], fun z -> z) ]

But it is bad typed for several reasons: one of them (that you can
see) is that the functions in the right part of these two couples have
different types. Another one is that the Camlp4 constructor "Nterm"
accepts any kind of 'a entry and it is perfectly possible to have a
"int entry" and a "string entry" in the same list.

To resolve that, I use Obj.magic and type constraints to type this
expression. The code is actually something like this:

   extend (Obj.magic expr : 'a entry)
     [ ([Nterm (Obj.magic (expr : 'a1 entry)); Term "+";
         Nterm (Obj.magic (expr : 'a2 entry))],
              (Obj.magic (fun (x : 'a1) (y : 'a2) -> (x + y : 'a))));
       ([Nterm (Obj.magic (int : 'a3 entry))],
              (Obj.magic (fun (z : 'a3) -> (z : 'a)))) ]

In this example, the normal type inferrence of Ocaml gives the type
"int" to all of these above type variables 'a, 'a1, 'a2, and 'a3.
However, in the general case, any types could be inferred.

I absolutely need to give to the function "extend" the parameters with
this form because I want to be able to extend the entry again: internally,
I record a parsing tree (for left factorization) and I need the details of
this tree to apply associativity rules.

They are trees with these parsing patterns at each node and functions
at each leaf. All patterns can have different types. A function in a
given leaf has n parameters where n is the length of the path from the
root to the leaf. The type of its parameters is respectively the same
than the type of all patterns of the path (in the same order). The
result type of all functions is the same.

It is not dangerous if this type extension is correct. (Not proved but
I have used it since several years...)

  ---

2/ In GeneWeb (genealogy software).

The normal "input_value" of Ocaml is written in C. I use it to very quickly
input large array of records (input_value is very fast). But I sometimes need
to read just one record in such arrays. For that, I wrote an input_value
function for an array item (the offset have been previously computed). This
function needs Obj.magic.

It is dangerous if the data on disk is not of the good type. Actually it
is not more dangerous than input_value.

-- 
Daniel de Rauglaudre
daniel.de_rauglaudre@inria.fr
http://cristal.inria.fr/~ddr/