Review: C4Labs’ Pi Borg Plus Enclosure

A few months ago, I picked up one of C4Labs’ Pi Borg Plus enclosures. And it’s since just been sitting in a box unopened, waiting for another RaspPi project to come along. Over the holiday weekend, I had the opportunity to dig it out and put it to use.

The Pi Borg Plus is a traditional “pack o’ cigarettes” form-factor RaspPi case. But as you can see from the photo below, it really differentiates itself in style.

The enclosure is made out of Philippine mahogany plywood, which is stained in two different shades and sandwiched together to form three layers that really create an almost organic steampunk look and feel.

The whole thing goes together pretty easily and is just as easy to disassemble should the need arise.

Pros:

  • Very nice to look at
  • Provides good air circulation
  • Easy to assemble (4 pieces)
  • Provides access to commonly used ports (including MicroSD card slot)
  • Rubber feet to protect furniture
  • Works with Raspberry Pi B+, 2B, and 3

Cons:

  • Price ($19.50 at the time of this writing
  • GPIO and camera connector inaccessible

It’s a great enclosure for the Pi on-the-go. If you can get past the price, I definitely recommend giving this a try for your next project.

(Note: If you go looking for the assembly instructions in the “Build” section of C4Labs’ site, for whatever reason the enclosure is called the Nucleus there.)

Hyrum’s Law

A few mornings ago, I was listening to CppCast Episode #70 on my commute into work. This particular episode featured an interview with Titus Winters. If you’re not familiar with Titus, he currently leads the C++ libraries team at Google and generally has lots to say regarding large codebases and sustainability. You can check out his CppCon talks here, here, and here.

During the interview, Titus shared a small anecdote regarding an attempt by his team to make broad code changes. They discovered weird behavioral dependencies that were never intended to be part of the API’s contract, never documented, and certainly never intended for client applications to rely upon. He followed the anecdote with the following “law”, attributed to his colleague Hyrum. (presumably Hyrum Wright)

“With a sufficient number of users of an interface, it doesn’t matter what you promised in the interface contracts, all observable behaviors of your class or function or whatnot will be depended upon by somebody.”

Titus calls this Hyrum’s Law and it’s a trueism if there ever was one.

Most developers learn to use an API or library by experimentation, regardless of whether there’s documentation to lean on. It turns out that the human brain has an uncanny need to actually apply a solution to a given problem before fully appreciating and understanding the problem. Attempting to use someone else’s software component in your own code is where the real learning starts. And when a moment of success is achieved, it’s often where the learning stops.

As I see it, there are really two major contributors to Hyrum’s Law. The first is that once some minimal amount of success is achieved, developers working with an API or library don’t always verify that a given component’s contract matches their expectations or usage. We’ve got other things to do, after all. And besides, what we’re doing makes total sense and is not at all weird, right? Umm….maybe? Maybe not? The second is that interface authors aren’t always comprehensive when it comes to contracts. Sometimes there are side-effects and pre/post conditions that escape our attention or we may make naïve assumptions about our users. For instance, threading restrictions, “undefined” behavior guarantees, object lifetime, optional vs. required client data, thrown exception types, etc. are all things that sometimes get glossed over when it comes time to document the contract. As such, users of our components can only make assumptions about things we aren’t explicit about.

As users of others’ code, we must be careful not to assume our usage of an interface is as the author intended. When in doubt (and when possible), verify. And if there’s disparity between the contract and actual behavior, please notify the author!

As authors of interfaces, we must be careful to document and make explicit the intended contract. Of course, that’s often easier said than done. It’s hard to be comprehensive, but we should give it our best shot. And we should be prepared to refine the contract at opportune times as we learn where the holes are.