djdrzzy
djdrzzy

Reputation: 613

How to concatenate a bit to the end of a bit string?

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

Answers (1)

michalmuskala
michalmuskala

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

Related Questions