caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] Bless me Father, for I have used Obj.magic
@ 2011-12-22 21:24 rixed
  2011-12-22 22:07 ` Fabrice Le Fessant
  2011-12-22 23:29 ` Thierry Martinez
  0 siblings, 2 replies; 7+ messages in thread
From: rixed @ 2011-12-22 21:24 UTC (permalink / raw)
  To: caml-list

I have these types:

type t = { operation : t1 -> t2 ;
           some_fields : of_some_types }
type t_priv = { t : t ;
                some_other_fields : of_some_other_types }

In other words, I have a "super" type t that's further specialized
by t_priv, which is hidden within t.operation as shown below in the
constructor for t values :

let make ... =
	let some_operation t_priv t1 =
		... use t_priv to return a t2 ... in
	let rec t_priv = { t ;
	                   some_other_fields = some_values }
	and t = { operation = some_operation t_priv ;
	          some_fields = some_values }
	in t

This does not compile because of the way t_priv is used within t
construction. The policed way to get around this seams to be:

type t_priv = { mutable t : t option ;
                some_other_fields : of_some_other_types }
and then:

let make ... =
	...
	let t_priv = { t = None ; ... } in
	let t = { operation = some_operation t_priv ; ... } in
	t_priv.t <- Some t in
	t

But then every time one need to use t_priv.t one use to deconstruct the
option (equivalent of what one would do using dark age languages
checking at runtime for proper initialization of a field).

So I ended up doing:

type t_priv = { mutable t : t ; (* look ma! no option! *)
                some_other_fields : of_some_other_types }

let make ... =
	...
	let t_priv = { t = Obj.magic 0 ; (* Frères humains qui après nous codez... *)
	               ... } in
	t_priv.t <- { operation = some_operation t_priv ; ... } in
	t_priv.t

In my simplistic model of what's happening under the hood, the object
for t_priv will hold for a moment a 0 in its t field instead of a
pointer to a legitimate t object, but that's not a problem even if the
GC awakes right at that moment since it does not use the actual types
(they are gone by then) but the tags, and the 0 is tagged as an integer
so from its point of view all is fine.  And apparently the program is
running well.

Should I fear some backfire?


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Caml-list] Bless me Father, for I have used Obj.magic
  2011-12-22 21:24 [Caml-list] Bless me Father, for I have used Obj.magic rixed
@ 2011-12-22 22:07 ` Fabrice Le Fessant
  2011-12-22 22:19   ` rixed
  2011-12-22 23:29 ` Thierry Martinez
  1 sibling, 1 reply; 7+ messages in thread
From: Fabrice Le Fessant @ 2011-12-22 22:07 UTC (permalink / raw)
  To: caml-list

[-- Attachment #1: Type: text/plain, Size: 918 bytes --]

On 12/22/2011 10:24 PM, rixed@happyleptic.org wrote:
> I have these types:
> 
> type t = { operation : t1 -> t2 ;
>            some_fields : of_some_types }
> type t_priv = { t : t ;
>                 some_other_fields : of_some_other_types }

> Should I fear some backfire?

You might one day forget this [Obj.magic], and access the field [t] that
has not yet been initialized, and get a segfault.

My advise would be to first create a dummy [t] record:

let dummy_t = { operation = (fun _ -> failwith "t not initialized");
                some_fields = ... some dummy initializer .. }

and use it as the initial value for uninitialized values.

let t_priv = { t = dummy_t; ... }
in
let t = make_operations t_priv in
t_priv.t <- t

The good thing is that, since it is uniq in your program, you can test
if t_priv was initialized easily:

if t_priv.t == dummy_t then failwith "t_priv not yet constructed !"

--Fabrice

[-- Attachment #2: fabrice_le_fessant.vcf --]
[-- Type: text/x-vcard, Size: 380 bytes --]

begin:vcard
fn:Fabrice LE FESSANT
n:LE FESSANT;Fabrice
org:INRIA Saclay -- Ile-de-France;P2P & OCaml
adr;quoted-printable:;;Parc Orsay Universit=C3=A9 ;Orsay CEDEX;;91893;France
email;internet:fabrice.le_fessant@inria.fr
title;quoted-printable:Charg=C3=A9 de Recherche
tel;work:+33 1 74 85 42 14
tel;fax:+33 1 74 85 42 49 
url:http://fabrice.lefessant.net/
version:2.1
end:vcard


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Caml-list] Bless me Father, for I have used Obj.magic
  2011-12-22 22:07 ` Fabrice Le Fessant
@ 2011-12-22 22:19   ` rixed
  0 siblings, 0 replies; 7+ messages in thread
From: rixed @ 2011-12-22 22:19 UTC (permalink / raw)
  To: caml-list

-[ Thu, Dec 22, 2011 at 11:07:37PM +0100, Fabrice Le Fessant ]----
> You might one day forget this [Obj.magic], and access the field [t] that
> has not yet been initialized, and get a segfault.

As the only place where this 0 value exists is in the constructor and
it can easily be shown that the function never returns a semi-initialized
t, then this looks quite unprobable here. But I welcome the warning
nonetheless :-)

> My advise would be to first create a dummy [t] record:
> 
> let dummy_t = { operation = (fun _ -> failwith "t not initialized");
>                 some_fields = ... some dummy initializer .. }

Yes, this was my initial intention as well.
Unfortunately, my actual types are much more complex than what's shown
in the example; especially a value of type t2 is quite hairy to construct
and there are lots of operations having lots of complex output types
(records of records of functions of records...) That's why I had this
TODO note in the margin commanding to "build a dummy t to get rid of the
option type" for so long, until I had this terrible idea of using
Obj.magic.


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Caml-list] Bless me Father, for I have used Obj.magic
  2011-12-22 21:24 [Caml-list] Bless me Father, for I have used Obj.magic rixed
  2011-12-22 22:07 ` Fabrice Le Fessant
