|
Hello,
In erlang R14B01 shell: 1> <<1234>> = <<1234>>. ** exception error: no match of right hand side value <<"Ò">> Right side of expression evaluates to <<210>> (8 least significant bits from 1234), so the following matches: 2> <<210>> = <<1234>>. <<"Ò">> 1234 on the left side of expression should evaluate to <<210>> too, but it doesn't: 3> <<1234>> = <<210>>. ** exception error: no match of right hand side value <<"Ò">> Is there an explanation of what happens when integer on left side of binary matching expression doesn't fit into default 8 bit? Regards, Anton Lebedevich. ________________________________________________________________ erlang-questions (at) erlang.org mailing list. See http://www.erlang.org/faq.html To unsubscribe; mailto:[hidden email] |
|
Le 25 févr. 2011 à 20:23, Anton Lebedevich a écrit :
> Hello, > > In erlang R14B01 shell: > 1> <<1234>> = <<1234>>. > ** exception error: no match of right hand side value <<"Ò">> > > Right side of expression evaluates to <<210>> (8 least significant bits > from 1234), so the following matches: > 2> <<210>> = <<1234>>. > <<"Ò">> > > 1234 on the left side of expression should evaluate to <<210>> too, but > it doesn't: > 3> <<1234>> = <<210>>. > ** exception error: no match of right hand side value <<"Ò">> > > Is there an explanation of what happens when integer on left side of > binary matching expression doesn't fit into default 8 bit? > > Regards, > Anton Lebedevich. Wild guess here, but I would say <<1234>> on the right side constructs a binary using the use-only-the-8-least-significant-bits, thus not failing because the integer is too large; while <<1234>> on the left side is a pattern, so the integer isn't truncated and obviously fails to match since you can't have a byte larger than 255. Regards, -- Anthony Ramine Dev:Extend http://dev-extend.eu ________________________________________________________________ erlang-questions (at) erlang.org mailing list. See http://www.erlang.org/faq.html To unsubscribe; mailto:[hidden email] |
|
On 02/26/2011 05:24 PM, Anthony Ramine wrote:
> Le 25 févr. 2011 à 20:23, Anton Lebedevich a écrit : > >> Hello, >> >> In erlang R14B01 shell: >>1> <<1234>> = <<1234>>. ** exception error: no match of right hand side value <<"Ò">> >> >> Right side of expression evaluates to <<210>> (8 least significant >> bits from 1234), so the following matches: >> 2> <<210>> = <<1234>>. >> <<"Ò">> >> >> 1234 on the left side of expression should evaluate to <<210>> too, >> but it doesn't: >> 3> <<1234>> = <<210>>. ** exception error: no match of right hand side value <<"Ò">> >> >> Is there an explanation of what happens when integer on left side >> of binary matching expression doesn't fit into default 8 bit? >> >> Regards, Anton Lebedevich. > > Wild guess here, but I would say <<1234>> on the right side > constructs a binary using the use-only-the-8-least-significant-bits, > thus not failing because the integer is too large; while <<1234>> on > the left side is a pattern, so the integer isn't truncated and > obviously fails to match since you can't have a byte larger than > 255. Yes, <<1234>> on the right side becomes <<210>>, but I can't figure out what happens with <<1234> on the left side. Obviously it isn't truncated to <<210>> (least significant 8 bits), it doesn't fit into 16 bit too: 1> <<1234>> = <<1234:16>>. ** exception error: no match of right hand side value <<4,210>> Regards, Anton Lebedevich. ________________________________________________________________ erlang-questions (at) erlang.org mailing list. See http://www.erlang.org/faq.html To unsubscribe; mailto:[hidden email] |
|
Le 26 févr. 2011 à 17:37, Anton Lebedevich a écrit :
> On 02/26/2011 05:24 PM, Anthony Ramine wrote: >> Le 25 févr. 2011 à 20:23, Anton Lebedevich a écrit : >> >>> Hello, >>> >>> In erlang R14B01 shell: >>> 1> <<1234>> = <<1234>>. ** exception error: no match of right hand > side value <<"Ò">> >>> >>> Right side of expression evaluates to <<210>> (8 least significant >>> bits from 1234), so the following matches: >>> 2> <<210>> = <<1234>>. >>> <<"Ò">> >>> >>> 1234 on the left side of expression should evaluate to <<210>> too, >>> but it doesn't: >>> 3> <<1234>> = <<210>>. ** exception error: no match of right hand > side value <<"Ò">> >>> >>> Is there an explanation of what happens when integer on left side >>> of binary matching expression doesn't fit into default 8 bit? >>> >>> Regards, Anton Lebedevich. >> >> Wild guess here, but I would say <<1234>> on the right side >> constructs a binary using the use-only-the-8-least-significant-bits, >> thus not failing because the integer is too large; while <<1234>> on >> the left side is a pattern, so the integer isn't truncated and >> obviously fails to match since you can't have a byte larger than >> 255. > > Yes, <<1234>> on the right side becomes <<210>>, but I can't figure out > what happens with <<1234> on the left side. Obviously it isn't truncated > to <<210>> (least significant 8 bits), it doesn't fit into 16 bit too: > 1> <<1234>> = <<1234:16>>. > ** exception error: no match of right hand side value <<4,210>> > > Regards, > Anton Lebedevich. As I said, the thing on the left is a pattern, so I think it actually compiles to "a binary which the only byte's value is 1234", which obviously won't ever match anything. That could be the intended behaviour as much as it could be a bug, IMHO. -- Anthony Ramine Dev:Extend http://dev-extend.eu ________________________________________________________________ erlang-questions (at) erlang.org mailing list. See http://www.erlang.org/faq.html To unsubscribe; mailto:[hidden email] |
|
On 02/26/2011 06:04 PM, Anthony Ramine wrote:
> Le 26 févr. 2011 à 17:37, Anton Lebedevich a écrit : > >> On 02/26/2011 05:24 PM, Anthony Ramine wrote: >> >> Yes,<<1234>> on the right side becomes<<210>>, but I can't figure out >> what happens with<<1234> on the left side. Obviously it isn't truncated >> to<<210>> (least significant 8 bits), it doesn't fit into 16 bit too: >> 1> <<1234>> =<<1234:16>>. >> ** exception error: no match of right hand side value<<4,210>> >> >> Regards, >> Anton Lebedevich. > > As I said, the thing on the left is a pattern, so I think it actually compiles to > "a binary which the only byte's value is 1234", which obviously won't ever match > anything. > > That could be the intended behaviour as much as it could be a bug, IMHO. What about this: 9> <<1234:8>> = <<1234:8>>. ** exception error: no match of right hand side value <<"Ò">> 10> <<1234:16>> = <<1234:16>>. <<4,210>> -- Loïc Hoguin Dev:Extend ________________________________________________________________ erlang-questions (at) erlang.org mailing list. See http://www.erlang.org/faq.html To unsubscribe; mailto:[hidden email] |
|
In reply to this post by mabrek
----- "Loïc Hoguin" <[hidden email]> wrote:
> On 02/26/2011 06:04 PM, Anthony Ramine wrote: >> Le 26 févr. 2011 à 17:37, Anton Lebedevich a écrit : >> >> As I said, the thing on the left is a pattern, so I think it actually compiles to >> "a binary which the only byte's value is 1234", which obviously won't ever match >> anything. >> >> That could be the intended behaviour as much as it could be a bug, IMHO. > > What about this: > > 9> <<1234:8>> = <<1234:8>>. > ** exception error: no match of right hand side value <<"Ò">> > 10> <<1234:16>> = <<1234:16>>. The behaviour is not a bug, it is rather an effect of how the expression is evaluated. The first thing to be aware of is that expressions in the shell are not compiled but are interpreted, done in the module erl_eval. This explains any differences between compiled code and the shell. In this case Anton is close. When tryin to match a binary the matcher first uses the bitspecs in the binary pattern to extract a value, then it tries to match it against the value given in the pattern. In the first case it extracts the first 8 bit integer from the binary, 210, and tries to match it against 1234, which fails. In the second it extracts the first 16 bit integer, 1234, which suceeds. If the pattern had been <<12.34/float>> it would have extracted the first 64 bits as a float and tried to match it against 12.34. One of the cool things with binaries is that there is no info in the binary saying how it was created so I can do lots of fun things when I pull it apart. Robert -- Robert Virding, Erlang Solutions Ltd. ________________________________________________________________ erlang-questions (at) erlang.org mailing list. See http://www.erlang.org/faq.html To unsubscribe; mailto:[hidden email] |
|
Le 26 févr. 2011 à 20:28, Robert Virding a écrit :
> ----- "Loïc Hoguin" <[hidden email]> wrote: > >> On 02/26/2011 06:04 PM, Anthony Ramine wrote: >>> Le 26 févr. 2011 à 17:37, Anton Lebedevich a écrit : >>> >>> As I said, the thing on the left is a pattern, so I think it actually compiles to >>> "a binary which the only byte's value is 1234", which obviously won't ever match >>> anything. >>> >>> That could be the intended behaviour as much as it could be a bug, IMHO. >> >> What about this: >> >> 9> <<1234:8>> = <<1234:8>>. >> ** exception error: no match of right hand side value <<"Ò">> >> 10> <<1234:16>> = <<1234:16>>. > > The behaviour is not a bug, it is rather an effect of how the expression is evaluated. The first thing to be aware of is that expressions in the shell are not compiled but are interpreted, done in the module erl_eval. This explains any differences between compiled code and the shell. > > In this case Anton is close. When tryin to match a binary the matcher first uses the bitspecs in the binary pattern to extract a value, then it tries to match it against the value given in the pattern. > > In the first case it extracts the first 8 bit integer from the binary, 210, and tries to match it against 1234, which fails. In the second it extracts the first 16 bit integer, 1234, which suceeds. If the pattern had been <<12.34/float>> it would have extracted the first 64 bits as a float and tried to match it against 12.34. > > One of the cool things with binaries is that there is no info in the binary saying how it was created so I can do lots of fun things when I pull it apart. > > Robert While it may be cool, I think the compiler should issue a warning when an impossible pattern is encountered. 1234 is obviously not representable with only 8 bits. -- Anthony Ramine Dev:Extend http://dev-extend.eu ________________________________________________________________ erlang-questions (at) erlang.org mailing list. See http://www.erlang.org/faq.html To unsubscribe; mailto:[hidden email] |
|
I agree, it's confusing and this is one of those things that you "have to know". A shell interpreter or compiler warning would be nice. However, the binary syntax in erlang is extremely powerful, and this quirk is really just a small inconvenience in the long run.
(BTW, Anthony - I, too, tend to run away fast from anything in software that is described with the phrases: "the cool thing" or "makes it easy".) /s |
|
In reply to this post by mabrek
----- "Anthony Ramine" <[hidden email]> wrote: > Le 26 févr. 2011 à 20:28, Robert Virding a écrit : > > > One of the cool things with binaries is that there is no info in the > binary saying how it was created so I can do lots of fun things when I > pull it apart. > > > > Robert > > While it may be cool, I think the compiler should issue a warning when > an impossible pattern is encountered. 1234 is obviously not > representable with only 8 bits. The coolness was not an impossible pattern, I agree that the compiler should warn, but more the fact that you can pull apart a binary differently from how it was constructed. It is with that you can do cool things. Robert -- Robert Virding, Erlang Solutions Ltd. ________________________________________________________________ erlang-questions (at) erlang.org mailing list. See http://www.erlang.org/faq.html To unsubscribe; mailto:[hidden email] |
|
Le 28 févr. 2011 à 01:40, Robert Virding a écrit : > > ----- "Anthony Ramine" <[hidden email]> wrote: > >> Le 26 févr. 2011 à 20:28, Robert Virding a écrit : >> >>> One of the cool things with binaries is that there is no info in the >> binary saying how it was created so I can do lots of fun things when I >> pull it apart. >>> >>> Robert >> >> While it may be cool, I think the compiler should issue a warning when >> an impossible pattern is encountered. 1234 is obviously not >> representable with only 8 bits. > > The coolness was not an impossible pattern, I agree that the compiler should warn, but more the fact that you can pull apart a binary differently from how it was constructed. It is with that you can do cool things. > > Robert That certainly looks impossible to me, how can you match <<1234>>? You make it sound like if you know the underlying binary representation you can match it. -- Anthony Ramine Dev:Extend http://dev-extend.eu ________________________________________________________________ erlang-questions (at) erlang.org mailing list. See http://www.erlang.org/faq.html To unsubscribe; mailto:[hidden email] |
|
In reply to this post by mabrek
----- "Anthony Ramine" <[hidden email]> wrote:
> Le 28 févr. 2011 à 01:40, Robert Virding a écrit : > > > > > ----- "Anthony Ramine" <[hidden email]> wrote: > > > >> Le 26 févr. 2011 à 20:28, Robert Virding a écrit : > >> > >>> One of the cool things with binaries is that there is no info in > the > >> binary saying how it was created so I can do lots of fun things > when I > >> pull it apart. > >>> > >>> Robert > >> > >> While it may be cool, I think the compiler should issue a warning > when > >> an impossible pattern is encountered. 1234 is obviously not > >> representable with only 8 bits. > > > > The coolness was not an impossible pattern, I agree that the > compiler should warn, but more the fact that you can pull apart a > binary differently from how it was constructed. It is with that you > can do cool things. > > > > Robert > > That certainly looks impossible to me, how can you match <<1234>>? You > make it sound like if you know the underlying binary representation > you can match it. Quite the opposite. <<1234>> is definitely as impossible pattern, and constructor for that matter, as the default in a binary without any type or size specifier is an 8-bit integer. And 1234 is not an 8-bit integer. I think the system *should* complain. What I meant is that you can do things like: <<Sign:1,Exponent:11,Significand:52>> = << 1.234:64/float >> (with reservation for the order) where you pull apart a 64-bit floating point number into its components. You construct a binary with a floating-point number and pull it apart into three integers. That is cool. Robert ________________________________________________________________ erlang-questions (at) erlang.org mailing list. See http://www.erlang.org/faq.html To unsubscribe; mailto:[hidden email] |
|
Le 28 févr. 2011 à 14:15, Robert Virding a écrit :
> ----- "Anthony Ramine" <[hidden email]> wrote: > >> Le 28 févr. 2011 à 01:40, Robert Virding a écrit : >> >>> >>> ----- "Anthony Ramine" <[hidden email]> wrote: >>> >>>> Le 26 févr. 2011 à 20:28, Robert Virding a écrit : >>>> >>>>> One of the cool things with binaries is that there is no info in >> the >>>> binary saying how it was created so I can do lots of fun things >> when I >>>> pull it apart. >>>>> >>>>> Robert >>>> >>>> While it may be cool, I think the compiler should issue a warning >> when >>>> an impossible pattern is encountered. 1234 is obviously not >>>> representable with only 8 bits. >>> >>> The coolness was not an impossible pattern, I agree that the >> compiler should warn, but more the fact that you can pull apart a >> binary differently from how it was constructed. It is with that you >> can do cool things. >>> >>> Robert >> >> That certainly looks impossible to me, how can you match <<1234>>? You >> make it sound like if you know the underlying binary representation >> you can match it. > > Quite the opposite. <<1234>> is definitely as impossible pattern, and constructor for that matter, as the default in a binary without any type or size specifier is an 8-bit integer. And 1234 is not an 8-bit integer. I think the system *should* complain. > > What I meant is that you can do things like: > > <<Sign:1,Exponent:11,Significand:52>> = << 1.234:64/float >> > > (with reservation for the order) where you pull apart a 64-bit floating point number into its components. You construct a binary with a floating-point number and pull it apart into three integers. That is cool. > > Robert So we agree, but I misread what you said and thought the opposite ;) The compiler does not complain with <<1234>> and that's already weird as it is. It gets to a whole new level of weirdness when you discover that <<foo>> is also a legal pattern even though it won't ever match. -- Anthony Ramine Dev:Extend http://dev-extend.eu ________________________________________________________________ erlang-questions (at) erlang.org mailing list. See http://www.erlang.org/faq.html To unsubscribe; mailto:[hidden email] |
|
In reply to this post by mabrek
----- "Anthony Ramine" <[hidden email]> wrote: > So we agree, but I misread what you said and thought the opposite ;) > The compiler does not complain with <<1234>> and that's already weird > as it is. It gets to a whole new level of weirdness when you discover > that <<foo>> is also a legal pattern even though it won't ever match. Yes, I checked the compiler as well and, unfortunately :-), you are right. If you check the generated code you will find that works in the same way as the interpreter: it first extracts the first 8 bit integer (default as no size or type specified) and then tries to match it against the atom foo, which fails. I would have thought that erl_lint should have caught this. Just to boast a bit: in LFE this results in an error in both the compiler and interpreter. :-) Robert -- Robert Virding, Erlang Solutions Ltd. ________________________________________________________________ erlang-questions (at) erlang.org mailing list. See http://www.erlang.org/faq.html To unsubscribe; mailto:[hidden email] |
| Powered by Nabble | Edit this page |
