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 --]
next prev 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