Callbacks in APIs · 1256 days ago

I’ve come to the conclusion that the omnipresent callback often makes code harder to read. Their power comes with a cost.
The runtime flow of the code isn’t as easy to hold in one’s head, and debugging can be difficult (you can easily find yourself stepping through reams of unfamiliar code).

This point is particularly relevant in python when code with callbacks can sometimes be rewritten with iterators.

Consider:


  def twiddle(node):
     node.twiddle()
  context.frobnicate(twiddle)

versus:


  for node in context.frobnicatableNodes():
     node.twiddle()

What happened here? frobnicateNodes is still magic, but it can often be safely ignored by a programmer who doesn’t understand how it works. It can be doing something terrible behind the scenes, but I usually don’t have to worry about it.

As a harried programmer, I’m gonna like things that I can at least appear to control rather than those that control me. Thus, I like calling other code and telling it what to do, rather than trying to beg other code to call me and scratching my head when it didn’t.
I can thus hope to ignore the internals of what context is doing, allowing it to have a smaller surface area.

Therefore, in python, prefer iterators to callbacks when things can be reasonably persuaded into the iterator form.

Comment

* * *