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 p4G77p49025575 for ; Mon, 16 May 2011 09:07:51 +0200 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AnsDAE/M0E3RVdQ2imdsb2JhbACXWoZiAYdNCBQBAQEKCQ0HEgYhiHCiF4wagjWEFDeIYgEBAwaGEwSCMY1giEuCOjuDNw X-IronPort-AV: E=Sophos;i="4.64,373,1301868000"; d="scan'208";a="99098890" Received: from mail-vw0-f54.google.com ([209.85.212.54]) by mail4-smtp-sop.national.inria.fr with ESMTP/TLS/RC4-MD5; 16 May 2011 09:07:46 +0200 Received: by vws18 with SMTP id 18so5907229vws.27 for ; Mon, 16 May 2011 00:07:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc:content-type; bh=UIdQuWDWOrKUJRiDEcKYVNplpe3tzBV+srhucwbb7Ck=; b=Kvo9M1I0s0dL1UDAs7x0dO05w+teBkQPTIAToso+2fHdbZ7iDX5HfPMPt5gtX502Ok PV0h2pjdamXPiJmNIDgfLxumeongdAyKjzWeFEp1ZgrDkTeHb/WmhmA3Y2jKv/TzeZCp gWv8wNH7nuVNjZwqAgbYLEKp5p+882yb3kS1s= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc:content-type; b=D/X71LrdMm4ShiFde2VEQx4yKX+P4KlHsJHjYBXhyxgH/navUhUGJZCUPt/0jKGECi DVDgEwWmhNcIrJj1WQhyZmPExhju1v8KdHjj7+HVn+AdSMzPaXihgw/U2iJik9kWT51s 8Go4bCWAOouoNoy+s6G5ktjKhBCcJZExtwMMQ= Received: by 10.52.115.72 with SMTP id jm8mr3074382vdb.93.1305529665066; Mon, 16 May 2011 00:07:45 -0700 (PDT) MIME-Version: 1.0 Received: by 10.52.183.136 with HTTP; Mon, 16 May 2011 00:07:25 -0700 (PDT) In-Reply-To: <87wrhr9n88.fsf@frosties.localnet> References: <87wrhr9n88.fsf@frosties.localnet> From: Gabriel Scherer Date: Mon, 16 May 2011 09:07:25 +0200 Message-ID: To: Goswin von Brederlow Cc: Joel Reymont , caml-list Content-Type: multipart/alternative; boundary=bcaec548a445ee15cd04a35f4f36 Subject: Re: [Caml-list] do i need a private row type? --bcaec548a445ee15cd04a35f4f36 Content-Type: text/plain; charset=ISO-8859-1 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. 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. 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? Joel Reymont writes: > > > https://github.com/wagerlabs/ocaml-zmq/blob/master/src/ZMQ.ml > > > > Looking at the Poll module at the bottom and the definition of poll_item > as > > > > type 'a poll_item = ('a Socket.t * event_mask) > > > > I would like to be able to put different 'a in the same poll_item array. > > > > This is not possible as written, e.g. > > > > Error: This expression has type > > ZMQ.Socket.pub ZMQ.Socket.t * ZMQ.Poll.event_mask > > but an expression was expected of type > > ZMQ.Socket.pull ZMQ.Socket.t * ZMQ.Poll.event_mask > > > > How do I type poll_item and poll_item array so that the array is > polymorphic with respect to 'a? > > > > Does the definition of Socket a the top of ZMQ.ml need to be changed to > make this possible? > > > > Thanks, Joel > > How clean do you want this to be? Lets go with easy and dirty. > > 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 you want to make it clean then you need a 2 layer approach with 2 > records and 'a. 'a -> 'b style types. I can't remember how to do this > from memory but search the list archive for something like universal > container. I've asked the same a few years back. > > MfG > Goswin > > -- > Caml-list mailing list. Subscription management and archives: > https://sympa-roc.inria.fr/wws/info/caml-list > Beginner's list: http://groups.yahoo.com/group/ocaml_beginners > Bug reports: http://caml.inria.fr/bin/caml-bugs > > --bcaec548a445ee15cd04a35f4f36 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable
On Mon, May 16, 2011 at 8:24 AM, Goswin von Bred= erlow <goswin-v-b= @web.de> wrote:
First thing is that if you have different 'a poll_items then you need t= o
include a callback that accepts a matching 'a Socket.t. E.g.:

type 'a poll_item =3D ('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) =3D
=A0 =A0array.[i] <- Obj.magic item

let call i =3D
=A0 =A0let (sock, mask, fn) =3D array.[i]
=A0 =A0in
=A0 =A0fn 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 closur= e.

=A0 type poll_item_thunk =3D unit -> unit

=A0 let set i (sock= et, event_mask, callback) =3D
=A0=A0=A0 array.(i) <- (fun () -> ca= llback socket event_mask);

=A0 let call i =3D 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&#= 39;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-sa= fe use is.

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.
Joel, may you be more explicit as to what you want to do with those &qu= ot;poll_item" array. More precisely, how do you plan to *use* the data= in the array?

Joel Reymont <joel= r1@gmail.com> writes:

> https://github.com/wagerlabs/ocaml-zmq/blob/master/sr= c/ZMQ.ml
>
> Looking at the Poll module at the bottom and the definition of poll_it= em as
>
> =A0 type 'a poll_item =3D ('a Socket.t * event_mask)
>
> I would like to be able to put different 'a in the same poll_item = array.
>
> This is not possible as written, e.g.
>
> Error: This expression has type
> =A0 =A0 =A0 =A0 =A0ZMQ.Socket.pub ZMQ.Socket.t * ZMQ.Poll.event_mask > =A0 =A0 =A0 =A0but an expression was expected of type
> =A0 =A0 =A0 =A0 =A0ZMQ.Socket.pull ZMQ.Socket.t * ZMQ.Poll.event_mask<= br> >
> How do I type poll_item and poll_item array so that the array is polym= orphic with respect to 'a?
>
> Does the definition of Socket a the top of ZMQ.ml need to be changed t= o make this possible?
>
> =A0 =A0 =A0 Thanks, Joel

How clean do you want this to be? Lets go with easy and dirty.

First thing is that if you have different 'a poll_items then you need t= o
include a callback that accepts a matching 'a Socket.t. E.g.:

type 'a poll_item =3D ('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) =3D
=A0 =A0array.[i] <- Obj.magic item

let call i =3D
=A0 =A0let (sock, mask, fn) =3D array.[i]
=A0 =A0in
=A0 =A0fn 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 you want to make it clean then you need a 2 layer approach with 2
records and 'a. 'a -> 'b style types. I can't remember h= ow to do this
from memory but search the list archive for something like universal
container. I've asked the same a few years back.

MfG
=A0 =A0 =A0 =A0Goswin

--
Caml-list mailing list. =A0Subscription management and archives:
https://sympa-roc.inria.fr/wws/info/caml-list
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs


--bcaec548a445ee15cd04a35f4f36--