I don't think the over-complicated code was motivated by a desire to show off — it was written by someone who doesn't understand how bit shifts work, which is still potentially troubling but very different
I don't think the over-complicated code was motivated by a desire to show off — it was written by someone who doesn't understand how bit shifts work, which is still potentially troubling but very different
build_info_control(SendSeq, RecvSeq, Poll) ->
<<0:1, SendSeq/bitstring, Poll/bitstring, RecvSeq/bitstring>>.
Where the `SendSeq` and `RecvSeq` are 3-bit sequence numbers... say one of them is `<<2:3>>` (0b010) and Poll is a single bit (you can see the format here: https://imgur.com/a/9bVBM0W). This field would then be stuck into a binary representing the entire frame.This could probably be made a littler simpler, though, as I'm still rather new to Erlang.
Note you also do get bit shift operators for cases when they’re an appropriate solution (`bsl` and `bsr`)
[0] ++ sendSeq ++ recvSeq ++ [poll]
say sendSeq was one bit but we still wanted it to take 3 bits:
[0] ++ pad 3 sendSeq ++ poll ++ recvSeq
given some "pad" function defined in a library
The only reason it's "hard" in C is because the operations are induced from what the machine can do efficiently and without "a sufficiently smart compiler".
The entire language is built around pattern matching to the point where it simply wouldn't exist otherwise, and I assume binary protocol handling was a core requirement when the language was designed since it was created for telecom switches.
> say sendSeq was one bit but we still wanted it to take 3 bits:
> [0] ++ pad 3 sendSeq ++ poll ++ recvSeq
In Erlang you could do this to get something padded (or truncated) to the correct size:
<< 2:3 >> ;; corresponds to the 3 bits <<010>>
So you can do something like this to ensure the precise bit size of each field: << 0:1, SendSeq:3, Poll:3, RecvSeq:3>> struct build_info_control
{
unsigned char : 1;
unsigned char SendSeq : 3;
unsigned char Poll : 1;
unsigned char RecvSeq : 3;
};
struct build_info_control control;
control.SendSeq = sendSeq;
control.Poll = true;
control.RecvSeq = recvSeq;
The downside of bit fields is that they are implementation specific---you'll have to check the compiler documentation to see if the bits are specified "most significant bit to least significant bit" or "least significant bit to most significant bit" (if that is indeed, important to the problem).It's still rare that I use anything outside of those two operators in work code, and when I do it tends to get commented as a premature optimization during code reviews.
[0] That's not a humble-brag, context provided b/c it's a time, due to 7 hours a day spent taking tests/memorizing and spent also learning algebra through calculus, I was at my absolute peek for learning this sort of thing.
Ok, the article just made me remember they are not signed. But it's certain that the next time I need them, I won't remember it again.
What I don't get: Are those operators present in C++ too -- wouldn't they clash with the "streaming" thingamajigs, isn't that what "<<" means nowadays?
Imo, Rust makes a very good second language for someone who first learned Javascript or Ruby — and someone who used those languages primarily for web dev may never have needed to learn about bit shifts
Also, JavaScript's handling of numbers is so weird that it's one of those things that comes up just by virtue of its weirdness. For that reason I'd expect a JS programmer at least have come across but operations.
(edit - I take the original post as a joke too, and that the humour is derived from the juxtaposition)
I know I've seen examples at least as odd as this in the past in languages I'm familiar with -- where, say, the developer was really good with LINQ or something and made five calls instead of just accessing an array by index -- that were meant "intentionally", but were bizarre to someone not sitting in their brain at that moment.
I hadn't, however, thought about either of the points you mentioned.
You're quite the detective. :)
[1] https://insights.stackoverflow.com/survey/2021#section-worke...
> which is still potentially troubling but very different
I'm having a really difficult time remembering the last time I had to even use a bit operator at work[0]. For a lot of developers, the need to keep that operator in their head is going to rank way lower than, say, how to properly configure CORS in `ngninx`.You always have to judge a developer's gaps/knowledge given their context. We're dealing in technologies that have sub-sub-sub-sub-disciplines that a person may have expertise in which result in them missing huge portions of the languages' features. I've learned that this hyper-specialized developer can be as effective as anyone -- the ability to rapidly acquire, integrate and use new knowledge with whatever tooling is required is far more important to me than whether or not a developer has large gaps in the tools we use[1].
I'm nit-picking a little, but it's a habit of mine to turn around discussions at my office that go something like "How can any web developer not know (x)?"[2] Ask a developer on a conference call if they're familiar with some obscure technology, and you'll hear ranges of qualified "Yes" responses and a whole bunch of clacking while each Google's various bits of information. How much easier is it if everyone just says "No, I don't" and asks the person who brought it up to explain. It's really hard to get developers past "Imposter Syndrom" and open to admitting their gaps so they can be accounted for in planning. Even where I'm at, now, I see it from time to time and this is at a shop with excellent culture and a focus on projects/products that are new inventions/creations.
And, unfortunately, it causes me to judge that individual unfairly, myself -- I've been writing code since I was 13 years old. I have written a lot of code. My goal is that the best code I wrote 6 months ago should at least slightly embarrass me, today.[3] And I guarantee, over the years, I've written code that is worthy of posting on a site like this. I can't imagine what kind of insanity my first "useful" rust program will end up looking like, but given the memory-safety rules imposed, I'm expecting to have to integrate a new mental model that will result in some comical implementations.
For me -- this work has a way of either humbling you or down-right beating you up with how often you're reminded about what you don't know. I think it gets worse as you learn more almost feeding the whole "ageism" in the industry -- middle-aged developers are far more honest about what they don't know and some are just beaten to death by the treadmill. I have watched, over the years, as developer after developer has left for "management" or leaving a shop like the one I'm at for a global multi-national to work on the most boring internal enterprise-y waste -- consistent/easy, but pointless. For the few that I was close enough to that I got more than just "PR answers", the crux of it was burn out from never feeling like you're actually "knowing" less about what you're working on[4]
[0] Outside of `enum`s in my language of choice, which perform best when flags are checked/appended using operators. But even that is an unnecessary optimization nearly always, there's a ".HasFlag()" method that I simply forget about because it was taught to me in my teens, it's implemented consistently in a lot of languages and it's muscle memory at times.
[1] I've recommended the hire of individuals who, outside of "they have been writing C# code for a decade", they hadn't touched the part of the framework the job was for -- i.e. they were Desktop devs applying to Web, Web applying to mobile, and many candidates lack even basic Docker/shell knowledge, etc. All ended up picking up what they were missing on-the-job just like the rest of us.
[2] Because, unlike every other field, when "(x)" became "old", it had been on its 5th version, 4th major API change and was born about three and a half minutes ago.
[3] Sometimes I'm unfair -- the reason I'm embarrassed is because I didn't use a very obvious feature, but at the time I'm looking at the code I'm also forgetting that said feature didn't exist back then. But often it's just because I've continued to read/study/do.
[4] These were not developers who were suffering from mental decline with age and were among the better I've worked with. I really think it's a case of "learning about something new" simultaneously adding to "discovering that your skillset does not include this massive body of knowledge around your small usage of 'something new'". You learn way more about how much you don't know than you add to your total knowledge making you feel 'net dumber'.
I wouldn't criticize a developer for being unfamiliar with bit shifts because I've never had to use it for work either. The part I'm incredulous about is that there wasn't a step in the middle where the developer looked up bit manipulations.