Reputation: 613
I'm looking to construct a bit string bit by bit, and am wondering how to do so.
I was expecting the syntax to be similar to concatenating two bytes like so:
iex(1)> <<1>> <> <<1>>
<<1, 1>>
So I tried:
iex(2) <<1::1>> <> <<1::1>>
** (ArgumentError) argument error
Is this possible? Thanks in advance.
Upvotes: 6
Views: 2419
Reputation: 11288
I'm not exactly sure if it's a bug or not, but let's explore what's going on and worry about that later.
What is <>
? It turns out it's just a macro defined in Kernel.<>/2
. What can we do with macros to understand them better? Expand them!
quote(do: <<1::1>> <> <<1::1>>)
|> Macro.expand(__ENV__)
|> Macro.to_string
#=> "<<(<<1::1>>::binary), (<<1::1>>::binary)>>"
We can see that <>
desugars to the normal binary syntax. Unfortunately for us it assumes it's arguments are binaries! We have bitstrings - hence the error. How to fix it? We can use the regular binary/bitstring syntax directly:
<< <<1::1>>::bitstring, <<1::1>>::bitstring >>
#=> <<3::size(2)>>
Which works as expected.
EDIT: I followed up on this. This behaviour is expected. <>
operator is designed to work on binaries and not bitstrings. The error is rather unpleasant, but it's coming deep from within Erlang.
Upvotes: 15