Lisp Syntax & Eval Model

1. Syntax

  • Algol-like languages: infix notation
1 + 2 + 3; // and not +(1, 2, 3)
myFunction(x, y, z);
  • Lisp: prefix notation (aka Polish)
(+ 1 2 3)
(myfunction x y z)

Our '+' is a regular function call. Read: Apply the addition to the numbers...


(+ 1 2 3)
;; but we have libraries to use infix notation for math

(my-function x y z)

(defun hello (name)
  "documentation string"
  (format t "Hello ~a" name))

(hello "you")


1 + 2 + 3;

my_function(x, y, z);

function hello (name) {
  console.log("hello ", name);
}

hello("you");

2. Evaluation Model

2.1 Functions

  • No surprises here: a function call first evaluates all its arguments, from left to right.

(format t
  "Hello ~a, you are ~a years old."
  "Lisp"
  (- 2022 1958))

2.2 Everything is an Expression

  • Everything will return a result.

(format t "Hello ~a, you are ~a"
  "Lisp" 
  (let ((age (- 2022 1958))) 
  (if (< 50 age)
    "not making your age!"
    "young.")))

2.3 Macros

  • Macros are not functions
  • They don't follow their evaluation model.
  • Macros manipulate code (syntactic expressions) and generate code. You'll learn macros in due time!

(defmacro parrot-eval (expression) 
    `(format t "The result of ~S is: ~S"
            ',expression
            ,expression))

(parrot-eval (+ 2 2))
=>
"The result of (+ 2 2) is : 4"

Commonly Used Macros

They have a different syntax than functions. Spotting them helps understand the code.

  • Iteration macros: dolist, loop...
(dotimes (i 5)
    (print i))
  • Condition handling macros: handler-case, ignore-errors...
(ignore-errors
    (parse-integer "*!?"))
  • All macros that start with "with": with-open-file, with-output-to-string...

(with-open-file (myfile "hellotest.txt"
                        :if-does-not-exist :create
                        :direction :output
                        :if-exists :overwrite)
    (print "hello" myfile))