From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@sympa.inria.fr Delivered-To: caml-list@sympa.inria.fr 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 738F07EEBF for ; Thu, 20 Aug 2015 10:06:36 +0200 (CEST) Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of romain.bardou@inria.fr) identity=pra; client-ip=46.105.63.230; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="romain.bardou@inria.fr"; x-sender="romain.bardou@inria.fr"; x-conformance=sidf_compatible Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of romain.bardou@inria.fr) identity=mailfrom; client-ip=46.105.63.230; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="romain.bardou@inria.fr"; x-sender="romain.bardou@inria.fr"; x-conformance=sidf_compatible Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of postmaster@7.mo68.mail-out.ovh.net) identity=helo; client-ip=46.105.63.230; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="romain.bardou@inria.fr"; x-sender="postmaster@7.mo68.mail-out.ovh.net"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A0BpAgDAidVVnOY/aS5dh32/bYJYAgiBJ0wBAQEBAQESAQEBAQEGDQkJIS6EJAEBBCMPAQVAEQsYAgIFFgsCAgkDAgECAUUTCAIXiBcBuRaWAyyBIokNIYEDhFc6MYI4gUMBBJUojG+BSpUHg2mEJYM7AQEB X-IPAS-Result: A0BpAgDAidVVnOY/aS5dh32/bYJYAgiBJ0wBAQEBAQESAQEBAQEGDQkJIS6EJAEBBCMPAQVAEQsYAgIFFgsCAgkDAgECAUUTCAIXiBcBuRaWAyyBIokNIYEDhFc6MYI4gUMBBJUojG+BSpUHg2mEJYM7AQEB X-IronPort-AV: E=Sophos;i="5.15,714,1432591200"; d="scan'208";a="143330694" Received: from 7.mo68.mail-out.ovh.net ([46.105.63.230]) by mail3-smtp-sop.national.inria.fr with ESMTP/TLS/ADH-AES256-SHA; 20 Aug 2015 10:06:35 +0200 Received: from mail610.ha.ovh.net (b9.ovh.net [213.186.33.59]) by mo68.mail-out.ovh.net (Postfix) with SMTP id 0BE84FF8AA2 for ; Thu, 20 Aug 2015 10:06:35 +0200 (CEST) Received: from localhost (HELO queueout) (127.0.0.1) by localhost with SMTP; 20 Aug 2015 10:06:33 +0200 Received: from amontsouris-652-1-192-200.w90-24.abo.wanadoo.fr (HELO ?192.168.1.15?) (romain@bardou.fr@90.24.215.200) by ns0.ovh.net with SMTP; 20 Aug 2015 10:06:25 +0200 Message-ID: <55D58A7F.5030009@inria.fr> Date: Thu, 20 Aug 2015 10:06:23 +0200 From: Romain Bardou User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Icedove/31.7.0 MIME-Version: 1.0 To: caml-list@inria.fr References: <55BF75F6.1040006@bioquant.uni-heidelberg.de> <8E1A640CE3374EB492981ADB0A2DA5C6@erratique.ch> <20150804092633.GC5689@frosties> <5C2023F4AF0549F58F3E4C9A6F8ABE84@erratique.ch> <20150814105551.GD31364@frosties> <55CDD0F2.1090200@zoho.com> <20150818111134.GA11154@frosties> <55D4F1DB.5090906@polychoron.fr> In-Reply-To: <55D4F1DB.5090906@polychoron.fr> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit X-Ovh-Tracer-Id: 9980258250948381216 X-Ovh-Remote: 90.24.215.200 (amontsouris-652-1-192-200.w90-24.abo.wanadoo.fr) X-Ovh-Local: 213.186.33.20 (ns0.ovh.net) X-OVH-SPAMSTATE: OK X-OVH-SPAMSCORE: 0 X-OVH-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeekfedrgeejucetufdoteggucfrrhhofhhilhgvmecuqfggjfenuceurghilhhouhhtmecufedttdenuc X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: 0 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeekfedrgeejucetufdoteggucfrrhhofhhilhgvmecuqfggjfenuceurghilhhouhhtmecufedttdenuc X-Validation-by: romain.bardou@inria.fr Subject: Re: [Caml-list] destructive local opens So basically we have to write more stuff to be able to write less stuff. Unless the "write more stuff" part can be factored there is no point. The best place to factor is in libraries, and we're back to annotating libraries, something that Daniel pointed out was not ideal either. It seems to me that trying to tackle this issue from a syntax perspective will not yield good results, and that one should seek help from the type-checker instead. Basically we want some form of overloading. Type classes would solve a lot of use cases. OCaml does provide typing-based disambiguation though, although that is only for records and sum types and not for values. What if we could use infix symbols for sum types? Let's assume for a moment that (!) and (+) are valid constructors. module Int = struct type t = | (!) of int | (+) of t * t end module Float = struct type t = | (!) of float | (+) of t * t end let x: Int.t = !42 + !59 let y: Float.t = !42. + !59. (If you replace ! by A and + by B this is a valid OCaml program.) Compare the last two lines with: let x = Int.(!42 + !59) let y = Float.(!42. + !59.) The character count is similar but in the first example there is less risk of shadowing, at the cost of having to disable warning 40. I personally believe that disambiguation is cleaner than local open. Also, in more complex examples the first solution may not even need the type annotation, such as in: type t = { x: Int.t; y: Float.t } (* disambiguation-based example *) let _ = { x = !42 + !59; y = !42. + !59. } (* local-open-based example *) let _ = { x = Int.(!42 + !59); y = Float.(!42. + !59.) } OCaml's disambiguation is kind of reversed type classes: disambiguation propagates type constraints top-down whereas type classes propagates type constraints bottom-up. The latter is more powerful - in particular typing can be principal - but it requires much more from the type system. On 19/08/2015 23:15, octachron wrote: > From my point of view, a prefixed notation M.+ does not replace all use > case of local opens, for at least two reasons: > > 1. It makes operators harder to spot since I can not rely any more > on the first character > 2. It adds syntactic noise and thus decreases readability within > the DSL > > As an illustration, a simple rotation > > (** Rotation on the vect(x,y) plane with an angle t > precondition: x and y are orthonormal *) > let rotation (x,y) t v = let open V in > v > + R.( ( cos t - 1. ) * (v|*|x) - sin t * (v|*|y) ) * x > + R.( sin t * (v|*|x) + ( cos t - 1. ) * (v|*|y) ) * y > > (where V is a vector module, R the associated real-like field and |*| > the scalar product) > becomes > > let rotation (x,y) t v = > v > V.+ ( ( cos t R.- 1. ) R.* ( v V.|*| x ) R.- sin t R.* ( v V.|*| > y ) ) V.* x > V.+ ( sin t R.* ( v V.|*| x ) R.+ ( cos t R.- 1. ) R.* ( v V.|*| > y ) ) V.* y > > with your proposition. > > In this second version, I have a hard time separating the different > subexpressions, and I don't think it would improve much with a better > familiarity with the syntax. > > At the same time, I do agree that it would be nice to be able to use > operators as operators without having to bring them in the local scope. > > -- octachron > > Le 08/19/15 17:55, Simon Cruanes a écrit : >> This whole thread makes me wonder whether local opens are worth it. I >> don't like global open (at all), and shadowing is harmful even in >> smaller scopes. Local open seems to be used for DSL that have a lot of >> infix operators (maths, etc.) as demonstrated by the proposal of new >> warnings and syntax about shadowing of infix operators. >> >> If modules have short names (Z, Q from Zarith come to mind, but >> module-aliasing your favorite monad to "M" would do too), would M.+ be >> a reasonable infix operator? I would be ready to have slightly more >> verbose calls to M.>>= if it removes ambiguity and potential shadowing >> bugs. Of course I don't know if this is compatible with the current >> syntax. >> >> -- >> Simon >