From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail1-relais-roc.national.inria.fr (mail1-relais-roc.national.inria.fr [192.134.164.82]) by walapai.inria.fr (8.13.6/8.13.6) with ESMTP id pBMLQqmY008132 for ; Thu, 22 Dec 2011 22:26:52 +0100 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AtUBANuf807UGyoFk2dsb2JhbABDrDAiAQEBAQkJCwkUAyKCIAsBgTuIWJdun1CIdYI3YwSVAIVfjFU X-IronPort-AV: E=Sophos;i="4.71,395,1320620400"; d="scan'208";a="136523522" Received: from smtp5-g21.free.fr ([212.27.42.5]) by mail1-smtp-roc.national.inria.fr with ESMTP; 22 Dec 2011 22:26:49 +0100 Received: from yeeloong (unknown [82.67.194.89]) by smtp5-g21.free.fr (Postfix) with SMTP id 536F1D48574 for ; Thu, 22 Dec 2011 22:26:41 +0100 (CET) Received: by yeeloong (sSMTP sendmail emulation); Thu, 22 Dec 2011 22:24:30 +0100 Date: Thu, 22 Dec 2011 22:24:30 +0100 From: rixed@happyleptic.org To: caml-list@inria.fr Message-ID: <20111222212429.GA8156@yeeloong.happyleptic.org> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit User-Agent: Mutt/1.5.21 (2010-09-15) Subject: [Caml-list] Bless me Father, for I have used Obj.magic 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?