Code Is Data

Have you ever heard your friendly (but annoying) neighborhood Lisper loudly proclaim that “Code is data!” and wondered why in the heck anyone would store source code in a database? OK, of course you know that’s not what she means, but it’s not necessarily obvious what the expression does mean.

So let’s drill in: she means that the code itself is constructed using only the data structures in the language. Non-Lisp languages, on the other hand, usually have code with some relatively large syntax, where the syntax for their data structures is just a small subset of the full language syntax. This is much easier to visualize with an example, so let’s take a look at the data structures contained in a bit of Clojure code from clojure.core:

basics/defn.clj
 
(​defn​ ​mapcat
 
"Returns the result of applying concat to the result of applying map
 
to f and colls. Thus function f should return a collection."
 
{:added ​"1.0"
 
:static true}
 
[f & colls]
 
(​apply​ ​concat​ (​apply​ ​map​ f colls)))

Try your best to ignore the details of what this code does—let’s instead focus on its syntactic structure. The word defn here is a Clojure symbol, and the famous Lisp parentheses that surround it mean that everything from the opening to the closing parenthesis represents a list. Similarly, the parentheses around the two apply invocations also represent lists. The docstring ("Returns the result...") is just a literal string, and the :added and :static are keywords within a map of metadata. The argument list, [f & colls], is written as a vector of three symbols, f, &, and colls.

We have two ways to interpret this code. We can look at it the way we just did, as data structures, or we can look at how it evaluates. These dual interpretations are closely related to the way macros work. In the mapcat definition, the data structure representation of the code allows defn (which, as it turns out, is just a macro), to manipulate the source code passed to it.

Can you imagine why—aside from trivia and aesthetics—we actually care that the code can be viewed as normal data? The most compelling answer is that it makes it relatively straightforward to manipulate programs. When we do metaprogramming in Clojure, we can think at the expression level rather than at the textual level. It may not seem like a big deal right now, but as you’ll see over the course of this book, this simple concept is the key that allows you to write macros.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.107.193