(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.