Thoughts on a ‘Powerful’ API

One of the words that keeps coming up when I have conversations about new products is that the API must be “powerful”. While intuitively this sounds good – after all, who wants to develop an API that is a bit wimpy – how can you measure and judge the power of one API over another? I’m pretty sure that you can’t assign a wattage to a function call.

Say we have a scene graph that lets a caller insert objects into a hierarchy. An object can reference other objects using a standard instancing metaphor. Lets say this manifests itself like this:

// Add child node to parent
int SceneGraph::AddObject (Node *parent, const Node *child);

Such an API makes it easy to put in a circular dependency, which would cause subsequent scene graph traversals to loop ad-infinitum. So it would be trivial here to make the method check that parent and child are not the same. But what if parent is indirectly reference by child? E.g.

start with A -> B -> C
call SceneGraph::AddObject (C, A)

So, if AddObject were to be “powerful”, would it check for this and return an error? It would certainly make the method robust, as you could not poke invalid data at it. But does robust==powerful?

I would say no. Because even though it stops a user doing something daft that could be hard to diagnose, it does not scale. If the code has to traverse the graph every time a new node is added to the scene graph, then the act of building a model with hundreds or thousands of objects will execute in O(n^2) time complexity. By making this API robust, you actually reduce its power by imposing an overhead upon the user.

Most scene building code will be well behaved – there will be enough knowledge at the application end to “know” that the data is good. And for those times when the application does not know, we can supply a method like:

// Check if one object is a child of another
bool SceneGraph::IsChild (const Node *n0, const Node *n1)

Application code can then query only when needed. The “power” here is in enabling the user to make the decision on balancing cost against convenience.

Leave a Reply