Look at how little I need

I recently found the time to rewrite an old library of mine from the ground up: ez-form. This is one of the first libraries I wrote for Clojure, based on code I found myself writing yet again, in yet another project. Forms for the web is one of those things that you find yourself doing a lot when you do web development. And there is a whole lot that goes in to them: specification, validation, rendering, layout, error handling (where do we show them, do we show all?, etc), i18n, reuse and probably more.
Overkill #1
Being new to Clojure I was (and still is to be honest) infatuated with functional zippers. They are just… supercool, awesome and the coolest ever. Something along those lines. When sliced bread was invented, functional zippers were there for the initial draft, slicing and dicing all the atoms in the bread for the perfect cut so that future generations of bread slice makers had something to aim for, but never reach.
Knowing that I had to do a lot of data manipulation I crafted up a whole eloborate scheme for extending syntax that you could hook into. And it worked. Quite well actually.
But a postwalk can get you to about 70-80% of what you can do with functional zippers, so unless you need to know about the surrounding data in the data structure you’re walking through, a postwalk is probably fine.
Overkill #2
Multimethods is another of those things that I dove straight for. Very powerful stuff. A map lookup can also work just as well, and with a small setup step you can have your extendability as much as you want with a simple merge.
Mistake #1
Validation is super important for web forms. Especially for backend. Don’t trust data from the web. Always validate.
The mistake I made here was that I went with a specific validation library. It was a really good library, but I now tied myself down to a specific validation, instead of making it optional.
Mistake #2
I made the same mistake with i18n as with validation. I picked a specific implementation. In addition, I added a number of translations out of the box. While helpful to some extent, I still would consider them harmful because they set a specific direction, and thus sets an implicit boundary for the library in terms of what it should do, as opposed to what it can do.
Mistake #3
Syntax. If you can avoid it, do it! Syntax is one of those insidious things that are really, really, really hard to get right. Hiccup’s genius is that it’s HTML in the guise of EDN. Pure data structures, with a one to one mapping to HTML.
Mistake #4
I did not use maps and vectors enough. Maps are so incredibly versatile because of their associative nature. Combine it with vectors for lookups and you remove the need for a lot of elaborative walk-throughs of complex datastructures. It is better to spend time designing a datastructure with maps and good key naming, than writing yet another function that navigates a complex datastructure for a small update.
Result?
With the old version of ez-form, I had 8268 words in my src directory. With the rewritten version, which mostly has feature parity, I stand at 1003 words. That is a 88% reduction in code size. The code is smaller, easier to reason about, easier to test and has so far been very easy to extend whenever I found myself wishing for a new feature.
