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 mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by sympa.inria.fr (Postfix) with ESMTPS id D2EC37EEBF for ; Wed, 19 Aug 2015 20:09:51 +0200 (CEST) Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of anthony.tavener@gmail.com) identity=pra; client-ip=209.85.212.176; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="anthony.tavener@gmail.com"; x-sender="anthony.tavener@gmail.com"; x-conformance=sidf_compatible Received-SPF: Pass (mail2-smtp-roc.national.inria.fr: domain of anthony.tavener@gmail.com designates 209.85.212.176 as permitted sender) identity=mailfrom; client-ip=209.85.212.176; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="anthony.tavener@gmail.com"; x-sender="anthony.tavener@gmail.com"; x-conformance=sidf_compatible; x-record-type="v=spf1" Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of postmaster@mail-wi0-f176.google.com) identity=helo; client-ip=209.85.212.176; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="anthony.tavener@gmail.com"; x-sender="postmaster@mail-wi0-f176.google.com"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A0DhAQALxtRVlLDUVdFdhFgGgx+uYZNHAoE9B0wBAQEBAQESAQEBAQcLCwkfMIQkAQEDARIRHQEbHQEDDAYFBAc3AgIiAREBBQEcBhMbB4d2AQMKCKtQgS8+MYtAgWyCeYsEChknDVeFAAEBAQEBBQEBAQEBARYBBQ6LRYUKB4JpgUMFjVSEQIMQjG2BSpR/ghwSI4EXF4IdHIFyHzOCTAEBAQ X-IPAS-Result: A0DhAQALxtRVlLDUVdFdhFgGgx+uYZNHAoE9B0wBAQEBAQESAQEBAQcLCwkfMIQkAQEDARIRHQEbHQEDDAYFBAc3AgIiAREBBQEcBhMbB4d2AQMKCKtQgS8+MYtAgWyCeYsEChknDVeFAAEBAQEBBQEBAQEBARYBBQ6LRYUKB4JpgUMFjVSEQIMQjG2BSpR/ghwSI4EXF4IdHIFyHzOCTAEBAQ X-IronPort-AV: E=Sophos;i="5.15,711,1432591200"; d="scan'208";a="174217755" Received: from mail-wi0-f176.google.com ([209.85.212.176]) by mail2-smtp-roc.national.inria.fr with ESMTP/TLS/RC4-SHA; 19 Aug 2015 20:09:39 +0200 Received: by wicja10 with SMTP id ja10so15525805wic.1 for ; Wed, 19 Aug 2015 11:09:38 -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; bh=v/JTlUkNr3TbCGXoxE/tra+fmvVAEiyc2dbdxb8cGAs=; b=tSdD+JcGNHQu5lbfNkdXyMG3VCGPqltOZ9BoNZHgi0C4xjCdRjCVO+Mthes9gHCAM6 Mmz4SrIV64NgvwlIMigzw5ul3v0qkULbbE+eOFZvSaDQWGMtPMw5sL0bq8de4nM6Icbg l4L2P2pF36/RbSMB39BtTZ6Eji6R/4dgCVShu7wl9HX+spxi5OFU7TuRx7Qgx0qTh3yU uSqLR3km2RgWmaQKQ3RAbU+NknCcEqnzhFiFeD9V9zNX0Y2QMbr4XTMYkXgvoNO/R2dw THOGt209v1L/8rj488bJ4MjMXfoKSHtNUkSOxYygrV8ukQVpAPbTrOFQWi/hf4POYjrJ 7XJw== MIME-Version: 1.0 X-Received: by 10.180.206.8 with SMTP id lk8mr5645493wic.12.1440007778801; Wed, 19 Aug 2015 11:09:38 -0700 (PDT) Received: by 10.28.93.4 with HTTP; Wed, 19 Aug 2015 11:09:38 -0700 (PDT) In-Reply-To: <20150819155249.GB31044@topoi.pooq.com> References: <20150804092633.GC5689@frosties> <5C2023F4AF0549F58F3E4C9A6F8ABE84@erratique.ch> <20150814105551.GD31364@frosties> <55CDD0F2.1090200@zoho.com> <20150818111134.GA11154@frosties> <20150819155249.GB31044@topoi.pooq.com> Date: Wed, 19 Aug 2015 12:09:38 -0600 Message-ID: From: Anthony Tavener To: Hendrik Boom Cc: "caml-list@inria.fr" Content-Type: multipart/alternative; boundary=001a11c369cc211bda051dadf0b6 Subject: Re: [Caml-list] destructive local opens --001a11c369cc211bda051dadf0b6 Content-Type: text/plain; charset=UTF-8 On Wed, Aug 19, 2015 at 9:52 AM, Hendrik Boom wrote: > > The way to make this explicit is to write > > let init flags = > (M.init (M.flag1 + M.flag2 + flags) (* flags is 'local', and is not > shadowed by a value in M *) > > THe code is one characte longer, and even the comment becomes smaller! > > The '+' operator is also from M, not just normal addition. And, instead of M, it might be "Sdl.Init". :) Local open has been fantastic for code hygene and clarity -- previously it was very common to define local module aliases (even though they weren't actual aliases at the time!): module S = Sdl.Init... and then prefixing everything with S, similar to your example. But this is ugly, still redundant, plus it adds cognitive indirection (alias). Often when I use a local open it's in an expression which uses mostly values from the opened module, with a few from local scope, very much like the example I gave. If it's not heavily from the external module, of course I only prefix the relevant identifiers rather than opening scope. I've always hated the following function-call sloppiness in several languages: Namespace::func( Namespace::arg1, Namespace::Enum::arg2, myArg ); I felt like the arguments should be implicitly open to the namespace of the called function. Then local-open in OCaml, particularly with the short syntax M.(), provided an elegant solution -- without need for anything implicit! I facepalmed that day. Module.(func arg1 Enum.arg2) myarg Fantabulous! Now the minor quibble to this otherwise luxurious syntax is that there is no way to make it clear when something really is local rather than coming from an opened scope -- and this arises when currying doesn't pan out as nice as the above, or more often: once binary operators are involved. But as I said, there has been the related (at least conceptually) thorn of the inability to specify the path of the current module. I'm hoping someone familiar with OCaml internals and style has a bright idea. --001a11c369cc211bda051dadf0b6 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
On W= ed, Aug 19, 2015 at 9:52 AM, Hendrik Boom <hendrik@topoi.pooq.com= > wrote:

The way to make this explicit is to write

=C2=A0 let init flags =3D
=C2=A0 =C2=A0 (M.init (M.flag1 + M.flag2 + flags) (* flags is 'local= 9;, and is not shadowed by a value in M *)

THe code is one characte longer, and even the comment becomes smaller!


The '+' operator is also from M, not just no= rmal addition. And, instead of M, it
might be "Sdl.Init"= ;. :)

Local open has been fantastic for code hygen= e and clarity -- previously it was
very common to define local mo= dule aliases (even though they weren't actual
aliases at the = time!): module S =3D Sdl.Init... and then prefixing everything
wi= th S, similar to your example. But this is ugly, still redundant, plus it a= dds
cognitive indirection (alias).

Often= when I use a local open it's in an expression which uses mostly values=
from the opened module, with a few from local scope, very much l= ike the
example I gave. If it's not heavily from the external= module, of course I only
prefix the relevant identifiers rather = than opening scope.

I've always hated the foll= owing function-call sloppiness in several languages:

=C2=A0 Namespace::func( Namespace::arg1, Namespace::Enum::arg2, myArg );=

I felt like the arguments should be implicitly op= en to the namespace of the called
function.

<= div>Then local-open in OCaml, particularly with the short syntax M.(), prov= ided an
elegant solution -- without need for anything implicit! I= facepalmed that day.

=C2=A0 Module.(func arg1 Enu= m.arg2) myarg

Fantabulous!

Now the minor quibble to this otherwise luxurious syntax is that there is= no way
to make it clear when something really is local rather th= an coming from an opened
scope -- and this arises when currying d= oesn't pan out as nice as the above, or
more often: once bina= ry operators are involved.

But as I said, there ha= s been the related (at least conceptually) thorn of the
inability= to specify the path of the current module. I'm hoping someone familiar=
with OCaml internals and style has a bright idea.

=
--001a11c369cc211bda051dadf0b6--