caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Simon Cruanes <simon.cruanes.2007@m4x.org>
To: Anthony Tavener <anthony.tavener@gmail.com>,Gabriel Scherer
	<gabriel.scherer@gmail.com>
Cc: "caml-list@inria.fr" <caml-list@inria.fr>
Subject: Re: [Caml-list] destructive local opens
Date: Wed, 19 Aug 2015 17:55:18 +0200	[thread overview]
Message-ID: <D7CDD808-BC13-4D77-9EDD-D9F450391993@m4x.org> (raw)
In-Reply-To: <CAN=ouMQ-=dr7FyvPTEcF0wgBDsF5xyOxBb0roerckHCs0f0WnQ@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 7615 bytes --]

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.

Le 19 août 2015 00:26:00 UTC+02:00, Anthony Tavener <anthony.tavener@gmail.com> a écrit :
>(TL;DR: I commonly want to specify paths -uniquely- for identifiers in
>local
>scopes (function, module) which have no means to do this.)
>
>As I run into this yet again, moments ago...
>
>I do often want the ability to be clear that something is not to be
>shadowed
>by the opened scope... to specify it's from the local (usually
>function)
>scope.
>Part of the reason is for code clarity, but also to safeguard against
>possible
>later changes in the *opened* module (introducing the same identifier).
>
>  let init flags =
>   M.(init (flag1 + flag2 + flags)) (* flags is intended to be 'local',
>but it could be shadowed by a value in M *)
>
>Where M provides 'init', 'flag1', 'flag2', and '+', but 'flags' is in
>the
>local (function) context. When I do this I try to think of a way to
>make it
>self evident that 'flags' is not from M, but there is no way. Aside
>from
>bringing it outside the local-open, but then it's more difficult to
>build
>an expression.
>
>Vimscript might be one of the worst languages to use as a reference,
>but
>this
>issue does bring to mind the scope prefixes...
>
>  let init flags =
>M.(init (flag1 + flag2 + l:flags)) (* illustrative -- not a proposal!
>*)
>
>I sometimes consider using naming conventions, but I don't want to
>explicitly
>make function arguments something like l_flags, l_point, etc. That
>would be
>a
>horrible widespread style, and doesn't work nicely with named
>arguments.
>Plus, changing names to do this seems wrong -- it's at the access site
>where
>you want to disambiguate, which always leads me to think some sigil or
>prefix.
>
>There was an earlier sidetrack which went with ^ as an "unopen" prefix.
>At
>first,
>my interest was piqued. Naturally, the issue of recursive unopen came
>up...
>
>In response, Gabriel wisely remarked:
>
> "It is remarkable that programming languages have avoided introducing
> explicit weakening (the popping of a symbol out of scope) for now, and
> I think it is a property that should be preserved. We're not yet ready
>  to go there."
>
>Good advice when the thread was spinning out of control and probably
>not
>going
>to settle on anything realistic or favorable. Even though there might
>be
>merit
>in pursuing fine-grained scope-popping as its own topic.
>
>I think there is a simpler gain to be had from the idea of being able
>to
>specify
>the path of the current context. "Current context" would need to be
>something sensible, and I'm not sure yet what would be best, as there
>is a
>related issue I encounter commonly:
>
>A way to specify the path of the current module.
>
>There is no way to do this, right? If I'm in "a.ml", I can't refer to
>A.identifier, and there is no other way to uniquely specify the path to
>what
>*will become* A.identifier? As the bare "identifier" can be shadowed by
>any
>modules opened afterward. Unlike the general "scope-popping", there is
>also
>a common language feature like this: self or this.
>
>I usually want to be explicit with module paths, especially if I am
>using an
>"identifier" which could reasonably be expected to exist now or later
>in the
>other modules being used. I do keep opens to a minimum, but often an
>entire
>expression will be in a local open (to bring in operators), and there,
>again... I would like that clarity, and safeguard against changes which
>might
>happen in the other modules, leading to suprises or need to change
>*this*
>module for no good reason other than a naming conflict which ideally
>can be
>prepared against.
>
>Has there been any discussion about referring to the local module? My
>guess
>is
>that it might be a mild enough problem to not warrant any proposed
>solutions.
>But if there are ideas, maybe the same thing or something similar can
>also
>apply to this problem of "escaping" a local open? They are very
>similar, but
>one is module-scope, while I think the other would be function-scope
>(though
>module-scope might imply the "right thing" anyway)... I'm not certain,
>as
>haven't been keeping track of the cases I encounter, and others might
>have
>different use-cases.
>
>
>On Tue, Aug 18, 2015 at 7:00 AM, Gabriel Scherer
><gabriel.scherer@gmail.com>
>wrote:
>
>> Note that the dual feature does not exist for variant constructors,
>> because it is easy to define only on the constructor at the toplevel
>of the
>> pattern, and nested patterns get us in muddy waters.
>>
>> On Tue, Aug 18, 2015 at 2:52 PM, David Allsopp
><dra-news@metastack.com>
>> wrote:
>>
>>> Goswin von Brederlow wrote:
>>> > On Fri, Aug 14, 2015 at 01:28:50PM +0200, Drup wrote:
>>> > >
>>> > > >You can't qualifylocal values or values of the surrounding
>module so
>>> > > >that is a no go.
>>> > > >
>>> > > >I also often use local open to access records, as in:
>>> > > >
>>> > > >let r = M.({ x = 1; y; z = depth; }) in
>>> > >
>>> > > You can avoid the local open altogether and write it like that:
>>> > >
>>> > >     let r = {M. x = 1; y; z = depth } in
>>> > >
>>> > > It's even shorter.
>>> >
>>> > That only works because newer ocaml disambiguises (is that a
>word?)
>>> record
>>> > So it's implicitly using M.y = y and M.z = depth.
>>> > labels when it determines the record type from the first label,
>right?
>>>
>>> Only since you ask: "disambiguates" :o) That said, it's quite common
>to
>>> see words like "disambiguises" being invented by Americans!
>>>
>>> But this isn't related to the disambiguation features of OCaml
>4.01+.
>>> Those allow you to write things like:
>>>
>>> type t = {x : int}
>>> type u = {x : int; y : string}
>>>
>>> let foo = {x = 1}
>>> let bar = {x = 42; y = ""}
>>>
>>> This is actually a much older notation added in OCaml 3.08. Prior to
>>> that, if you hadn't opened a module you had to qualify each label:
>>>
>>> {M.x = 1; M.y = y; M.z = depth}
>>>
>>> but this was "silly", since it's not possible to use non-equivalent
>>> module paths for labels, so OCaml 3.08 changed it so that you only
>needed
>>> to put the module path on one label (and it doesn't have to be the
>first
>>> one, it's just a bit weird to put it in the middle!).
>>>
>>> OCaml 3.12 added, amongst other record-related goodies, the
>shorthand {y}
>>> to mean {y = y}. So while you can use local open as you're using it,
>you've
>>> been able to do it as a totally unambiguous language feature for
>quite some
>>> time.
>>>
>>>
>>> David
>>>
>>>
>>> --
>>> Caml-list mailing list.  Subscription management and archives:
>>> https://sympa.inria.fr/sympa/arc/caml-list
>>> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
>>> Bug reports: http://caml.inria.fr/bin/caml-bugs
>>>
>>
>>
>
>-- 
>Caml-list mailing list.  Subscription management and archives:
>https://sympa.inria.fr/sympa/arc/caml-list
>Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
>Bug reports: http://caml.inria.fr/bin/caml-bugs

-- 
Simon

[-- Attachment #2: Type: text/html, Size: 9857 bytes --]

  parent reply	other threads:[~2015-08-19 16:05 UTC|newest]

Thread overview: 59+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-08-03 13:39 Nils Becker
2015-08-03 13:43 ` Thomas Refis
2015-08-03 13:45 ` Daniel Bünzli
2015-08-03 13:47   ` Daniel Bünzli
     [not found]     ` <55BF75F6.1040006@bioquant.uni-heidelberg.de>
2015-08-03 14:24       ` Daniel Bünzli
2015-08-03 14:37         ` Gabriel Scherer
2015-08-03 14:43           ` Daniel Bünzli
2015-08-03 15:10           ` octachron
2015-08-03 15:22             ` Daniel Bünzli
2015-08-03 16:13               ` octachron
2015-08-03 16:51                 ` Daniel Bünzli
2015-08-03 17:18                   ` Hendrik Boom
2015-08-03 17:59                   ` octachron
2015-08-06 13:23                     ` RE : " moreno pedro
2015-08-04  6:51         ` Petter Urkedal
2015-08-04  9:33           ` Goswin von Brederlow
2015-08-05  6:40             ` Petter A. Urkedal
2015-08-05 10:16               ` David Allsopp
2015-08-06  9:35               ` Goswin von Brederlow
2015-08-04 13:50           ` Hendrik Boom
2015-08-04  9:26         ` Goswin von Brederlow
2015-08-04  9:38           ` Daniel Bünzli
2015-08-04 12:26             ` vrotaru.md
2015-08-04 13:12               ` David Allsopp
2015-08-04 13:17                 ` Jeremy Yallop
2015-08-04 13:54                   ` vrotaru.md
2015-08-04 15:25                   ` Drup
2015-08-04 22:22                     ` vrotaru.md
2015-08-04 22:55                       ` Hendrik Boom
2015-08-05  4:52                         ` Gabriel Scherer
2015-08-04 13:14               ` Ivan Gotovchits
2015-08-14 10:55                 ` Goswin von Brederlow
2015-08-14 11:28                   ` Drup
2015-08-18 11:11                     ` Goswin von Brederlow
2015-08-18 12:52                       ` David Allsopp
2015-08-18 13:00                         ` Gabriel Scherer
2015-08-18 22:26                           ` Anthony Tavener
2015-08-19 13:55                             ` Oleg
2015-08-19 14:13                               ` John Whitington
2015-08-19 15:47                                 ` Hendrik Boom
2015-08-19 15:52                             ` Hendrik Boom
2015-08-19 18:09                               ` Anthony Tavener
2015-08-19 15:55                             ` Simon Cruanes [this message]
2015-08-19 16:42                               ` Arthur Wendling
2015-08-19 21:15                               ` octachron
2015-08-20  8:06                                 ` Romain Bardou
2015-08-20 17:03                                   ` Yotam Barnoy
2015-08-20 19:19                                     ` Erkki Seppala
2015-08-06  9:23               ` Goswin von Brederlow
2015-08-06  9:21             ` Goswin von Brederlow
2015-08-06 10:19               ` Daniel Bünzli
2015-08-06 13:36                 ` Hendrik Boom
2015-08-14 10:57                   ` Goswin von Brederlow
2015-08-17 10:17 Nils Becker
2015-08-17 14:26 ` Gabriel Scherer
2015-08-17 15:11   ` Nils Becker
2015-08-17 15:17     ` Drup
2015-08-17 15:18     ` Gabriel Scherer
2015-08-17 18:31       ` Hendrik Boom

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=D7CDD808-BC13-4D77-9EDD-D9F450391993@m4x.org \
    --to=simon.cruanes.2007@m4x.org \
    --cc=anthony.tavener@gmail.com \
    --cc=caml-list@inria.fr \
    --cc=gabriel.scherer@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).