LISP in 5 minutes (more or less)

Ben
3 min readFeb 9, 2021

--

So what is LISP? LISP is a style of syntax. Just Like c has influenced the syntax of java, python and JavaScript LISP has influenced the syntax of Clojure, Scheme and Common LISP. A lot of good programmers (RMS, Lex Fridman, Paul Graham, John Carmack …) think LISP is an elegant and powerful syntax and this article will try to explain what it is.

difficulty: 🐥 Simple , 🌶 Hard (at first glance) , 🔮 Black Magic

🐥LISP Syntax

Let’s compare a list in JavaScript and one in LISP

// JavaScript
[1, 2, 3]
// LISP
(1 2 3)

The main difference is that LISP doesn’t have any commas and use parentheses rather than brackets.

Let’s compare a function in JavaScript and one in LISP.

// JavaScript
add(1, 2) --> 3 // returns 3
// LISP
(add 1 2) --> 3 // returns 3

The main difference is that the function name is inside the parenthesis. Why is it this way? To understand let’s compare a list and a function in LISP

// List
(1 2 3) --> (1 2 3)
// Function
(add 1 2) --> 3

There is no difference. Just by including the function name inside the parenthesis your function has the same syntax has a list. But how does LISP differentiate a list from a function? Well, it depends on how it’s interpreted.

🐥LISP Quote

I was lying earlier for the sake of simplicity a list is actually written in two different ways.

(list 1 2 3)     --> (1 2 3)
(quote (1 2 3)) --> (1 2 3)
'(1 2 3) // "'" is an abbreviation for quote

The list function just returns a list of its arguments, but quote is more interesting. It tells the LISP interpreter to not eval/call/execute the first argument. Therefore if you quote a function call, it wouldn’t execute it would just be data; just a list.

(add 1 2)         --> 3
'(add 1 2) --> (add 1 2)
// JavaScript Equivalent
add(1, 2)
"add(1, 2)"

🌶 LISP Eval

You have the option to quote data, because by default LISP will evaluate your code.

(eval '(add 1 2)) === (add 1 2) --> 3

Basically your source code is data and when you execute it evaluates your data into executable code like a real time & incremental compiler.

🔮 LISP Eval + Quote = Macros

What is so amazing with the LISP syntax is the macros. The macro system is only powerful in lisp because code is data therefore you can actually manipulate code just like data. Actually that’s how compilers compile. They turn regular code into LISP code (S-Expressions/AST) in order to manipulate and evaluate code. Actually Paul Graham has an excellent quote about this:

If you understand how compilers work, what’s really going on is not so much that Lisp has a strange syntax as that Lisp has no syntax. You write programs in the parse trees that get generated within the compiler when other languages are parsed. But these parse trees are fully accessible to your programs. You can write programs that manipulate them. In Lisp, these programs are called macros. They are programs that write programs.

🔮Macros Example

// Macro definition in elisp
(defmacro for (init predicate end &rest body)
`(progn
,init
(loop
,@body
(if ,predicate
(return))
,end)))
// Macro call
(for (setq i 0) (= i 10) (setq i (+ i 1))
(print "hello, world"))
// Macro expansion
(progn
(setq i 0)
(loop
(print "hello, world")
(if
(<= i 10)
(return))
(setq i
(+ i 1))))

What macros allow you to extend the language without having to rewrite the interpreter/compiler. In this example I’m implementing a basic for-loop in LISP. You couldn’t implement such a thing in C. You would have to convince the language designers to implement your feature or start your own language. It was the case for C++. They wouldn’t add objects to the C compiler so they had to create a C++ compiler. In LISP it’s just a matter of adding a few macros.

--

--