Skip to content

Instantly share code, notes, and snippets.

@jimblandy
Last active April 12, 2018 05:27
Show Gist options
  • Select an option

  • Save jimblandy/b1991e23c3e03a6aa00b27c9ac46e5b1 to your computer and use it in GitHub Desktop.

Select an option

Save jimblandy/b1991e23c3e03a6aa00b27c9ac46e5b1 to your computer and use it in GitHub Desktop.
API styles for enabling and disabling things

Minutiae: API styles for enabling and disabling things

So there are two API styles for enabling and disabling something: you can have a boolean that you turn on and off (call this "flag style"); and you can have calls that increment and decrement a counter, and the thing is enabled depending on whether the count is zero (call this "semaphore style").

Semaphore style is essential in some cases. If there are many different influences who all have to come to consensus in order to enter a certain state, the counter is sort of a reference count: the number of people holding us in the lack-of-consensus state. In situations like this, flag style is a pain in the neck: you'd have to implement the counter someplace else just to decide when to flip the bit.

But if you need the thing to be enabled/disabled depending on a predicate on some state, and you're calling the API whenever the state changes, then the flag API is much better: evaluate the predicate, and set the flag. If a bug causes you to miss a transition, the next transition you catch will correct it. Here, the semaphore style is asking for trouble: you have to increment and decrement the counter as the predicate's value changes. If a bug causes you to miss transitions, your counter might spend the rest of its life bouncing between one and two, instead of between zero and one.

It's interesting to note that, in both of the mismatch cases, you end up implementing the API you wish you had: to drive a flag in a consensus situation, you need a counter; and to drive a counter in a state predicate situation, you need to track the last value of the predicate --- a flag!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment