Code as data

Some tasks seem to be much simpler if the code of our doohickey was all data instead. Like if I could write:

(endpoint "create_contact"
  modules [require-user name-validator email-validator]
  implementation endpoints/create_contact

And then there would be code that magically output documentation with validations, param names and such. Or produced a list of endpoints by authentication method. This second task seems to be impossible for a more traditional arrangement where the authentication might be squirreled away in imperative code:

def create_contact
  raise Unauthenticated unless current_user.present?

This seems like a more difficult way to program though, or at least a more unfamiliar one. Instead of telling the computer what you want it to do step by step you have to build some kind of structure out of blocks. And if the blocks you want are not available you need to create them imagining both the shape of the final product and the kind of blocks that it might be built from at the same time.

I guess a subset of what I’m describing is already implemented in things like clojure’s schema which allows one to specify how a piece of data should look using another data structure. It’s easy then to imagine traversing that data description to generate docs or check two such descriptions for compatibility. The Lisp/Clojure people seem to go in this direction in general, with all the code being s-expressions, so I should search there for more solutions like this…

Now it gets real spicy once you can string these together somehow. You’re free to have optional type annotations, complex conditions on input data and so on, all automatically documented and compile-time-checked - if your language has a proper compilation step that is…

The big question is: can you support such a paradigm in a general-enough way for your application to be built with it all the way through and simultaneously it not being a bother to maintain?


Now read this

Code as data is just annotated functions?

What I wrote previously might just boil down to having a bunch of annotations on your functions. In a functional language a lot of your functions will look something like this: (defn new-functionality [x] (-> x first-step second-step... Continue →