title: Comma separated binary arguments? - elixir
body: <p>I've been learning elixir this month, and was in a situation where I wanted to convert a binary object into a list of bits, for pattern matching.</p>
  
  <p>My research led me <a href="https://minhajuddin.com/2016/11/01/how-to-extract-bits-from-a-binary-in-elixir/" rel="nofollow noreferrer">here</a>, to an article showing a method for doing so. However, I don't fully understand one of the arguments passed to the <code>extract</code> function.</p>
  
  <p>I could just copy and paste the code, but I'd like to understand what's going on under the hood here.</p>
  
  <p>The argument is this: <code>&lt;&lt;b :: size(1), bits :: bitstring&gt;&gt;</code>.</p>
  
  <p><strong>What I understand</strong></p>
  
  <p>I understand that <code>&lt;&lt; x &gt;&gt;</code> denotes a binary object <code>x</code>. Logically to me, it looks as though this is similar to performing: <code>[head | tail] = list</code> on a List, to get the first element, and then the remaining ones as a new list called tail. </p>
  
  <p><strong>What I don't understand</strong></p>
  
  <p>However, I'm not familiar with the syntax, and I have never seen <code>::</code> in elixir, nor have I ever seen a binary object separated by a comma: <code>,</code>. I also, haven't seen <code>size(x)</code> used in Elixir, and have never encountered a <code>bitstring</code>.</p>
  
  <p><strong>The Bottom Line</strong></p>
  
  <hr/>
  
  <p>If someone, could explain exactly how the syntax for this argument breaks down, or point me towards a resource I would highly appreciate it.</p>
  
  <p>For your convenience, the code from that article:</p>
  
  <pre><code>defmodule Bits do
    # this is the public api which allows you to pass any binary representation
    def extract(str) when is_binary(str) do
      extract(str, [])
    end
  
    # this function does the heavy lifting by matching the input binary to
    # a single bit and sends the rest of the bits recursively back to itself
    defp extract(&lt;&lt;b :: size(1), bits :: bitstring&gt;&gt;, acc) when is_bitstring(bits) do
      extract(bits, [b | acc])
    end
  
    # this is the terminal condition when we don't have anything more to extract
    defp extract(&lt;&lt;&gt;&gt;, acc), do: acc |&gt; Enum.reverse
  end
  
  IO.inspect Bits.extract("!!") # =&gt; [0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1]
  IO.inspect Bits.extract(&lt;&lt; 99 &gt;&gt;) #=&gt; [0, 1, 1, 0, 0, 0, 1, 1]
  </code></pre>