Saturday, April 14, 2012

Breaking problems down and defaults

In a classic essay Dave Rolsky wrote: Want Good Tools? Break Your Problems Down. I wish more people have read this and applied the advice - CPAN libraries would be more useful then. But stating the goal is probably not enough - we need also to talk about how it can be reached and about problems encountered on the way there. For example let's take the module that was the result of the process described in the essay linked above:

The problem is that the criticized approach, a unified library that just converts Markdown to HTML, would result in a simpler API - for example something like this:

Maybe the difference does not look very significant - but after a while it can get annoying. For the 99% of cases you don't need to extra flexibility that comes with the replaceable parser - so why should you pay for it?  If I had to use Markdent frequently I would write a wrapper around it with an API like above.

By the way, Text::Markdown already has this wrapper and it does present a double, functional/object oriented API - where the presented above simple, functional one does the most common thing, while the object oriented one gives you more control over the choices made.  Only that it still couples parsing and generation.

Another way of simplifying the API is providing defaults to function arguments. For example to the object constructor.  Dependency Injection is all about breaking the problem down and making flexible tools -  but it might become unbearable if we not soften it up a bit with defaults.

Programming is always about doing trade-offs - here we add some internal complexity (by adding the wrappers or providing the defaults) and in exchange get a simplified API that covers the most common cases while still maintaining the full power under the hood.  I think this is a good trade off in most cases, and especially in the case of libraries published to CPAN that need to be as universal as possible.

2 comments:

cezio said...

It's because you should stop writing classes ;)

zby said...

OK - I kind of agree that people tend to over-engineer stuff and I have many times written about that. But there are cases when you do need something complicated - and in particular I believe that this little additional complexity in providing a simplified interface is worth it. The alternative is that we'll have the complex, but flexible library on CPAN and many simple ones that do one aspect of that complex library - sometimes it does make sense - but often this fragmentation is a nuisance. It is really nice feeling when you can use the same library in many contexts. And if your argument really was that the whole Markdent design was overkill - then I don't agree - Rolsky had a need for the flexibility that he got from splitting the problem into the two phases.