From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail3-relais-sop.national.inria.fr (mail3-relais-sop.national.inria.fr [192.134.164.104]) by sympa.inria.fr (Postfix) with ESMTPS id 1A1E67EEBF for ; Fri, 24 Jul 2015 22:25:19 +0200 (CEST) Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of yallop@gmail.com) identity=pra; client-ip=209.85.217.169; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="yallop@gmail.com"; x-sender="yallop@gmail.com"; x-conformance=sidf_compatible Received-SPF: Pass (mail3-smtp-sop.national.inria.fr: domain of yallop@gmail.com designates 209.85.217.169 as permitted sender) identity=mailfrom; client-ip=209.85.217.169; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="yallop@gmail.com"; x-sender="yallop@gmail.com"; x-conformance=sidf_compatible; x-record-type="v=spf1" Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of postmaster@mail-lb0-f169.google.com) identity=helo; client-ip=209.85.217.169; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="yallop@gmail.com"; x-sender="postmaster@mail-lb0-f169.google.com"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A0CMAQBonrJVm6nZVdFchFIGgx2tK5J5AoFDB0wBAQEBAQESAQEBAQEGCwsJIS6EIwEBAQMBEhEEGQEbHQEDAQsGBQsNAgImAgIiAREBBQEcBhMih3YBAwoIq1aBLD4xiz+BbIJ5T4pVChknDVeEWAEBAQcBAQEBARcBBQ6BFIorhDwYMweCaYFDBYxBiCKMPIFFhy+MT4IXEiOBFReEDT0xgksBAQE X-IPAS-Result: A0CMAQBonrJVm6nZVdFchFIGgx2tK5J5AoFDB0wBAQEBAQESAQEBAQEGCwsJIS6EIwEBAQMBEhEEGQEbHQEDAQsGBQsNAgImAgIiAREBBQEcBhMih3YBAwoIq1aBLD4xiz+BbIJ5T4pVChknDVeEWAEBAQcBAQEBARcBBQ6BFIorhDwYMweCaYFDBYxBiCKMPIFFhy+MT4IXEiOBFReEDT0xgksBAQE X-IronPort-AV: E=Sophos;i="5.15,540,1432591200"; d="scan'208";a="141122848" Received: from mail-lb0-f169.google.com ([209.85.217.169]) by mail3-smtp-sop.national.inria.fr with ESMTP/TLS/RC4-SHA; 24 Jul 2015 22:25:18 +0200 Received: by lbbzr7 with SMTP id zr7so21969692lbb.1 for ; Fri, 24 Jul 2015 13:25:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type:content-transfer-encoding; bh=fjO22799nSLvxtOGIHfh5apPayZvmk4BgcLXKj6sfM8=; b=WZYLIRT9tf5x64nqvHvUa5EqSoYI2Us1ZRmSjkwcAQk+wKZw2vq9aJiD2iMOG3ON8h XipgRWQq0WgvVmDKxsSVEPg7JtRJ/PfA/LKqCi1WeKX8Jrw1/e5TiEuY7GU/ytgMcEW0 rsAyXNK1Oom49EkcKHW2id96KLwnMPkFp5KRsm64023xVWVQNKXLUlxUk9Mdvs08g/FU OUOaR0I8vn7wCI3jRkbvis4END6dJt4JL8U4lZc1at+EtJPl8/hhCJDP/dRgM0ZUJPh3 3qDHGsJHTUNOBbfwvfY3sjrkUd16AK9OCC0k4IGrLsNdc7mXUYC22LzvKpUuoFOh5pjl dXmQ== MIME-Version: 1.0 X-Received: by 10.112.157.36 with SMTP id wj4mr15383966lbb.115.1437769517579; Fri, 24 Jul 2015 13:25:17 -0700 (PDT) Received: by 10.25.199.10 with HTTP; Fri, 24 Jul 2015 13:25:17 -0700 (PDT) In-Reply-To: References: Date: Fri, 24 Jul 2015 21:25:17 +0100 Message-ID: From: Jeremy Yallop To: =?UTF-8?Q?Markus_Wei=C3=9Fmann?= Cc: Caml List Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Subject: Re: [Caml-list] Clever typing for client-server communication? On 24 July 2015 at 12:01, Markus Wei=C3=9Fmann = wrote: > but is there some clever way to only have the socket annotated with one t= ype > while keeping only one send and one recv function? One way to achieve this is to add some structure to the 'server' and 'client' types, by turning your descriptions of the desired behaviour into code. For example, you say > There is a server and a client which can only send "client" (client to > server) and "server" (server to client) messages. which you might encode as follows: type server =3D < src: server; dst: client; name: [`server] > and client =3D < src: client; dst: server; name: [`client] > These are object types, but there's no need to actually use object values in your code. The object type syntax is simply a convenient way to label the different components of the type so that they can be retrieved later. Once you have these types you might write type-level functions to retrieve the components. Here's a function that retrieves the 'src' component: type 'a src =3D 's constraint 'a =3D < src: 's; .. > This can be read as follows: src is a function that maps 'a to 's, where 'a is an object type with a src key, and 's is the value of that key. Similarly, here's a function to retrieve the 'dst' component: type 'a dst =3D 'd constraint 'a =3D < dst: 'd; .. > > You can only send "client messages" on the "client socket" and "server > messages" on the "server socket". > > val send : ('a, _) socket -> 'a message -> unit > > You can get these messages only on the respective other side. > > val recv : (_, 'b) socket -> 'b message > > Something in the spirit of this: > > type 'a socket > val send : 'a socket -> 'a message -> unit > val recv : [server socket -> client message | client socket -> server > message] You might then write val send : 's socket -> 's src message -> unit val recv : 's socket -> 's dst message and OCaml will enforce the constraints you describe. Kind regards, Jeremy.