<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Hi Fred,<div class=""><br class=""></div><div class="">I should have used a more appropriate erlang term “bitstring" as opposed to “bit field” in my email — thank you for correcting this.</div><div class=""><br class=""></div><div class="">I’ve been using bitstrings in the past, well, not really as a bunch of “loose” bits, but always as a part of some other binary pattern aligned to 8-bit boundary.</div><div class=""><br class=""></div><div class="">If you cannot write 17 loose bits to a file, or, better yet, if you cannot send 13 loose bits over a socket, one has to wonder how useful are non-aligned bitstrings (and by this I mean “loose” bits). </div><div class=""><br class=""></div><div class="">And it gets worse. Consider this:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(255, 255, 255); background-color: rgb(43, 102, 201);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">(tsdb_1_1@macbookv-3)433> term_to_binary( <<0:8>> ).</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(255, 255, 255); background-color: rgb(43, 102, 201);" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><br class=""></span></div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(255, 255, 255); background-color: rgb(43, 102, 201);" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><<131,109,0,0,0,1,0>></span></div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(255, 255, 255); background-color: rgb(43, 102, 201);" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><br class=""></span></div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(255, 255, 255); background-color: rgb(43, 102, 201);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">(tsdb_1_1@macbookv-3)434> term_to_binary( <<0:1>> ).</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(255, 255, 255); background-color: rgb(43, 102, 201);" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><br class=""></span></div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(255, 255, 255); background-color: rgb(43, 102, 201);" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><<131,77,0,0,0,1,1,0>></span></div></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">It follows that it takes more memory to store 1 loose bit than 8 aligned bits. </div><div class=""><br class=""></div><div class="">And just to prove that if it walks like a duck, and quacks like a duck, it's probably… an elephant.</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><div class=""><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(255, 255, 255); background-color: rgb(43, 102, 201);" class=""><span style="font-variant-ligatures: no-common-ligatures;" class="">(tsdb_1_1@macbookv-3)449> is_binary( <<0:8>> ).</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(255, 255, 255); background-color: rgb(43, 102, 201);" class=""><span style="font-variant-ligatures: no-common-ligatures;" class=""><br class=""></span></div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(255, 255, 255); background-color: rgb(43, 102, 201);" class=""><span style="font-variant-ligatures: no-common-ligatures;" class="">true</span></div></div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(255, 255, 255); background-color: rgb(43, 102, 201);" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(255, 255, 255); background-color: rgb(43, 102, 201);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">(tsdb_1_1@macbookv-3)448> is_binary( <<0:1>> ).</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(255, 255, 255); background-color: rgb(43, 102, 201);" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><br class=""></span></div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(255, 255, 255); background-color: rgb(43, 102, 201);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">false</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(255, 255, 255); background-color: rgb(43, 102, 201);" class=""><br class=""></div></div><div class=""><br class=""></div><div class="">But, if you put two elephants next to each other, you get — a duck!</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(255, 255, 255); background-color: rgb(43, 102, 201);" class=""><span style="font-variant-ligatures: no-common-ligatures;" class="">is_binary( <<0:5, 0:3>> ). </span></div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(255, 255, 255); background-color: rgb(43, 102, 201);" class=""><span style="font-variant-ligatures: no-common-ligatures;" class=""><br class=""></span></div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(255, 255, 255); background-color: rgb(43, 102, 201);" class=""><span style="font-variant-ligatures: no-common-ligatures;" class="">true</span></div></div><div class=""><span style="font-variant-ligatures: no-common-ligatures;" class=""><br class=""></span></div><div class=""><br class=""></div><div class="">Given all this, why would anyone find bitstrings useful?</div><div class=""><br class=""></div><div class="">But, the above notwithstanding, I understood your point that run-time does not mandate any kind of alignment, hence compiler has nothing to report.</div><div class="">Makes sense — Thank you.</div><div class=""><br class=""></div><div class="">V/</div><div class=""><div><br class=""><blockquote type="cite" class=""><div class="">On 20 Aug 2019, at 15:13, Fred Hebert <<a href="mailto:mononcqc@ferd.ca" class="">mononcqc@ferd.ca</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><div dir="ltr" class=""></div><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Aug 20, 2019 at 8:26 AM Valentin Micic <<a href="mailto:v@micic.co.za" class="">v@micic.co.za</a>> wrote:<br class=""></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="overflow-wrap: break-word;" class="">Hi all,<div class=""><br class=""></div><div class="">Recently I’ve made a silly mistake. I wrote:</div><div class=""><br class=""></div><div class=""><div style="margin:0px;font-stretch:normal;line-height:normal" class=""><font face="Courier New" class="">case Payload of</font></div><div style="margin:0px;font-stretch:normal;line-height:normal" class=""><font face="Courier New" class=""> <<_:4/binary-unit:8, _:<b class=""><font color="#e32400" class="">255</font></b>, _:7/binary-unit:8, 0:16>> -> Payload;</font></div><div style="margin:0px;font-stretch:normal;line-height:normal" class=""><font face="Courier New" class=""> _ -> throw( drop )</font></div><div style="margin:0px;font-stretch:normal;line-height:normal" class=""><font face="Courier New" class="">end</font></div></div><div style="margin:0px;font-stretch:normal;line-height:normal" class=""><div class=""><font face="Courier New" class=""><br class=""></font></div><div class=""><font face="Courier New" class=""><br class=""></font></div><div class="">Considering that overall pattern (which erroneously references 255 bits long field, instead of an octet with a value of 255 ) is not aligned to 8-bit boundary, is it unreasonable to expect the compiler to report this as a potential problem, or at least generate a warning (support for bit-fields notwithstanding).</div><div class=""><br class=""></div><div class="">What am I missing here?</div><br class=""></div></div></blockquote><div class=""> </div><div class="">There are informally two kinds of binaries: 8-bit aligned binaries (regular ones) are those people call 'binaries', and then you have bitstrings. Bitstrings don't need any alignment whatsoever. Your pattern can be made to work by using any fitting bitstring. For example:</div><div class=""><br class=""></div><div class="">1> <<_:4/binary-unit:8, _:255, _:7/binary-unit:8, 0:16>> = <<0:(32+255+7*8+16)>>.<br class=""><<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,<br class=""> 0,...>></div><div class=""><br class=""></div><div class="">But more generally, the binary/bitstring distinction will make sense when pattern matching:</div><div class=""><br class=""></div><div class="">3> <<_:4/binary-unit:8, _/binary>> = <<0:(32+255+7*8+16)>>. <br class="">** exception error: no match of right hand side value <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,<br class=""> 0,...>></div><div class="">4> <<_:4/binary-unit:8, _/bitstring>> = <<0:(32+255+7*8+16)>>.<br class=""><<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,<br class=""> 0,...>></div><div class="">5> <<_:4/binary-unit:8, _/bits>> = <<0:(32+255+7*8+16)>>. <br class=""><<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,<br class=""> 0,...>><br class=""><br class=""></div><div class=""></div><div class="">Note that bits is shorthand for bitstring. Do note as well that you can always cheat the pattern match by specifying units:</div><div class=""><br class=""></div><div class="">6> <<_:4/binary-unit:8, _/binary-unit:1>> = <<0:(32+255+7*8+16)>>.<br class=""><<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,<br class=""> 0,...>><br class=""></div><div class=""><br class=""></div><div class="">Nothing in Erlang actually mandates exact alignment, it's just that with the default widths of various types impacts pattern matching. Dialyzer, however, does enforce some semantic values. Here's a sample module:</div><div class=""><br class=""></div><div class="">-module(chk).<br class="">-export([f/0, f/1, g/0, g/1]).<br class=""><br class="">f() -> f(<<0:17>>).<br class="">g() -> g(<<0:17>>).<br class=""><br class="">-spec f(binary()) -> ok.<br class="">f(Bin) -><br class=""> <<_/binary>> = Bin,<br class=""> ok.<br class=""><br class="">-spec g(binary()) -> ok.<br class="">g(Bin) -><br class=""> <<_/bits>> = Bin,<br class=""> ok.</div><div class=""><br class=""></div><div class="">If you run dialyzer on it, you'll find out the following:</div><div class=""><br class=""></div><div class="">chk.erl:4: Function f/0 has no local return<br class="">chk.erl:4: The call chk:f(<<_:17>>) will never return since the success typing is (binary()) -> 'ok' and the contract is (binary()) -> 'ok'<br class="">chk.erl:5: Function g/0 has no local return<br class="">chk.erl:5: The call chk:g(<<_:17>>) breaks the contract (binary()) -> 'ok'</div><div class=""><br class=""></div><div class="">the type binary(), to Dialyzer, implies the 8-bit alignment you're looking after. The bitstring() type will not care for alignment. This is because Dialyzer supports defining binary types as:</div><div class=""></div><div class=""><pre class=""> <<>> %% empty binary
<<_:M>> <span class="gmail-hljs-comment">%% fixed-size binary, where M is a positive integer</span>
<<_:_*N>> <span class="gmail-hljs-comment">%% variable-size binary with an alignment on N</span>
<<_:M, _:_*N>> %% binary of at least M size, with a variable-sized tail aligned on N</pre></div><div class="">Essentially, binary() is defined as <<_:_*8>> and bitstring() is defined as <<_:_*1>>. This lets you encode whatever check semantics you'd like within type specifications, and Dialyzer can try to figure it out for you. But nothing, by default, would necessarily warrant compiler warnings since alignment on 8 bits is not mandated by the runtime.<br class=""></div><div class=""><br class=""></div></div></div>
</div></blockquote></div><br class=""></div></body></html>