lisp-in-quantum/How_does_Lisp_work.md

5.7 KiB
Raw Blame History

How does Lisp work?

This is from the book meta math by Gregory Chaitin!! I think it was explained really well. So how does it work?

LISP Style

First of all LISP is a non-numerical programming language. Instead of computing only with numbers, you deal with symbolic expressions which are called “S-expressions.”

Programs and data in LISP are both S-expressions. Whats an S-expression? Well, its like an algebraic expression with full parenthesization. For example, instead of

a * b + c * d

you write

((a * b) + (c * d))

And then you move operators forward, in front of their arguments rather than between their arguments, like so

(+(* a b) (* c d))

This is called prefix as opposed to infix notation which were typically used to. Actually in LISP it written this way

(+ (* a b) (* c d))

Pretty much the same thing as above. And just like in other programming languages * is used for multiplication, and you also have minus - and exponentiation ^ in LISP.

The cool thing in LISP is S-expressions. In general, an S-expression consists of a nest of parentheses that balance, like this

(     ( )  (( ))   ((( )))    ) 

What can you put INSIDE these parentheses? Words, and unsigned integers, which can both be arbitrarily big. And for doing math with integers, which are exact, not approximate numbers, its very important to be able to handle very large integers.

Also, a word or unsigned integer can appear all by itself as an S-expression, with no parentheses. Then, this is referred to as an atom (which means “indivisible” in Greek). If an S-expression isnt an atom, then its called a list, and its considered to be a list of elements, with a first elements, a second, a third, etc.

(1 2 3) 

and

((x 1) (y 2) (z 3))

are both lists with three elements.


Stay Functional

LISP is a functional programming language. Which means that everything in LISP (thats instructions rather than data) is built by applying functions to arguments like this:

(f x y) 

This indicates that the function “f” is applied to the arguments “x “and “y”.

is another way to say in pure math normally written like this:

f(x,y)

And everything is put into this function-applied-to-arguments form. For example,

(if condition true-value false-value)

is how you choose between two values depending on whether a certain condition is true or not. So “if” is treated as a three-argument function with the strange property that only two of its arguments are evaluated. For instance

(if true (+ 1 2) (+3 4))

gives 3, and

(if false (+1 2) (+3 4)) 

gives 7,

Another handy pseudo-function is the quote function, which doesnt evaluate its only arguments. The argument following the quote is literal data, not an expression to be evaluated. For instance

( ( a b c)) 

gives (a b c) “as is”. In other words, this does not mean that the function a should be applied to the arguments b and c************************************************************************************************************************************************************.************************************************************************************************************************************************************ Like stated, it is literal data not an expression to be evaluated.

Here are two more conditions that may be used with “if.”

(= x y) 

gives true if x is equal to y.

(atom x) 

gives true if x is an atom, not a list.

Next, let me tell you about “let” which is very important because it enables you to associate values with variables and to define functions.

(let x y expression) 

yields the value of “expression” in which x is defined to be y. You can use “let” either to define a function, or like an assignment statement in an ordinary programming language. However, the function defining or assignment is only temporarily in effect, inside “expression”. In other words, the effect of “let” is invariably local.

Here are two examples of how to use “let”. Let n be 1 + 2 in 3 * n. So it would be

(let n (+ 1 2)
		(* 3 n)
)

This gives 9. And now, let f of n be n * n in f of 10.

(let (f n) (*n n) 
	 (f 10)
)

This gives 100.

Also in LISP, we can take lists apart and then reassemble them. To get the first element of a list,, we “car” it.

(car ( (a b c))) 

gives a. To get the rest of a list, we “cdr” it.

(cdr ( (a b c)))

gives (b c). And to reassemble the pieces, you “cons” it.

(cons ( a) ( (b c)))

which gives us back (a b c) .

And thats it! Thats the general idea. LISP is a simple but powerful formalism.

Before showing two real LISP programs, let me point out that in LISP you dont speak of programs. Theyre called expressions. And you dont run them or execute them, you evaluate them. And the result of evaluating an expression is merely a value; there is no side effect. The state of the universe is unchanged.


Back to basics.

Of course, mathematical expressions have always behaved like this. But normal programming languages are not at all mathematical. LISP is mathematical.