From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail4-relais-sop.national.inria.fr (mail4-relais-sop.national.inria.fr [192.134.164.105]) by walapai.inria.fr (8.13.6/8.13.6) with ESMTP id p4H4QRkq016069 for ; Tue, 17 May 2011 06:26:27 +0200 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AukCADn40U3ZSMDjkWdsb2JhbACmFxQBAQEBCQsLBxQDIohwvjGGGQSUQIQchiw X-IronPort-AV: E=Sophos;i="4.65,223,1304287200"; d="scan'208";a="99170463" Received: from fmmailgate02.web.de ([217.72.192.227]) by mail4-smtp-sop.national.inria.fr with ESMTP; 17 May 2011 06:26:25 +0200 Received: from smtp04.web.de ( [172.20.0.225]) by fmmailgate02.web.de (Postfix) with ESMTP id 1F1DA19FC83CD; Tue, 17 May 2011 06:26:25 +0200 (CEST) Received: from [78.43.204.177] (helo=frosties.localnet) by smtp04.web.de with asmtp (TLSv1:AES256-SHA:256) (WEB.DE 4.110 #2) id 1QMBrU-0001xR-00; Tue, 17 May 2011 06:26:24 +0200 Received: from mrvn by frosties.localnet with local (Exim 4.72) (envelope-from ) id 1QMBrT-0007aF-Q8; Tue, 17 May 2011 06:26:23 +0200 From: Goswin von Brederlow To: Gabriel Scherer Cc: Goswin von Brederlow , Joel Reymont , caml-list References: <87wrhr9n88.fsf@frosties.localnet> Date: Tue, 17 May 2011 06:26:21 +0200 In-Reply-To: (Gabriel Scherer's message of "Mon, 16 May 2011 09:07:25 +0200") Message-ID: <877h9qt0k2.fsf@frosties.localnet> User-Agent: Gnus/5.110009 (No Gnus v0.9) XEmacs/21.4.22 (linux, no MULE) MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 8bit Sender: goswin-v-b@web.de X-Sender: goswin-v-b@web.de X-Provags-ID: V01U2FsdGVkX1//pT2oSyEbqjZ8KYrj1HR8b6Oo9B9Qa7RDEFF3 HHfd7zaQKXnVZB8IuNG3YllLLc9mw5bUtvFcAp3qBaIg6bVTZI mqF8182FI= Subject: Re: [Caml-list] do i need a private row type? Gabriel Scherer writes: > On Mon, May 16, 2011 at 8:24 AM, Goswin von Brederlow > wrote: > > First thing is that if you have different 'a poll_items then you need to > include a callback that accepts a matching 'a Socket.t. E.g.: > > type 'a poll_item = ('a Socket.t * event_mask * ('a Socket.t -> event_mask > -> unit)) > > Then you can make an unit poll_item array and use > > let set i (item : 'a poll_item) = >    array.[i] <- Obj.magic item > > let call i = >    let (sock, mask, fn) = array.[i] >    in >    fn sock mask > > The important part here is that you ensure the 'a Socket.t is only > accessed through the callback. Only that will have the right type. > > > If "call" is the only thing you wish to do on your array, you don't need such > an ugly solution. "sock" and "mask" being constants for a given item, you can > simply capture them in a closure. > >   type poll_item_thunk = unit -> unit > >   let set i (socket, event_mask, callback) = >     array.(i) <- (fun () -> callback socket event_mask); > >   let call i = array.(i) () > > > There is no reasonable answer to "how do I force OCaml into breaking type > safety ?". Joel must have an use case in mind which is actually type-safe; > maybe it's only the callback as you demonstrated (I fail to see its usefulness, > but I don't know anything about ZeroMQ), maybe it's something a bit more > complicated. But we won't be able to give him a satisfying solution unless he > describes more precisely what this type-safe use is. This is still type safe given sufficient encapsulation in a module so it can't be abused. But as I said, it is the dirty solution, like anything requireing Obj.magic is. And you are right, if all you have is one callback then a simple closure is better. But you also need access to the Unix.file_descr underlying the socket to select on it. And then you need a second callback to handle error conditions. And then your socket probably has some state and things become mutable and closures quickly become ugly and use up a lot more memory if you have many sockets. > The most general solution, as you alluded, is to use existential types. This > can be done by an encoding into universal types (this is the "2 records" > approach), or using first-class modules and abstract types. I haven't tried this with first-class modules and the better support for abstract types yet. But I would be interested to see in how they improve on the 2 records solution. Another thing I didn't mention is to use objects. This use case is actually the poster child for objects with virtual functions. > Joel, may you be more explicit as to what you want to do with those "poll_item" > array. More precisely, how do you plan to *use* the data in the array? MfG Goswin