New EEP draft: Pinning operator ^ in patterns
Kostis Sagonas
kostis@REDACTED
Thu Jan 21 01:09:25 CET 2021
Some days ago, I was asked (privately) to explicitly voice my opinion on
this topic. I've hesitated to do so, for various reasons, but FWIW here
is my view on this EEP.
TL;DR : Erlang will *not* become a better language with this EEP.
(as originally described, at least.)
For those interested to read further, some more explanation follows below.
On 1/15/21 4:35 PM, Raimo Niskanen wrote:
> On Fri, Jan 15, 2021 at 04:22:55PM +0100, Nicolas Martyanoff wrote:
> :
>> I believe this discussion is moot. We can spend hours arguing about CS theory,
>> but at the end of the day, the problem is about changing a fundamental aspect
>> of a language. And clearly quite a lot of developers, me included, are worried
>> about this kind of change.
> And I want to get clarity about exactly why so many developers are worried
> about this particular proposed change, and therefore try to look thoroughly
> at the arguments.
>
> It is as you say a fundamental detail in the language.
>
> 1) Would the language be a better language with a mandatory pinning operator?
>
> 2) If so is there a migration path worth the trouble?
>
> So far I think the discussion has been centered around 2),
> before talking about 1).
Raimo raises an interesting point here. Let's focus on 1) first.
IMO, languages do not become better by adding syntactical constructs
which have add hoc design and, more importantly, add nothing to the
expressive power of the language (i.e., they can be expressed with the
constructs which already exist in the language, even if these are
currently slightly more verbose).
I claim that this "operator" (annotation is a _much_ better word for it)
is currently ad hoc because it is not what I would have expected from
its design/semantics. Its original post in this list described it as:
The ^ operator allows you to annotate already-bound pattern variables
so, for such an operator with a consistent design, this would mean that
a pattern as <<X:8, X:X, ...>> would be allowed, and in fact at some
point in the future be _required_, to be written as <<X:8, ^X:^X, ...>>,
but from what I can see/read in this EEP, this is not the case.
(Yes, the above is ugly alright, but it's at least consistent.)
Also, I claim that, even as a compiler annotation, it does not add any
expressive power (of the form that I would have expected, at least)
because an annotation that _did_ add to the expressive power of pattern
matching would have allowed programmers to control/tell the compiler the
order that pattern matching should be performed and write clause heads
of the form:
f(X, <<_:^X>>) -> % Hey compiler, I'm telling you in which order to
% bind variables to allow me to write what I want
From what I can see, the EEP does nothing of the above.
Now, let's focus on what the EEP actually does. The main thing it does
is to shut off compiler warnings when the new warning pass is enabled,
which touches point 2) of Raimo's list, the migration path and its trouble.
But let me answer this question first:
Should this warning pass be introduced?
My view is YES. This pass can certainly be useful to many developers
and I also bet it will detect real bugs in existing code bases. So YES
with all capital.
But IMO, we do not need strange hieroglyphics (with ad hoc design, as I
explained above) to shut off these warnings. Plain `when` clauses with
=:= tests suffice for this -- perhaps with the exception of pattern
matching with variables used as lengths of bitstring segments where the
compiler warning pass can simply be silenced / not check.
For example, instead of changing the code:
f(X, Y) ->
io:format("checking: ~p", [Y]),
case X of
{a, Y} -> {ok, Y};
_ -> error
end.
to:
f(X, Y) ->
io:format("checking: ~p", [Y]),
case X of
{a, ^Y} -> {ok, Y};
_ -> error
end.
one will need to change it to:
f(X, Y) ->
io:format("checking: ~p", [Y]),
case X of
{a, FreshY} when FreshY =:= Y -> {ok, Y};
_ -> error
end.
and the compiler will be equally satisfied. (That's what I would be
doing in my code, at least.)
Note that the code after the above change will be compilable not only in
the new compiler with the warning pass enabled, but also with OLDER
compilers that do not understand the ^ hieroglyphics.
[So I can still use the R15B01 compiler, which is my favorite :-)]
If Richard's counting is correct and the places where such changes are
needed are only a few --and I have no reason to doubt him-- the effort
is equally small and the net effect is the same. I would even argue
that readability of the code has been increased for future readers.
Of course, the greatest advantage of the above scheme is that nobody
would ever need to do a Google search for "Erlang carot operator" :-)
Jokes aside, this works for most case expressions, but what about Loic's
favorite coding idiom? (Presumably he likes to use that in test code.)
X = 5,
...,
X = inc(4),
...,
X = dec(6),
...
Well, I would advice to use ?assert and friends in such situations.
The post is already too long, so I will stop here.
Kostis
More information about the erlang-questions
mailing list