<div dir="ltr"><div dir="ltr">On Wed, Jan 20, 2021 at 7:42 PM Raimo Niskanen <<a href="mailto:raimo%2Berlang-questions@erlang.org">raimo+erlang-questions@erlang.org</a>> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On Wed, Jan 20, 2021 at 07:28:09PM +0530, Nalin Ranjan wrote:<br>
> Hi,<br>
> Call it curiosity, but I would also love to share something and look for a<br>
> discussion around the following(and many people have noted this already).<br>
> <br>
> " *So, if there is any proposal to put forth, in my view, it is to get rid<br>
> of **variable shadowing*."<br>
> <br>
> If Erlang *drops* support for "v*ariable shadowing*", will it not help<br>
> address the "*emergence*" that we are discussing about?<br>
<br>> I do not follow... Drop support for variable shadowing? Emergency?  <br></blockquote><div>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. </div><div><br></div><div></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
/Nalin Ranjan<br>
> <br>
> Even with *^-annotation* around, things are not addressed once and for all.<br>
> The situation will only get avoided in the interim, but the likelihood of<br>
> its reoccurrence still holds good.<br>
> <br>
> As I could have a name whose first occurrence happens to be on line number<br>
> 100, and all subsequent occurrences annotated with ^ in a defensive style.<br>
<br>> All subsequent occurences in Patterns, that is.  Not allowed elsewhere.<br></blockquote><div>How about patterns inside nested scopes?</div><div></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
> So far so good.Tomorrow I could embark on "Refactoring" fleet, and add some<br>
> new code to the function around line 30-50, and endup naming one of my new<br>
> variables to be the same as the one on line number 100. Situation,<br>
<br>
You would get a warning about not using the pinning operator in the pattern<br>
on line 100, if you use the warning.<br>
<br></blockquote><div>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.  </div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
/ Raimo Niskanen<br>
<br>
> re-emerged. I need to go and attend these variables to deal with the<br>
> situation. Or, I could embark on "Renaming" my variables to improve the<br>
> "developer intent" for the sake of communication, even so I could lead to<br>
> such a conflict. Even having the annotation capability around isn't helping<br>
> too much for the problem which is being cited as the reason.<br>
> <br>
> It's an *emergence*, and is owing to the way name<-> denotation association<br>
> is handled in Erlang. Maybe we should try to deliberate more about the<br>
> problem that the proposal is trying to address, and if there are options<br>
> available which could keep Erlang closer to "minimalism" then I would<br>
> prefer to go for that.<br>
> <br>
> Thanks and Regards<br>
> Nalin Ranjan<br>
> <br></blockquote><div><br></div><div>Sorry about the below. I did read your replies, and so was intrigued to ask. </div><div>/Nalin Ranjan </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
> On Wed, Jan 20, 2021 at 6:16 PM Raimo Niskanen <<br>
> <a href="mailto:raimo%2Berlang-questions@erlang.org" target="_blank">raimo+erlang-questions@erlang.org</a>> wrote:<br>
> <br>
> > On Wed, Jan 20, 2021 at 01:47:12AM +0100, Chris Rempel wrote:<br>
> > > Hello,<br>
> > ><br>
> > > > I agree about the beauty of Erlang's simplicity. For this particular<br>
> > > > suggestion I, personally, feel that because Erlang "hides" if a<br>
> > variable<br>
> > > > occurence is a binding or a matching in the knowledge if the variable<br>
> > has<br>
> > > > occured before or not, it may be too simple because it is slightly<br>
> > ambigous.<br>
> > > ><br>
> > > > Therefore I think that although annotating matches would make the<br>
> > language<br>
> > > > less simple it would improve clarity by making intention explicit.<br>
> > > ><br>
> > > > I can live without this, have so for the last 20 years, but I think<br>
> > Erlang<br>
> > > > would be a slightly better language with pinning than it is without it.<br>
> > > ><br>
> > > > / Raimo Niskanen, Erlang/OTP, Ericsson AB<br>
> > ><br>
> > > I find a different conclusion in this, with how I think when coding in<br>
> > Erlang.<br>
> > > Knowing a variable always has the same value after first use, whether<br>
> > assigned<br>
> > > or pattern match, and the value never can change, is such simple concept<br>
> > to<br>
> > > work with.<br>
> ><br>
> > The proposal does not change that property.<br>
> ><br>
> > ><br>
> > > >From the EEP:<br>
> > ><br>
> > > f (X, Y) -><br>
> > >   case X of<br>
> > >     {a, Y} -> {ok ,Y};<br>
> > >     _ -> error<br>
> > >   end.<br>
> > ><br>
> > > would no longer be valid (at some point in the distant future when<br>
> > pinning is<br>
> > > mandatory), and would have to be written:<br>
> > ><br>
> > > f (X, Y) -><br>
> > >   case X of<br>
> > >     {a, ^Y} -> {ok ,Y};<br>
> > >     _ -> error<br>
> > >   end.<br>
> > ><br>
> > > yet today we can already write:<br>
> > ><br>
> > > f (X, Y) -><br>
> > >   case X of<br>
> > >     {a, Y2} when Y2 =:= Y -> {ok ,Y2};<br>
> > >     _ -> error<br>
> > >   end.<br>
> > ><br>
> > > So, for those who want this EEP in order to be more explicit, why do you<br>
> > not<br>
> > > write your code in that third form and introduce an EEP requesting a<br>
> > compiler<br>
> ><br>
> > I think that is too clumsy, just as it annoys me to have to do that when<br>
> > defining fun()s:<br>
> >     Y = value,<br>
> >     F = fun (YY) when YY =:= Y -> Y end,<br>
> ><br>
> > > flag that you can use to generate a warning in the first form above, so<br>
> > that<br>
> > > you rewrite it in the third form. The second form flies in the face of<br>
> > how I,<br>
> > > and apparently many others, think in Erlang. The pinning operator is<br>
> > > extraneous, and in fact determintal to that way of thinking.<br>
> ><br>
> > I have noticed the opinion that this breaks how they think about Erlang,<br>
> > and above you mentioned the principle that the same variable has the same<br>
> > value in all occurences.  I say that this proposal does not break that<br>
> > principle.<br>
> ><br>
> > So I have a hard time understanding exactly what way to think it is that<br>
> > the<br>
> > pinning operator destroys.<br>
> ><br>
> >     Y = foo(),<br>
> >     case bar() of<br>
> >         {ok, ^Y} -> {ok, Y}<br>
> >     end<br>
> ><br>
> > Y is the same variable and has the same value in all 3 occurences.<br>
> > But I know for sure that the code did not crash at Y = foo(), because<br>
> > Y can not have been previously bound.<br>
> ><br>
> ><br>
> > ><br>
> > > The good thing about this EEP is that it addresses variable shadowing.<br>
> > It has<br>
> > > always bugged me that variable shadowing was a thing in Erlang.<br>
> > ><br>
> > > f(X, Y) -><br>
> > >   F = fun<br>
> > >     ({a, Y}) -> {ok, Y};<br>
> > >     (_) -> error<br>
> > >   end,<br>
> > >   {F(X), Y}.<br>
> > ><br>
> > > That generates the shadow variable warning currently, and `f({a, 1}, 2)`<br>
> > > returns `{{ok, 1}, 2}` which is just wrong as it breaks (in my view) the<br>
> > rule<br>
> > > that a variable value never changes.  And so pointlessly this must be<br>
> > > rewritten like so:<br>
> > ><br>
> > > f(X, Y) -><br>
> > >   F = fun<br>
> > >     ({a, Y2}) when Y2 =:= Y -> {ok, Y2};<br>
> > >     (_) -> error<br>
> > >   end,<br>
> > >   {F(X), Y}.<br>
> > ><br>
> > > The pinning operator "fixes" this by allowing for:<br>
> > ><br>
> > > f(X, Y) -><br>
> > >   F = fun<br>
> > >     ({a, ^Y}) -> {ok, Y};<br>
> > >     (_) -> error<br>
> > >   end,<br>
> > >   {F(X), Y}.<br>
> > ><br>
> > > But in both cases, I have to explicitly say, hey Erlang, don't break<br>
> > your own<br>
> > > rule that a variable value never changes. To me this EEP is fixing the<br>
> > problem<br>
> > > in the wrong way.<br>
> ><br>
> > I do not see how the pinning operator breaks the rule that a variable's<br>
> > value never changes.<br>
> ><br>
> > A variable's value never changes for all occurences of the variable in its<br>
> > scope.  The variable's scope is all of the function after its first<br>
> > occurence.<br>
> ><br>
> > When we get to fun()s we have a conflict of principles.  Should the<br>
> > the same scoping rule apply to the fun() as to the surrounding function?<br>
> ><br>
> > Erlang has solved this with a pragmatic compromise (as often enough):<br>
> > variables bound in a fun() are local to the fun().  But variables from the<br>
> > outer scope that are referred to in a fun() are from the outer scope.  So<br>
> > if it has the same name it is the one in the outer scope.  Except in the<br>
> > fun() argument list.  Here variables are in general new ones so they are<br>
> > local to the fun(), even if a different variable with the same name exists<br>
> > in the outer scope.<br>
> ><br>
> > But a variable's value never changes within its scope.  Not today.<br>
> > Not with this proposal.  The snag is; which variable do we mean?<br>
> ><br>
> > ><br>
> > > So, if there is any proposal to put forth, in my view, it is to get rid<br>
> > of<br>
> > > variable shadowing.<br>
> ><br>
> > You are free to sketch on one; it does not have to be an EEP.<br>
> ><br>
> > A problem is that today variables in a fun() head shadows variables from<br>
> > the outer scope, and the compiler warns about it.  If the behaviour should<br>
> > be changed into not shadowing variables the compiler could not warn about<br>
> > using a variable from the outer scope because it is now assumed that it is<br>
> > the correct semantics.  If there was an annotation of the variables that<br>
> > are bound instead of matched the compiler could tell the difference.  Such<br>
> > an annotation would very much look like variable rebinding and could easily<br>
> > be extended to exactly that.<br>
> ><br>
> > Another possibility would be to introduce some kind of let...end construct<br>
> > to explicitly introduce variable scoping, which has been discussed before.<br>
> ><br>
> > There might, of course, be other possibilities.<br>
> > I am not a language expert.<br>
> ><br>
> > ><br>
> > > Also, already in this thread it is now being mentioned to have variable<br>
> > > rebinding support. If this EEP erodes such a core tenant (in my view) of<br>
> > > Erlang such that it leads to variable rebinding, it should be rejected<br>
> > on that<br>
> > > alone (in my view).<br>
> ><br>
> > I also do not want to get variable rebinding.  But this EEP should be<br>
> > evaluated on its own merits and on the possibilities it offers that we<br>
> > might want.<br>
> ><br>
> > ><br>
> > > But the part of the EEP that just completely nullifies it is:<br>
> > ><br>
> > > > In this case, there is no new binding of Y, and the use of Y in the fun<br>
> > > > clause body refers to the function parameter. But it is also possible<br>
> > to<br>
> > > > combine pinning and shadowing in the same pattern:<br>
> > > ><br>
> > > > f(X, Y) -><br>
> > > >     F = fun ({a, ^Y, Y})  -> {ok, Y};<br>
> > > >             (_) -> error<br>
> > > >         end,<br>
> > > >     F(X).<br>
> > > ><br>
> > > > In this case, the pinned field refers to the value of the function<br>
> > function<br>
> > > > parameter, but there is also a new shadowing binding of Y to the third<br>
> > field<br>
> > > > of the tuple. The use in the fun clause body now refers to the<br>
> > shadowing<br>
> > > > instance.<br>
> > ><br>
> > > You now have two variables named the same thing with different values. It<br>
> > > breaks fundamental way of thinking in Erlang.  There is zero value in<br>
> > allowing<br>
> > > this. Use a different variable name.<br>
> ><br>
> > I agree that anyone that writes code like that deserves a good telling<br>
> > off...<br>
> ><br>
> > I think the problem is in the variable shadowing, not in the pinning<br>
> > operator.<br>
> > Today we get a compiler warning when a variable in a fun() head shadows one<br>
> > in the outer scope.  But other than that it is legal.<br>
> ><br>
> > We do not, however, get a warning when a variable is used in a fun() body<br>
> > from the surrounding function since a fun() body has got the same scope as<br>
> > the surrounding function, except for newly bound variables...  Accidentally<br>
> > referring to a variable from outside the fun() is a problem.<br>
> ><br>
> > With the pinning operator it becomes possible to explicitly refer to the<br>
> > outer scope and thereby possible to warn for referring to the containing<br>
> > function without being explicit, making the fun() more a real variable<br>
> > scope.<br>
> ><br>
> > ><br>
> > > The EEP Rationale section is likewise problematic, but copying it here<br>
> > and<br>
> > > responding to each point is tiresome.<br>
> ><br>
> > That was some handwaving.  You are stating that it is problematic without<br>
> > explaining why.  Not very constructive.<br>
> ><br>
> > ><br>
> > > So, I'd like to propose that any EEP added to<br>
> > <a href="https://github.com/erlang/eep/" rel="noreferrer" target="_blank">https://github.com/erlang/eep/</a><br>
> > > is done in a PR and left open for reviews/comments on the PR for a<br>
> > period of<br>
> > > time. There is much in the EEP that I would comment on, line by line.<br>
> ><br>
> > That is an interesting suggestion.  EEP 1 states that after an EEP has been<br>
> > accepted (not approved) it should try to get community support, but it does<br>
> > not say how.<br>
> ><br>
> > The current situation where this EEP is discussed in <a href="mailto:eeps@erlang.org" target="_blank">eeps@erlang.org</a>,<br>
> > <a href="mailto:erlang-questions@erlang.org" target="_blank">erlang-questions@erlang.org</a>, and in the PR for the reference<br>
> > implementation<br>
> > is not good.<br>
> ><br>
> > Having discussions about the EEP before submission (and after(?)) in a pull<br>
> > request on the eep repository on GitHub sounds like a good step, except for<br>
> > the ones that do not have accounts on GitHub, and it would drive us further<br>
> > into the GitHub (/Microsoft) hands, which may be politically sensitive.<br>
> ><br>
> > ><br>
> > > There has been concern on the list that this discussion has not remained<br>
> > > technical and on point to the value of the EEP, and I would suggest the<br>
> > fault<br>
> > > lies in the tool being used to elicit feedback (e-mail). That concern<br>
> > would be<br>
> > > addressed by allowing people to comment line by line on the EEP and<br>
> > discuss<br>
> > > the specific points of the EEP in the PR itself. And we can avoid blame<br>
> > being<br>
> > > thrown around about people having or not having read the EEP.<br>
> ><br>
> > A very valid point.  I also think GitHub Pull Requests offer better<br>
> > possibilities for discussion around details.<br>
> ><br>
> > ><br>
> > > Regards,<br>
> > ><br>
> > > Chris<br>
> ><br>
> > --<br>
> ><br>
> > / Raimo Niskanen, Erlang/OTP, Ericsson AB<br>
> ><br>
<br>
-- <br>
<br>
/ Raimo Niskanen, Erlang/OTP, Ericsson AB<br>
</blockquote></div></div>