New EEP draft: Pinning operator ^ in patterns
Raimo Niskanen
raimo+eeps@REDACTED
Thu Jan 14 16:49:28 CET 2021
On Thu, Dec 24, 2020 at 04:05:12PM -0500, Fred Hebert wrote:
> On 12/24, Richard Carlsson wrote:
> >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.
> >
> >Generator patterns in list comprehensions or binary comprehensions
> >follow the same rules as fun clause heads, so with pinning we can for
> >example write the following code:
> >
> > f(X, Y) ->
> > [{b, Y} || {a, ^Y, Y} <- X].
> >
> >where the `Y` in `{b, Y}` is the shadowing instance bound to the third
> >element of the pattern tuple.
> >
>
> I don't understand the rationale here. If ^Y and Y are distinct in these
> patterns, they should be named differently. It sounds unsafe to let the
> values diverge. The rationale in fact tries to expand on it there:
I think the EEP would benefit from rephrasing this not as a feature, but rather
as an example to explain the semantics. If ^Y and Y are distinct a sensible
programmer would give them different names. So the examples in the EEP
should also do that, except when explaining what should happen if you
actually use both ^Y and Y.
/ Raimo Niskanen
>
> >Furthermore, in the odd case that the pattern would both need to
> >access the surrounding definition of `Y` as well as introduce a new
> >shadowing binding, this can be easily written using pinning:
> >
> > f(X, Y) ->
> > F = fun ({a, ^Y, Y}) -> {ok, Y};
> > (_) -> error
> > end,
> > F(X).
> >
> >but in current Erlang, two separate temporary variables would be
> >required:
> >
> > f(X, Y) ->
> > OuterY = Y,
> > F = fun ({a, Temp, Y}) when Temp =:= OuterY -> {ok, Y};
> > (_) -> error
> > end,
> > F(X).
> >
>
> But it still makes no sense why you would require Temp to be equal to Y
> but only use the inner binding specifically. Semantically there is no
> benefit to be had there, and this introduces a rebinding that isn't
> required?
>
> The one implementation detail that could have an impact there would be
> based on the values of binaries references where there is specifically a
> desire to use one more than the other.
>
> I'm opposed only to this specific part of the RFC as not helping making
> things clearer. Just name the variables differently and keep the
> shadowing warning.
> _______________________________________________
> eeps mailing list
> eeps@REDACTED
> http://erlang.org/mailman/listinfo/eeps
--
/ Raimo Niskanen, Erlang/OTP, Ericsson AB
More information about the eeps
mailing list