New EEP draft: Pinning operator ^ in patterns

Raimo Niskanen raimo+erlang-questions@REDACTED
Fri Jan 22 17:05:51 CET 2021

On Fri, Jan 22, 2021 at 08:57:29PM +0900, zxq9 wrote:
> On 2021/01/22 18:09, Raimo Niskanen wrote:
> > On Fri, Jan 22, 2021 at 02:28:35AM +0900, zxq9 wrote:
> Here is how this goes.
> You say "Make an argument"
> I do. Many do.
> You say "Well, I don't feel that addresses X"
> We address X directly.

Apparently I still did not think it addressed X.

> "Well, that's not what I meant so derpy-doo let's just go with the plan!"

"go on with the plan" is an incorrect suggestion that there is a plan.

> ffs...
>  > You are attempting the Trump argumentation line:
>  >     Repeat a lie until it is accepted as true.
>  > I hate that.  Please stop doing that!
> Bringing Trump up is just perfect.
> Bravo.

Sorry about that!  It was inappropriate.

But you repeatedly claimed that what you write would not matter because
someone(s) have a hidden agenda.  There is no agenda I am aware of, and
repeatedly claiming that will undermine the faith in the EEP process.

And yes, there is an EEP process, it is stated in EEP 1, a bit outdated,
but nevertheless.

> Incidentally, let me define the Woke technique:
> 1. Introduce a fringe problem almost nobody feels they have that only 

I do not think it is a fringe problem.

> presents in a corner case and change core principles everyone else has 

I do not think it changes core principles.

> followed based on it.
> Why is using Elixir not good enough? It already exists.

I do not like Elixir.

> Why not discuss eliminating shadowing entirely? Is there some reason 
> this suggestion has not been addressed at all? It is a curious omission 
> given that it has been brought up multiple times.

It has been talked about, and I am for!

Oddly enough ;-) I think the pinning operator would help when removing

    foo(X) ->
	F = fun (A, ^X) ->
	        {A, X}

instead of 

    foo(X) ->
	F = fun (A, X1) when X1 =:= X ->
	        {A, X1}

I think the first is neater, since that is how you can write it in a case.
The X is the X everywhere.  Without the pinning operator one can easlily
miss that the ^X is a match.

Just removing shadowing would make it like matching in case today.
That would also make the language be more uniform.

But I think would be a source of error since it is hard to tell what
is a match and what is a bind.  Just like matching in case patterns today.

> Let's say I want to forward a message to all clients, skipping the 
> origin of the message. For example does this not make quite sense?
> f(Message, Origin, Clients) ->
>    ForwardTo =
>      fun
>        (Origin) -> ok;
>        (Client) -> Client ! {msg, Origin, Message}
>      end,
>    lists:foreach(ForwardTo, Clients).
> Why must we use a guard here instead? OH THE PINNING OPERATOR!
> No.
> I mean, why is it allowed that Origin means one thing in just the 
> lambda's head but another in the body of the lambda if otherwise not 
> appearing in its head? We are able to close over values.
> The design decision to allow shadowing in this one silly case was a 
> mistake, a minor blemish on the language. We have a warning about it 
> because it is a blemish. But the proposal to "fix" it is to introduce an 
> even worse blemish -- great, now we have two blemishes and no fixes.
> That's not what "fix" means.

Smoke screen. It is primarily not this problem that is targeted.

> Your question #1 in some previous message, "would this change make 
> Erlang a better language?" was answered directly: No. It will not. It 
> will make it more complex and confusing to explain to beginners and 

Those are not answers.  Those are opinions.

That was not a question.  It was a discussion subject.

> introduce a feature with a name that is going to be very hard for 
> newcomers (and oldcomers not following the list and reading every line 
> of the release notes) to search for when they first encounter this.

Those are assumptions.

> A fix would literally be to fix the actual root problem: the ability to 
> shadow on literally the same line where you might close over a value 

And I say that the root problem is the automatic binding in a pattern.
Under that assumption would removing shadowing in fun() heads increase the
root problem.

> from the surrounding scope. I would point out that creating closures is 
> the main utility of anonymous functions in Erlang, and it would be a 
> benefit to make the definition of those lambdas consistent with every 
> other area of the language. No need for the "intention to be clear" -- 

Some think that consistency in this case is that there should be no way a
variable has a different value in a fun() than outside it.  Not all share
your view of consistency here.

That Erlang does not have a possibility for proper variable scoping
is a problem, though.  At least for writing macros.

> just make the rule consistent everywhere and you have no confusion about 
> intention. We don't have to "pin" values in case, if, matching for 

There is no confusion about intention.
The purpose is to clarify the intention.

> assertion, double assignment of the same value to check if it is the 
> same value in a normal function head, etc.
> Either
> 1. Leave it the way it is now because everyone knows it already.
> 2. Move toward eliminating shadowing completely.
> In all cases:
> - Encourage shorter functions.

Functions should have their proper size.  Do not create lots of small
functions for the sake of principles.

> - Stick to core principles.

It seems which principles are core principles varies.

> - Remember that just because bad code exists out there and horrible code 
> can be written in any language does NOT mean that you should enable the 
> casual creation of trash-tier code.

I agree.  Was that ever suggested?

> - If you are maintaining a codebase with silly problems FIX THAT CODE.

Easy to say.  Harder to do.  Often no business case for that.

> -Craig

Best regards

/ Raimo Niskanen, Erlang/OTP, Ericsson AB

More information about the erlang-questions mailing list