[erlang-questions] Binary match in function head doesn't compile

Dmitry Kolesnikov dmkolesnikov@REDACTED
Wed Oct 31 21:13:37 CET 2012


Erik,

I believe you can use closure instead of case to achieve re-usability of binary context.

e.g.

parse(Len, Bin) ->
   fun(<<Tkn:Len/binary, $, , Rest/binary>>) -> 
           {Len, Tkn, Rest}; 
        (<<Tkn:Len/binary, $: , Rest/binary>>) ->
           ....
   end.

- Dmitry


On Oct 31, 2012, at 9:52 PM, Erik Pearson wrote:

> Thanks, Robert, that helps clarify the state of things.
> Do you think it would be useful if it worked "the way I would like"?
> It seems that in the specific case of walking a binary by extending
> the length of a sub-binary in the match (via a Len argument) would be
> much more efficient than binary accumulation which always does at
> least some allocation (256 bytes) and copying, and also more efficient
> than moving the  code into a case (where the Len will already be
> bound.) It seems that the compiler would need to notice that what it
> thinks is an unbound variable is actually guaranteed to be bound in
> another argument, and express this as a dependency in the head pattern
> match code.
> Erik.
> 
> 
> On Wed, Oct 31, 2012 at 11:45 AM, Robert Virding
> <robert.virding@REDACTED> wrote:
>> I don't know if it is actually explicitly stated anywhere but multiple
>> occurrences of a variable in a pattern match means that the values the
>> variable would get in each occurrence are tested for equality. They are not
>> being used as you would like. Also the order in which function arguments are
>> matched is not defined, and if we just test multiple variable occurrences
>> for equality does not matter. This means that when you match the binary N
>> may not yet have a value. In fact we do match left-to-right (but don't tell
>> anyone) so N will in fact not have a value. Flipping the order of the
>> arguments will not help here.
>> 
>> It is different when match *INSIDE* a binary. There, by necessity, the
>> pattern match goes left-to-right and if match a value from a binary you can
>> use the value later in the binary match. So you can do:
>> 
>> <<N,B1:N/binary,Rest/binary>>  = Bin
>> 
>> Robert
>> 
>> ________________________________
>> 
>> From: "Erik Pearson" <erik@REDACTED>
>> To: "erlang-questions Questions" <erlang-questions@REDACTED>
>> Sent: Sunday, 28 October, 2012 11:08:44 AM
>> Subject: Re: [erlang-questions] Binary match in function head doesn't
>> compile
>> 
>> 
>> Is there a reference for the resolution of patterns in function/clause head
>> similar to
>> 
>> http://www.erlang.org/doc/apps/erts/match_spec.html
>> 
>> but for regular Erlang? The docs on the abstract format is useful
>> 
>> http://www.erlang.org/doc/apps/erts/absform.html
>> 
>> There are a few places in the docs that refer to the process of matching the
>> function clause head against arguments
>> 
>> e.g. the function overview
>> 
>> http://www.erlang.org/doc/reference_manual/functions.html#id74558
>> 
>> but it would be really useful to have those references link to documentation
>> which describes this process.
>> 
>> Thanks,
>> Erik.
>> 
>> (ps - I'm happy with your answer, Björn-Egil, but hoping this thread can
>> include some solid leads for others researching similar issues.)
>> 
>> (pps - there is a definitive response to my original post from Björn-Egil
>> Dahlberg below -- he inadvertently sent it directly to me)
>> 
>> On Fri, Oct 26, 2012 at 11:59 AM, Björn-Egil Dahlberg
>> <wallentin.dahlberg@REDACTED> wrote:
>>> 
>>> 
>>> 
>>> 2012/10/26 Erik Pearson <erik@REDACTED>
>>>> 
>>>> Hi,
>>>> 
>>>> I'm wondering why this
>>>> 
>>>> test(<<Field:Len/binary, Rest/binary>>, Len) ->
>>>>    {Len, Field, Rest}.
>>>> 
>>>> does not compile, complaining that "variable 'Len' is unbound", while
>>>> this
>>>> 
>>>> test(<<Field:2/binary, Rest/binary>>, Field) ->
>>>>    {Field, Rest}.
>>>> 
>>>> does. For some reason the compiler doesn't see the Len from the match
>>>> spec in the arguments, but it does see Field. Is that by design?
>>> 
>>> 
>>> Yes and a limitation that is being adressed.
>>> 
>>> 
>>>> 
>>>> BTW  supplying a variable for Len does work in this case:
>>>> 
>>>> test(Bin, Len) ->
>>>>  <<Field:Len/binary, Rest/binary>> = Bin,
>>>>  {Len, Field, Rest}.
>>> 
>>> 
>>> The difference here is that Len is bound when entering the function body
>>> as opposed when it is in the function head.
>>> 
>>> We have had fierce debates on, among other things, matching behaviors for
>>> Maps (extended frames/hashes) which also have led to redesigning parts how
>>> binary matching is done in function heads. This is currently in the
>>> prototyping stages and it is to early to say to which release this will be
>>> ready.
>>> 
>>> // Björn-Egil
>> 
>> 
>> 
>> _______________________________________________
>> erlang-questions mailing list
>> erlang-questions@REDACTED
>> http://erlang.org/mailman/listinfo/erlang-questions
>> 
>> 
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions




More information about the erlang-questions mailing list