Down with negative logic in programming

c: | f: /

I’m on the warpath against any programmers that employ negative logic in their code. Desist from never supplying positive assertions. Right now.

I used to work with a manager who revelled in writing impenetrable code. He’d use variable flags like this:

do_not_unset_unclosed_prior_issues = false

If you think that’s contrived, think again. I wish I still had some of his code lying around to prove the depth of his madness.

On some alternative plane of existence, it must have made sense to him, but to everyone else, reading his code was like a conversation between the BFG and the Mad Hatter. When the code broke, we drew straws to work on it. The amount of time spent debugging his crappy logic probably contributed to the collapse of the company.

I’d like to report that in the modern programming world, with well-defined, restful Application Programming Interfaces aplenty, things have improved since I last touched on this issue. Sadly this is not the case. In fact, I suspect my ol’ manager has gone to work for Groupon, because today I’ve been faced with trying to decipher some similarly twisted logic.

Here’s what happens when talking to Groupon’s servers:

  • -> Hey, Groupon, show me any orders we haven’t yet processed.
  • <- Sure thing, here they are.
  • -> Thanks. Can I see all the orders for the last week?
  • <- Nope. You can only get them for any given 24-hour window.
  • -> What? So I need to make multiple requests, one per day, to find an order?
  • <- Yes.
  • -> Sheesh. Okay, whatever, here’s a list of all the orders we’ve accepted, but not yet shipped. Please update your records.
  • <- Updated.
  • … some time later after shipping a few orders …
  • -> Hello again, Groupon. Here’s a list of couriers and tracking numbers for a bunch of orders. Please update your records.
  • <- Updated. Here’s a list of stuff indicating what we did. Or didn’t do. Or might have done. You figure it out.

That last step is just head-scratching. Along with their customary success message, they send back a list of things labelled non_open_ids. What the hell does that mean? The documentation (which I’ve discovered is inconsistent with the API responses elsewhere) isn’t sure either. In pseudocode, here’s what it offers:

if (success == true ) {
    // Successfully saved tracking info of items
    // other than those in "non_open_ids" array
} else {
    // Something went wrong.

Wait, so I send you a list of IDs, you do something with them and then send me back the ones that are non-open? i.e. closed? Or pending? Or tracked?

Does non-open mean they’re logged as tracked so I can update our system to reflect this? Or do you mean you’ve sent back ones that failed to be tracked so I can take the opposite action? And are they just a subset of the ones that I sent you, or all orders that might still be open or pending (or closed or tracked?) since the last time I asked?

Aaaaarghhh! Stop stop stop stoooooooop!

If they mean they’ve sent me orders that have successfully been tracked, they should damn well say so by labelling the returned list tracked_items. Or send me ones that failed using failed_items. Or, preferably, allow me to choose so I can select which makes sense to my application. Without a sandbox to code in, I’m forced to operate on live orders just to figure out their documentation and ill-defined API.

There are situations when negative logic saves time or bytes transferred, or simply excluding things makes sense. That’s fine. But for people who must do it, please don’t treat it as a time to be terse or ambiguous.

In this case with a published API, treat end customers (us poor developers) with some respect. Not only does backwards logic make an API tougher to decipher, it makes my code harder to understand because I need to employ similar bad logic like this when looping over the IDs I originally sent:

if ( id not in non_open_ids ) {
   // do something

Anyone looking at that would think I was some kind of codetard, when I’m merely having to pass on the retardation of a badly-implemented upstream API. Stop making me look worse than I know I already am. It’s annoying.

I want your brainjar


(required, never made visible)

(optional, linked with rel="nofollow")