Week 1
Intro to Lisp
Lisp
Acronym: List Processing || Lots of Irritating Silly Parentheses
# To run lisp progran in VS Code:
> rlwrap sbcl # starts REPL - read-eval-print loop
* (load "file.lisp") # assume hello()
* (hello) # calls hello() method in file.lisp
* (+ 2 3) # prints 5 (quick temp. form)
* (exit) # either trash the terminal or enter (exit)
Syntax Basics
Atoms
: basic syntactic units of the language ex:
Numbers
Integers (
0, -1, 69
)Ratios (
1/2, 2/3, 4/2
)Floats (
0.0, -1.0, +1.5
)
Individual Chars :
#\a, #\@
Strings :
"string"
Boolean :
T (true), NIL (false)
Symbols - names (made up of strings/numbers/chars) used for naming functions, variables, & other entities:
2021CPS305, symbolName123, +, T, NIL, <>, -+49ers+-, <+==+>
Lists : sequence of either atoms or other lists separated by blanks
(1 2 3) (a b c d) (a "b" T -2.0) (a (b c) (d (e f))) () ; () = NIL
Vectors : faster list-like sequence
#(1 2 3)
,#(a "b" -2.0)
S-Expressions
symbolic expressions (aka function application: non-empty list are themselves forms)
syntax :
( op a1 a2 a3 ... )
op
: function || operator
a1 a2 a3 ...
: arguments || operands
Forms
: lisp expressions that may be meaningfully evaluated
(= (+ 2 3) 5)
: evaluates tot
(a b c)
: ERROR 'a' is not a function (this is a list, not a form)
; same as 2 * 8
; evaluates to 6
(* 2 8)
; you can chain operations aswell
; same as doing 2 + (4 * 4)
; evaluates to 18
(+ 2 (* 4 4))
; another ex.
; same as doing (8/2) - (8*4)
(- (/ 8 2) (* 4 8))
; = to -28
; (2 + [4 * 6]) * (3 + 5 + 7)
; = 390
(* (+ 2 (* 4 6)) (+ 3 5 7))
; (2 - [3 - [6 + 4/5]]) ÷ (3 * [6 - 2])
; = 29/60
(/
(- 2 (- 3 (+ 6 4/5))) ; numerator
(* 3 (- 6 2)) ; denominator
)
; evaluates to 29/60
Variables & Constants
below ex. are for global vars/const ; for local vars use
let
>defvar
Variables
DEFINE =
(defvar varName varValue "var desc.")
SET =
(setq varName newValue)
; defines a mutable var *total-glasses* and assigns it's value to be 0 ; u dont need the *sandwich* like below ex's, but it is good practice (defvar *total-glasses* 0 "Total glasses so far") ; change value to 3 (setq *total-glasses* 3) ; same as += 1 (setq *total-glasses* (+ *total-glasses* 1))
Constants
DEFINE =
(defparameter constName constValue)
SET =can't change const value
; const variable B = 20 (defparameter B 20)
Named Procedures (aka Functions)
syntax : (defun [funcName] ([parameters]) ([body]) )
; squares the value of x
(defun square (x) (* x x))
; sum of squares of 2 parameters
(defun sum-of-squares (x y)
; calls above square function from inside this function
(+ (square x) (square y))
)
Lambda (Anonymous Functions)
much like in other languages,
lambda
fx's are quick one liners that are defined and called in the same line.
syntax : ( (lambda params body) arguments )
; normal (squares 4) vs. lambda function:
( (lambda (x) (* x x)) 4 )
((lambda (x y) (+ x y)) 2 2) ; => 4
Blocks + Progn
Block
Blocks allow for contorlled sequential execution.
syntax :
(block blockName body)
(block test (print "hello") (+ 2 2) ) ; evaluates to: ; "hello" ; 4
Progn
skipped the blockname and can call the block directly
syntax :
(progn body)
; evaluates to same thing above (progn (print "hello") (+ 2 2) )
Special Forms
If op
is 1 of 25 special words, the form is evaluated as a special form
Special Forms usually produce values (but not always)
quote
(quote v)
aka'v
where v=form : returns v as data, w/o evaluating it.(quote (+ 2 3)) ; (+ 2 3) not 5 '(+ 2 3) ; (+ 2 3)
and / or
The following objects are interpreted as NIL :
()
,'()
,NIL
,'NIL
All other objects are interpreted as True
and a1 ... aN
all forms a1...aN are evaluated (L-to-R)
if any form evaluates to NIL,
and
returns NILif none of the forms are NIL,
and
returns evaluation of aN
; 3rd form is nil
; returns NIL
(and 0 1 nil (+ 3 4) 3)
; no form is NIL
; returns (* 3 3) = 9
(and 0 1 2 (* 3 3))
or a1 ... aN
all forms a1...aN are evaluated (L-to-R)
if any form ai evaluates to true,
or
returns evaluation of aiif all forms but aN evaluate to NIL,
or
returns evaluation of aN
; 3rd form is (< 3 4) (truthy)
; return (< 3 4) = T
(or nil (> 5 6) (< 3 4) (= 1 2))
; 1st form is 0 (truthy)
; returns 0
(or 0 (* 3 3) 2 1)
if
(if cond then [else])
if
cond
-form is T, then evaluatethen
-formopt.
[else]
-form is evaluated ifcond
-form is NIL (false)
(if (condition)
(option-1)
; else
(option-2))
; cond=NIL, so else=(* 3 2) =6
(if nil
4
(* 3 2)) ; else
; cond=(and 0 1 NIL ..) =NIL, so else=10 =10
(if (and 0 1 nil (+ 3 4) 3)
3
10) ; else
; cond=(or 0 ...) =0 (truthy), so then=(+ 5 5) =10
(if (or 0 (* 3 3) 2 1)
(+ 5 5) ; then
(* 10 10))
When we want to evaluate several conditions in a row we use
cond
:(cond ; if condition 1 ((= 1 2) (print "hello")) ; else if condition 2 ((= 1 1) (print "world")) ; else (t ("nothing else worked"))) ; evaluates to: ; "world"
let
special form for temporary local variable binding
syntax :
(let ((var1 val1) … (varN valN)) <s-expressions>)
var1, ... varN
: variable namesval1, ... valN
: initial values assigned to respective vars (default=NIL)each varN is assigned to their valN, and finally the s-expression is evaluated.
The value of the last expression evaluated is returned
; x =4
; s-exp = (* 4 4) =16 is returned
(let ((x 4)) (* x x))
(let ((x 3) ; x=3
(y 1)) ; y=1
(+ (* y x) x)) ; s-exp = (+ (* 1 3) 3) =6 is returned
; ERROR
(let ((x 3) ; x=3
(y (* x x))) ; ERROR 3 hasn't been bound to x yet!
(+ x y))
Loops
dotimes
: used to create simple loops that loop from 0 to n-1analogous to "for i in range(n)" in python
syntax :
(dotimes (i [n] [completed value]))
i
- loop iteration variablen
- loops until n-1completed value
- opt. value that's returned when the loop completes;NIL
by default.
(dotimes (i 3) (prnt i)) ; 0 ; 1 ; 2 ; NIL
do
: more versatile loopingsyntax :
(
do
((i
[start value]
([increment by]
[operation]
i
)(
[body]
)))((
[exit condition]
)i
)(
[body]
))(defvar i 0) (do ((i 0 (1+ i)) (print i)) ((> i 4) i) ((print i)))
Note:
i
needs to be initialized prior.
Last updated