New EEP draft: Pinning operator ^ in patterns

Nalin Ranjan ranjanified@REDACTED
Wed Jan 20 15:38:27 CET 2021


On Wed, Jan 20, 2021 at 7:42 PM Raimo Niskanen <
raimo+erlang-questions@REDACTED> wrote:

> On Wed, Jan 20, 2021 at 07:28:09PM +0530, Nalin Ranjan wrote:
> > Hi,
> > Call it curiosity, but I would also love to share something and look for
> a
> > discussion around the following(and many people have noted this already).
> >
> > " *So, if there is any proposal to put forth, in my view, it is to get
> rid
> > of **variable shadowing*."
> >
> > If Erlang *drops* support for "v*ariable shadowing*", will it not help
> > address the "*emergence*" that we are discussing about?
>
> > I do not follow... Drop support for variable shadowing? Emergency?
>
Mentioned at so many occasions that it's a case of shadowing. And if so,
maybe not having to shadow could help prevent the situation. No emergency,
please.

/Nalin Ranjan
> >
> > Even with *^-annotation* around, things are not addressed once and for
> all.
> > The situation will only get avoided in the interim, but the likelihood of
> > its reoccurrence still holds good.
> >
> > As I could have a name whose first occurrence happens to be on line
> number
> > 100, and all subsequent occurrences annotated with ^ in a defensive
> style.
>
> > All subsequent occurences in Patterns, that is.  Not allowed elsewhere.
>
How about patterns inside nested scopes?

>
> > So far so good.Tomorrow I could embark on "Refactoring" fleet, and add
> some
> > new code to the function around line 30-50, and endup naming one of my
> new
> > variables to be the same as the one on line number 100. Situation,
>
> You would get a warning about not using the pinning operator in the pattern
> on line 100, if you use the warning.
>
> True. I do follow warnings, and very comfortably fixes them in the code
that I can control. But others' code is always a pain, and one could end up
borrowing some.And third-party packages could just be another nightmare.


> / Raimo Niskanen
>
> > re-emerged. I need to go and attend these variables to deal with the
> > situation. Or, I could embark on "Renaming" my variables to improve the
> > "developer intent" for the sake of communication, even so I could lead to
> > such a conflict. Even having the annotation capability around isn't
> helping
> > too much for the problem which is being cited as the reason.
> >
> > It's an *emergence*, and is owing to the way name<-> denotation
> association
> > is handled in Erlang. Maybe we should try to deliberate more about the
> > problem that the proposal is trying to address, and if there are options
> > available which could keep Erlang closer to "minimalism" then I would
> > prefer to go for that.
> >
> > Thanks and Regards
> > Nalin Ranjan
> >
>

Sorry about the below. I did read your replies, and so was intrigued to
ask.
/Nalin Ranjan