@ 2011-12-22 23:29 ` Thierry Martinez
  2011-12-23 12:04   ` rixed
  1 sibling, 1 reply; 7+ messages in thread
From: Thierry Martinez @ 2011-12-22 23:29 UTC (permalink / raw)
  To: rixed; +Cc: caml-list

rixed@happyleptic.org :
> let make ... =
> 	let some_operation t_priv t1 =
> 		... use t_priv to return a t2 ... in
> 	let rec t_priv = { t ;
> 	                   some_other_fields = some_values }
> 	and t = { operation = some_operation t_priv ;
> 	          some_fields = some_values }
> 	in t
>
> This does not compile because of the way t_priv is used within t
> construction. The policed way to get around this seams to be:

This will compile if you η-expand the partial application of
some_operation into “(fun t1 -> some_operation t_priv t1)”.

But perhaps your example is over simplified and hide the real
difficulty.

-- 
Thierry.


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Caml-list] Bless me Father, for I have used Obj.magic
  2011-12-22 23:29 ` Thierry Martinez
@ 2011-12-23 12:04   ` rixed
  2011-12-23 12:26     ` Fabrice Le Fessant
  0 siblings, 1 reply; 7+ messages in thread
From: rixed @ 2011-12-23 12:04 UTC (permalink / raw)
  To: caml-list

> This will compile if you ??-expand the partial application of
> some_operation into ???(fun t1 -> some_operation t_priv t1)???.
> 
> But perhaps your example is over simplified and hide the real
> difficulty.

No you are right, once eta-epxanded the compiler accepted the code.
I wonder what difference it makes in the generated code, if any.
Thank you very much for the tip!


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Caml-list] Bless me Father, for I have used Obj.magic
  2011-12-23 12:04   ` rixed
@ 2011-12-23 12:26     ` Fabrice Le Fessant
  2011-12-30 11:41       ` Damien Doligez
  0 siblings, 1 reply; 7+ messages in thread
From: Fabrice Le Fessant @ 2011-12-23 12:26 UTC (permalink / raw)
  To: caml-list

[-- Attachment #1: Type: text/plain, Size: 673 bytes --]

On 12/23/2011 01:04 PM, rixed@happyleptic.org wrote:
>> This will compile if you ??-expand the partial application of
>> some_operation into ???(fun t1 -> some_operation t_priv t1)???.
>>
>> But perhaps your example is over simplified and hide the real
>> difficulty.
> 
> No you are right, once eta-epxanded the compiler accepted the code.
> I wonder what difference it makes in the generated code, if any.
> Thank you very much for the tip!

The difference is that the function is evaluated everytime you want to
access the value. If the function is cheap and has no side-effect, it is
perfectly fine, but if it is not the case, the cost will be much higher.

--Fabrice


[-- Attachment #2: fabrice_le_fessant.vcf --]
[-- Type: text/x-vcard, Size: 380 bytes --]

begin:vcard
fn:Fabrice LE FESSANT
n:LE FESSANT;Fabrice
org:INRIA Saclay -- Ile-de-France;P2P & OCaml
adr;quoted-printable:;;Parc Orsay Universit=C3=A9 ;Orsay CEDEX;;91893;France
email;internet:fabrice.le_fessant@inria.fr
title;quoted-printable:Charg=C3=A9 de Recherche
tel;work:+33 1 74 85 42 14
tel;fax:+33 1 74 85 42 49 
url:http://fabrice.lefessant.net/
version:2.1
end:vcard


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Caml-list] Bless me Father, for I have used Obj.magic
  2011-12-23 12:26     ` Fabrice Le Fessant
@ 2011-12-30 11:41       ` Damien Doligez
  0 siblings, 0 replies; 7+ messages in thread
From: Damien Doligez @ 2011-12-30 11:41 UTC (permalink / raw)
  To: caml users

On 2011-12-23, at 13:26, Fabrice Le Fessant wrote:

> On 12/23/2011 01:04 PM, rixed@happyleptic.org wrote:
>> No you are right, once eta-epxanded the compiler accepted the code.
>> I wonder what difference it makes in the generated code, if any.
>> Thank you very much for the tip!
> 
> The difference is that the function is evaluated everytime you want to
> access the value. If the function is cheap and has no side-effect, it is
> perfectly fine, but if it is not the case, the cost will be much higher.

On the other hand, in the example shown by rixed the function expects
two arguments, so eta-expansion might even be more efficient because
you avoid going through the partial application machinery.

-- Damien


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2011-12-30 11:41 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-12-22 21:24 [Caml-list] Bless me Father, for I have used Obj.magic rixed
2011-12-22 22:07 ` Fabrice Le Fessant
2011-12-22 22:19   ` rixed
2011-12-22 23:29 ` Thierry Martinez
2011-12-23 12:04   ` rixed
2011-12-23 12:26     ` Fabrice Le Fessant
2011-12-30 11:41       ` Damien Doligez

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).