What is a programmable programming language?
let add = (a, b) => a + b
You can then call the function with numbers as arguments:
You can also call the function with more complex arguments:
add(700 * 3 * 2, Math.pow(2, 16)) // Returns 69736
add function has no knowledge of the fact that you performed all those multiplications to compute the first argument, and it certainly doesn’t know that you called
Math.pow to compute the second.
add, so that by the time
add is called, the call looks something like this:
add to inspect the operations that went into calculating its arguments.
In a Lisp dialect, though? It’s easy! You can write a special kind of function called a macro that receives all it’s arguments as-is. The macro can inspect the whole thing before deciding what to do, making some truly dynamic behavior possible.
Here’s the same
add function in Clojure, a Lisp dialect:
(defn add [a b]
(+ a b))
(add (* 700 3 2) (Math/pow 2 16)) ; Returns 69736
add function has no idea that you multiplied a bunch of numbers together to create its first argument, ditto for
Let’s create an
add macro instead. To keep things simple, let’s have it print its arguments and return nothing:
(defmacro add [a b]
(println "arg a is" a "of type" (type a))
(println "arg b is" b "of type" (type b)))
And here’s what you’d see if you invoked it:
formulate=> (add (* 700 3 2) (Math/pow 2 16))
arg a is (* 700 3 2) of type clojure.lang.PersistentList
arg b is (Math/pow 2 16) of type clojure.lang.PersistentList
add function is able to "see" its arguments in their entirety! Note that
clojure.lang.PersistentList is simply the type Clojure uses for its linked list data structure, so these arguments can be manipulated just like regular lists.
Crucially, you can now have the
add macro generate an implementation based on these arguments. You could run
Math/abs on every single integer that was used to construct the arguments to
add, or attempt to detect if one of the arguments has overflowed.
This was a very contrived example, but it goes to show how a programmable programming language can let you do things that are impossible in other languages.