I find the list processing possibilities of LISP languages very interesting. LISP stands for LISt Processing so I’m discovering anything new here. This is the core of the language, so far the implications worth noting are:
For the sake of simplicity of the argument and examples in the book:
Expressions are lists of numbers and operators
This means that we can turn a ‘real’ expression for example: (+ 1 1)
or (1 + 1)
into a data representation of such expression. So (1 + 1)
is a list of the atoms: 1
, +
and 1
. Why is this even important? This setup makes interpreting an expression easy. We can create a “new nano example language” where we use plus
keyword for addition, for example (plus 1 1)
. It is very easy to interpret such an expression. We can say: “if the first operator is keyword plus
just add the next two expressions. Yes, expressions, not numbers, because (plus 1 (plus 1 3))
is also a valid expression in our example language. Given enough imagination and time it is possible to build a Turing Complete language based on this principle.
All we need is a handful of primitives
For basic (and possibly advanced) arithmetics we just need four primitives number?
, zero ?
, add1
and sub1
.
Numbers are just representations
4 is a representation of a concept of four. For the sake of this example, the essence of four is a representation of four things. We’re used to an abstract definition of the number: 4. Yet numbers can be represented in different ways, they could be Roman numerals (IV
, XII
) or lists of empty lists, and an infinite number of other things.
We can represent numbers as list of empty lists such as:
; NumberList is one of the following:
; - '()
; - (cons '() Number List)
0 is ’()
4 is ’(() () () ())
We can use all four primitives (number?
, zero ?
, add1
and sub1
) and compute arithmetical expressions. Which is a great way to experience that the data representation (Arabic numbers, lists and more) are just a surface definitions behind certain concepts.