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

For those not in the know -> is the threading macro, the usage of which I’m probably misrepresenting here, but which pipes it’s first argument through a pipeline built out of the rest of the arguments. So this example is the same as:

(defn new-functionality [x]
  (third-step (second-step (first-step x))))

Or imperatively:

def new_functionality(x)
  a = first_step(x)
  b = second_step(a)
  return third_step(b)

The thing is that by default this structure is internal to the function and cannot be extracted. Of course macros in languages such as clojure or Elixir should allow one to pick apart the parse tree of a function and figure this out automatically, so this is one way. I think tools such as erlang’s dialyzer perform such dives to do compile-time type-checking.

So I guess all I’m asking is that when I write a function some of this internal structure gets attached as metadata that’s easily accessible from the outside. For example if first-step above is a validation I can then discover that fact automatically when examining that function and reflect it in the docs.


Now read this

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... Continue →