> > On Wed, Jan 20, 2021 at 6:16 PM Raimo Niskanen <
> > raimo+erlang-questions@REDACTED> wrote:
> >
> > > On Wed, Jan 20, 2021 at 01:47:12AM +0100, Chris Rempel wrote:
> > > > Hello,
> > > >
> > > > > I agree about the beauty of Erlang's simplicity. For this
> particular
> > > > > suggestion I, personally, feel that because Erlang "hides" if a
> > > variable
> > > > > occurence is a binding or a matching in the knowledge if the
> variable
> > > has
> > > > > occured before or not, it may be too simple because it is slightly
> > > ambigous.
> > > > >
> > > > > Therefore I think that although annotating matches would make the
> > > language
> > > > > less simple it would improve clarity by making intention explicit.
> > > > >
> > > > > I can live without this, have so for the last 20 years, but I think
> > > Erlang
> > > > > would be a slightly better language with pinning than it is
> without it.
> > > > >
> > > > > / Raimo Niskanen, Erlang/OTP, Ericsson AB
> > > >
> > > > I find a different conclusion in this, with how I think when coding
> in
> > > Erlang.
> > > > Knowing a variable always has the same value after first use, whether
> > > assigned
> > > > or pattern match, and the value never can change, is such simple
> concept
> > > to
> > > > work with.
> > >
> > > The proposal does not change that property.
> > >
> > > >
> > > > >From the EEP:
> > > >
> > > > f (X, Y) ->
> > > >   case X of
> > > >     {a, Y} -> {ok ,Y};
> > > >     _ -> error
> > > >   end.
> > > >
> > > > would no longer be valid (at some point in the distant future when
> > > pinning is
> > > > mandatory), and would have to be written:
> > > >
> > > > f (X, Y) ->
> > > >   case X of
> > > >     {a, ^Y} -> {ok ,Y};
> > > >     _ -> error
> > > >   end.
> > > >
> > > > yet today we can already write:
> > > >
> > > > f (X, Y) ->
> > > >   case X of
> > > >     {a, Y2} when Y2 =:= Y -> {ok ,Y2};
> > > >     _ -> error
> > > >   end.
> > > >
> > > > So, for those who want this EEP in order to be more explicit, why do
> you
> > > not
> > > > write your code in that third form and introduce an EEP requesting a
> > > compiler
> > >
> > > I think that is too clumsy, just as it annoys me to have to do that
> when
> > > defining fun()s:
> > >     Y = value,
> > >     F = fun (YY) when YY =:= Y -> Y end,
> > >
> > > > flag that you can use to generate a warning in the first form above,
> so
> > > that
> > > > you rewrite it in the third form. The second form flies in the face
> of
> > > how I,
> > > > and apparently many others, think in Erlang. The pinning operator is
> > > > extraneous, and in fact determintal to that way of thinking.
> > >
> > > I have noticed the opinion that this breaks how they think about
> Erlang,
> > > and above you mentioned the principle that the same variable has the
> same
> > > value in all occurences.  I say that this proposal does not break that
> > > principle.
> > >
> > > So I have a hard time understanding exactly what way to think it is
> that
> > > the
> > > pinning operator destroys.
> > >
> > >     Y = foo(),
> > >     case bar() of
> > >         {ok, ^Y} -> {ok, Y}
> > >     end
> > >
> > > Y is the same variable and has the same value in all 3 occurences.
> > > But I know for sure that the code did not crash at Y = foo(), because
> > > Y can not have been previously bound.
> > >
> > >
> > > >
> > > > The good thing about this EEP is that it addresses variable
> shadowing.
> > > It has
> > > > always bugged me that variable shadowing was a thing in Erlang.
> > > >
> > > > f(X, Y) ->
> > > >   F = fun
> > > >     ({a, Y}) -> {ok, Y};
> > > >     (_) -> error
> > > >   end,
> > > >   {F(X), Y}.
> > > >
> > > > That generates the shadow variable warning currently, and `f({a, 1},
> 2)`
> > > > returns `{{ok, 1}, 2}` which is just wrong as it breaks (in my view)
> the
> > > rule
> > > > that a variable value never changes.  And so pointlessly this must be
> > > > rewritten like so:
> > > >
> > > > f(X, Y) ->
> > > >   F = fun
> > > >     ({a, Y2}) when Y2 =:= Y -> {ok, Y2};
> > > >     (_) -> error
> > > >   end,
> > > >   {F(X), Y}.
> > > >
> > > > The pinning operator "fixes" this by allowing for:
> > > >
> > > > f(X, Y) ->
> > > >   F = fun
> > > >     ({a, ^Y}) -> {ok, Y};
> > > >     (_) -> error
> > > >   end,
> > > >   {F(X), Y}.
> > > >
> > > > But in both cases, I have to explicitly say, hey Erlang, don't break
> > > your own
> > > > rule that a variable value never changes. To me this EEP is fixing
> the
> > > problem
> > > > in the wrong way.
> > >
> > > I do not see how the pinning operator breaks the rule that a variable's
> > > value never changes.
> > >
> > > A variable's value never changes for all occurences of the variable in
> its
> > > scope.  The variable's scope is all of the function after its first
> > > occurence.
> > >
> > > When we get to fun()s we have a conflict of principles.  Should the
> > > the same scoping rule apply to the fun() as to the surrounding
> function?
> > >
> > > Erlang has solved this with a pragmatic compromise (as often enough):
> > > variables bound in a fun() are local to the fun().  But variables from
> the
> > > outer scope that are referred to in a fun() are from the outer scope.
> So
> > > if it has the same name it is the one in the outer scope.  Except in
> the
> > > fun() argument list.  Here variables are in general new ones so they
> are
> > > local to the fun(), even if a different variable with the same name
> exists
> > > in the outer scope.
> > >
> > > But a variable's value never changes within its scope.  Not today.
> > > Not with this proposal.  The snag is; which variable do we mean?
> > >
> > > >
> > > > So, if there is any proposal to put forth, in my view, it is to get
> rid
> > > of
> > > > variable shadowing.
> > >
> > > You are free to sketch on one; it does not have to be an EEP.
> > >
> > > A problem is that today variables in a fun() head shadows variables
> from
> > > the outer scope, and the compiler warns about it.  If the behaviour
> should
> > > be changed into not shadowing variables the compiler could not warn
> about
> > > using a variable from the outer scope because it is now assumed that
> it is
> > > the correct semantics.  If there was an annotation of the variables
> that
> > > are bound instead of matched the compiler could tell the difference.
> Such
> > > an annotation would very much look like variable rebinding and could
> easily
> > > be extended to exactly that.
> > >
> > > Another possibility would be to introduce some kind of let...end
> construct
> > > to explicitly introduce variable scoping, which has been discussed
> before.
> > >
> > > There might, of course, be other possibilities.
> > > I am not a language expert.
> > >
> > > >
> > > > Also, already in this thread it is now being mentioned to have
> variable
> > > > rebinding support. If this EEP erodes such a core tenant (in my
> view) of
> > > > Erlang such that it leads to variable rebinding, it should be
> rejected
> > > on that
> > > > alone (in my view).
> > >
> > > I also do not want to get variable rebinding.  But this EEP should be
> > > evaluated on its own merits and on the possibilities it offers that we
> > > might want.
> > >
> > > >
> > > > But the part of the EEP that just completely nullifies it is:
> > > >
> > > > > In this case, there is no new binding of Y, and the use of Y in
> the fun
> > > > > clause body refers to the function parameter. But it is also
> possible
> > > to
> > > > > combine pinning and shadowing in the same pattern:
> > > > >
> > > > > f(X, Y) ->
> > > > >     F = fun ({a, ^Y, Y})  -> {ok, Y};
> > > > >             (_) -> error
> > > > >         end,
> > > > >     F(X).
> > > > >
> > > > > In this case, the pinned field refers to the value of the function
> > > function
> > > > > parameter, but there is also a new shadowing binding of Y to the
> third
> > > field
> > > > > of the tuple. The use in the fun clause body now refers to the
> > > shadowing
> > > > > instance.
> > > >
> > > > You now have two variables named the same thing with different
> values. It
> > > > breaks fundamental way of thinking in Erlang.  There is zero value in
> > > allowing
> > > > this. Use a different variable name.
> > >
> > > I agree that anyone that writes code like that deserves a good telling
> > > off...
> > >
> > > I think the problem is in the variable shadowing, not in the pinning
> > > operator.
> > > Today we get a compiler warning when a variable in a fun() head
> shadows one
> > > in the outer scope.  But other than that it is legal.
> > >
> > > We do not, however, get a warning when a variable is used in a fun()
> body
> > > from the surrounding function since a fun() body has got the same
> scope as
> > > the surrounding function, except for newly bound variables...
> Accidentally
> > > referring to a variable from outside the fun() is a problem.
> > >
> > > With the pinning operator it becomes possible to explicitly refer to
> the
> > > outer scope and thereby possible to warn for referring to the
> containing
> > > function without being explicit, making the fun() more a real variable
> > > scope.
> > >
> > > >
> > > > The EEP Rationale section is likewise problematic, but copying it
> here
> > > and
> > > > responding to each point is tiresome.
> > >
> > > That was some handwaving.  You are stating that it is problematic
> without
> > > explaining why.  Not very constructive.
> > >
> > > >
> > > > So, I'd like to propose that any EEP added to
> > > https://github.com/erlang/eep/
> > > > is done in a PR and left open for reviews/comments on the PR for a
> > > period of
> > > > time. There is much in the EEP that I would comment on, line by line.
> > >
> > > That is an interesting suggestion.  EEP 1 states that after an EEP has
> been
> > > accepted (not approved) it should try to get community support, but it
> does
> > > not say how.
> > >
> > > The current situation where this EEP is discussed in eeps@REDACTED,
> > > erlang-questions@REDACTED, and in the PR for the reference
> > > implementation
> > > is not good.
> > >
> > > Having discussions about the EEP before submission (and after(?)) in a
> pull
> > > request on the eep repository on GitHub sounds like a good step,
> except for
> > > the ones that do not have accounts on GitHub, and it would drive us
> further
> > > into the GitHub (/Microsoft) hands, which may be politically sensitive.
> > >
> > > >
> > > > There has been concern on the list that this discussion has not
> remained
> > > > technical and on point to the value of the EEP, and I would suggest
> the
> > > fault
> > > > lies in the tool being used to elicit feedback (e-mail). That concern
> > > would be
> > > > addressed by allowing people to comment line by line on the EEP and
> > > discuss
> > > > the specific points of the EEP in the PR itself. And we can avoid
> blame
> > > being
> > > > thrown around about people having or not having read the EEP.
> > >
> > > A very valid point.  I also think GitHub Pull Requests offer better
> > > possibilities for discussion around details.
> > >
> > > >
> > > > Regards,
> > > >
> > > > Chris
> > >
> > > --
> > >
> > > / Raimo Niskanen, Erlang/OTP, Ericsson AB
> > >
>
> --
>
> / Raimo Niskanen, Erlang/OTP, Ericsson AB
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20210120/49d5ed39/attachment.htm>


More information about the erlang-questions mailing list