EEP 52: Allow key and size expressions in map and binary matching

Björn Gustavsson bjorn@REDACTED
Wed Jan 29 18:42:07 CET 2020


On Wed, Jan 29, 2020 at 5:03 PM Fred Hebert <mononcqc@REDACTED> wrote:
>
> First question, the following example is given as illegal:
>
> illegal_example6(Key, #{Key := Value}) -> Value.
>
> On the other hand, the text mentions this "All variables used in a key expression must be previously bound." If we go from the binary pattern match (<<Size:8,Payload:((Size-1)*8)/binary,Rest/binary>>), is there an implication that the following function call is valid and would match:
>
> maybe_legal_example(#{key := NextKey, NextKey := Value}) -> Value.

Illegal. With one exception, matching is not done in a left-to-right
order, but all variables in the pattern will be bound at the same
time. That means that the variables must be bound before the match
starts. For maps, that means that the variables referenced in key
expressions must be bound before the case (or receive) that matches
the map. In a function head, all map keys must be literals.

The exception to this general rule is that within a binary pattern,
the segments are matched from left to right, and a variable bound in a
previous segment can be used in the size expression for a segment
later in the binary pattern.

> Which given the map #{key => a, a => result} would return result. I don't want to assume whether it would work, but the idea of "previously bound" is a tad ambiguous in this case.

Yes, I should revise the text to make it clearer.

>
> I would also definitely encourage the "absurd sizes" to come with a compiler warning if an error is not acceptable.

The current implementation issues warnings for non-integer literals
used as a segment size.

>
> I'm not familiar enough with core erlang to properly review that part of the EEP, but I still have a few questions:
>
> Is there an expectation that the larger core erlang constructs will compile to the same underlying VM instructions and be as performant as they are right now, since it's mostly exploding the current higher-level operations into underlying ones?

In general, yes. I can certainly construct pathological cases for
which the generated code would be worse, but I don't expect it to be
an issue in practice. If some real-world code turns out to be worse,
we can improve the pattern matching compiler or add additional
optimization passes.

> Do the new core erlang constructs allow the creation of invalid programs that could break VM semantics? I.e. Were things such as  primop 'recv_peek_message'(), primop 'recv_next'(), and primop 'remove_message'() already allowed, or do they now allow someone to generate core-erlang programs that would re-read the same message off a mailbox multiple times, or introspect the list more fully without actually extracting messages without further VM support (i.e. process_info()-based introspection no longer needed)

Everything that you now can do in Core Erlang could be done by writing
BEAM assembly code. So I suppose it might be slightly easier than
before to do something bad because Core Erlang is at a higher level.

/Björn

-- 
Björn Gustavsson, Erlang/OTP, Ericsson AB



More information about the eeps mailing list