Jan. 4, 2024, 2 p.m.

Strategically incur opportunity costs to manage carrying costs

Sustainable Development and More

SocialMedia.jpg

Happy New Year!

Every engineering decision comes down to "it's a trade-off". But what are we trading off?

The best way I've found to quantify a trade-off is to talk about the opportunity cost and the carrying cost.

Opportunity Costs vs. Carrying Costs

The opportunity cost is something you pay up front—at the cost of not pursuing another opportunity. A carrying cost is something you pay constantly to live with the solution. Ideally, a strategic opportunity cost will reduce carrying cost and pay for itself, like so:

Line graph showing two series. The first is in red and increases exponentially. This is carrying cost going up and up. The second is in green and shows a large hump one third into the series, then a sharp drop followed by a logarithmic increase over time. The hump has an arrow pointed to it that says 'Opportunity Cost'
Graph showing reduced carrying cost after an opportunity cost

A poorly-chosen opportunity cost, however, will make things worse. I once paid an opportunity cost in designing a slick barcode-parsing framework for an app at Stitch Fix. It could dynamically figure out from any barcode what row in the database that barcode referred to. It was way too complicated and every change required navigating its convoluted design.

Not a good trade-off, since the carrying cost was high.

On the other hand, the first time Stitch Fix created an internal API/service, we decided to spend some time authoring and vetting a set of HTTP conventions for the entire team. It turned a one day task for one person into a one week multi-developer project.

But, it virtually eliminated all future discussion about versioning, JSON, headers, and anything else you can imagine about building internal services. A good trade-off.

Try it yourself the next time you face a technical or product decision: what's the opportunity cost and what will it do to the carrying cost for you or your team?

JavaScript is Kinda Nice

JavaScript has a well-earned reputation for being, well, kinda janky. But over the years, it's been slowly updated and changed and now, well, it's kinda nice, sometimes!

Lots of OO languages allow an object to expose attributes. Java tends to use getWidget and setWidget, while Ruby allows you to make a method named widget and another named widget=. JavaScript—way back when—followed the Java Model, but really most JavaScript programmers set values on objects directly. some_object.widget = 42.

Modern JavaScript, however, lets you maintain the conciseness of using attributes, but inject code:

class MyClass {
  get widget() {
    return new Widget(this.widget_id)
  }
  set widget(newWidget) {
    this.widget_id = newWidget.id
  }
}

const c = new MyClass()
c.widget = { id: 1234 }
console.log(c.widget_id)        // => 1234

One warning, however, is that both obj.widget and this.widget are the same thing, so the following code would cause a problem:

class MyClass
  get widget() {
    return this.widget // returns the getter function
  }
  set widget(newWidget) {
    this.widget = newWidget // overwrites the getter function
  }
}

d Even still, this is still a handy feature to design classes that behave the way you want. If you aren't a regular JavaScript programmer, now you know!


Unless otherwise noted, my emails were written entirely by me without any assistance from a generative AI.

You just read issue #4 of Sustainable Development and More. You can also browse the full archives of this newsletter.

Share on LinkedIn Share on Hacker News Share on Reddit Share via email
Website
Powered by Buttondown, the easiest way to start and grow your newsletter.