Home Previous Next

CSC240 :: Lecture Note :: Week 09
Assignments | Code | Handouts | Resources | Email Thurman {Twitter::@compufoo Facebook::CSzero}
{GDT::Bits:: Time  |  Weather  |  Populations  |  Special Dates}

Overview

Assignment(s): #MakeHelloWorld2 (due 11/14/2017)

Code: cons.cpp


Introduction to Lisp

Lisp (LISt Processing) was created by John McCarthy. Via Wikipedia.org: "John McCarthy (September 4, 1927 - October 24, 2011) was an American computer scientist and cognitive scientist. McCarthy was one of the founders of the discipline of artificial intelligence. He coined the term "artificial intelligence" (AI), developed the Lisp programming language family [...]." John McCarthy was awarded the ACM Turing Award in 1971.

Note: Lisp does not stand for "Lots of Irritating Superfluous Parentheses."

The clisp command executes the "Common Lisp" interpreter and compiler.

clisp runs in interactive mode (read-eval-print loop) when executed with no arguments. Nutshell: READ an expression from the standard input; EVALuate the expression; PRINT results to standard output.

The format of clisp prompts: [n]> (where n is the command number).

$ clisp
  i i i i i i i       ooooo    o        ooooooo   ooooo   ooooo
  I I I I I I I      8     8   8           8     8     o  8    8
  I  \ `+' /  I      8         8           8     8        8    8
   \  `-+-'  /       8         8           8      ooooo   8oooo
    `-__|__-'        8         8           8           8  8
        |            8     o   8           8     o     8  8
  ------+------       ooooo    8oooooo  ooo8ooo   ooooo   8

Welcome to GNU CLISP 2.49 (2010-07-07) 

Copyright (c) Bruno Haible, Michael Stoll 1992, 1993
Copyright (c) Bruno Haible, Marcus Daniels 1994-1997
Copyright (c) Bruno Haible, Pierpaolo Bernardi, Sam Steingold 1998
Copyright (c) Bruno Haible, Sam Steingold 1999-2000
Copyright (c) Sam Steingold, Bruno Haible 2001-2010

Type :h and hit Enter for context help.

[1]> (bye)
Bye.

Many commands like clisp support a "quiet mode" that is turned on by executing them using either a -q or --quiet option. {clisp.org::man clisp (manual page)}

$ clisp --quiet
[1]> (bye)

Let's start again using "quiet mode."

$ clisp -q

[1]> "hello, world"
"hello, world"

[2]> "0 or more characters in double quotes is a string"
"0 or more characters in double quotes is a string"

[3]> "comments start with a ; and end at end-of-line" ; this is a comment
"comments start with a ; and end at end-of-line"

[4]> "three types of numbers: integer, floating-point, ratio"
"three types of numbers: integer, floating-point, ratio"

[5]> 240  ; is-an integer
240

[6]> -240 ; is-an integer
-240

[7]> 3.14 ; is-a floating-point
3.14

[8]> "number and strings evaluate to themselves"
"number and strings evaluate to themselves"

[9]> "lisp supports ratios when integer arguments are used"
"lisp supports ratios when integer arguments are used"

[10]> 5/7
5/7

[11]> "you can use ratios to reduce fractions"
"you can use ratios to reduce fractions"

[12]> 42/240  ; proper fraction
7/40

[13]> 240/7  ; improper fraction
240/7

[14]> 240/8  ; prints an integer if denominator is 1
30

[15]> 240/100
12/5

[16]> 240/100.0  ; ratio arguments must be integers
*** - SYSTEM::READ-EVAL-PRINT: variable |240/100.0| has no value

[17]> 6.62607004e-34   ; floating-point in scientific notation
6.62607E-34

[18]> "let's look at symbols"
"let's look at symbols"

[19]> T       ; true (any value that's not nil)
T

[20]> t       ; not case sensitive (case insensitive?)
T

[21]> nil     ; false (or empty list)
NIL

[22]> Nil     ; not case sensitive
NIL

[23]> NIL
NIL

[24]> (exit)  ; same as (bye) and (quit)
Numbers in Other Number Systems
[1]> #b1010    ; base-2 (binary)
10

[2]> #o31      ; base-8 (octal)
25

[3]> #x2b      ; base-16 (hexadecimal)
43

[4]> #12r180   ; base-12 (can go up to 36)
240

[5]> #36r6o   ; base-36
240

[6]> #60r240  ; base-60
***error: The base 60 given between # and R should lie between 2 and 36

{TopOfPage} {Resources}


Number Operations

Lisp is a "prefix notation" language.

Arithmetic operators are functions having the following syntax.

   (function_name arguments) 

The arithmetic functions are named + - * / for addition, subtraction, multiply, and divide, respectively.

Quoting Peter Seibel: "Lisp was originally designed by a mathematician as a tool for studying mathematical functions."

Addition and Subtraction
$ clisp -q

[1]> (+ )
0

[2]> (+ 2)
2

[3]> (+ 2 3)
5

[4]> (+ 2 3 4)
9

[5]> (- )
*** - EVAL: too few arguments given to -: (-)

[7]> (- 4)
-4

[8]> (- 4 2)
2

[9]> (- 2 4)
-2

[10]> (- 4 2 1)
1

[11]> (- -3 -2)
-1

[12]> (- pi)
-3.1415926535897932385L0
Multiplication
$ clisp -q

[1]> (* )
1

[2]> (* 5)
5

[3]> (* 4 2)
8

[4]> (* 4 2 3)
24

[5]> (* 4 -5)
-20
Division
$ clisp -q

[1]> (/ )
*** - EVAL: too few arguments given to /: (/)

[3]> (/ 5)
1/5

[4]> (/ 5 2)
5/2

[5]> (/ 5 2.0)
2.5

[6]> (/ 6 2)
3

[7]> (/ 3 6)
1/2

[8]> (/ 12 2 2)
3

[9]> (/ 4 -2)
-2

[10]> (/ 4 0)
*** - /: division by zero
Predicates
$ clisp -q

[3]> (oddp 5)            ; predicate function names usually end in p
T

[4]> (oddp 10)
NIL

[5]> (evenp 5)
NIL

[6]> (evenp 10)
T

[13]> (zerop 10)
NIL

[14]> (zerop 0)
T

[15]> (plusp 12)            
T

[16]> (plusp -12)
NIL

[17]> (typep 240 'integer)    ; ' is the quote character
T

[18]> (typep 240 'float)      ; or do (typep 240 (quote float))
NIL

[19]> (typep 240 'long)
*** - TYPEP: invalid type specification LONG

[20]> (typep 240 'string)     ; or do (typep 240 (quote string))
NIL

[21]> (typep 240 'double)
*** - TYPEP: invalid type specification DOUBLE

[22]> (typep 240 'real)
T

[23]> (typep 240 'number)
T

[24]> (typep 240 'character)
NIL

[25]> (typep 240 'complex)
NIL

[26]> (integerp 240)
T

[27]> (floatp 240)
NIL

[28]> (complexp 240)
NIL

[29]> (stringp 240)
NIL

[30]> (characterp 240)
NIL

[31]> (numberp 240)
T

[32]> (typep "240" (quote string))
T

[33]> (typep "240" 'string)
T

[34]> (stringp "240")
T
Increment/Decrement
$ clisp -q

[1]> (1+ 0)
1

[2]> (1+ 1)
2

[3]> (1+ 2)
3

[4]> (1- 3)
2

[5]> (1- 2)
1

[6]> (1- 1)
0

[7]> (1- 0)
-1

[8]> (1+ 3.1416)            ; strange evaluation
4.1415997

[9]> (1- 3.1416)
2.1416
Math Functions
$ clisp -q

[1]> (gcd 20 30 40 50)   ; greatest common divisor
10

[2]> (lcm 1 2 3 4)       ; least common multiple
12

[3]> (rem 5 2)           ; the % operator in C and Java
1

[4]> (abs -5)            ; absolute value
5

[5]> (max 5 92 1 3 1 6)
92

[7]> (min 5 92 1 3 1 6)
1

[18]> (random 10)
9

[19]> (random 92.31)
27.658089

[20]> (floor pi)
3 ;
0.14159265358979323851L0

[21]> (ceiling pi)
4 ;
-0.8584073464102067615L0

[22]> (round pi)
3 ;
0.14159265358979323851L0

[23]> (truncate pi)
3 ;
0.14159265358979323851L0

[24]> (mod 240 7)
2

[25]> (ext:! 4)    ; ext: indicates an extension
24
Exponents/Logarithms
$ clisp -q

[1]> (expt 2 5)
32

[2]> (expt 5)
*** - EVAL: too few arguments given to EXPT: (EXPT 5)

[4]> (exp 5)
148.41316

[5]> (expt 0)
*** - EVAL: too few arguments given to EXPT: (EXPT 0)

[6]> (expt 5 0)
1

[7]> (sqrt 5)
2.236068

[8]> (sqrt 25)
5

[9]> (log 100)           ; base-e (natural logarithm)
4.6051702

[10]> (sqrt -1)          ; complex numbers supported
#C(0 1)

[11]> (isqrt 5)          
2

[12]> (log e)
*** - SYSTEM::READ-EVAL-PRINT: variable E has no value

[13]> (exp 1)
2.7182817


[14]> (log pi)
1.1447298858494001742L0

[15]> (log 8 2)        ; base-2 log
3

[16]> (log 100 10)     ; log is base-10 by default
2

[17]> (expt 25 0.5)    ; (expt base power)
5.0

; Lisp handles numbers greater than 2^262144 (via Peter Seibel)
[18]> (expt 2 262144)
Evaluating Expressions
$ clisp -q

; evaluate: 237 + 24 / 8
[1]> (+ 237 (/ 24 8))  
240

; evaluate:  240 + 14 * 2 / 4 - 7
[2]> (- (+ 240 (/ (* 14 2) 4)) 7)
240

; evaluate:  2 * (22 % 7)
[3]> (* 2 (mod 22 7))
2

; evaluate:  f(x) = 15 + 86(x)  when x = 4
[4]> (+ 15 (* 86 4))
359

; convert 240 Kelvin to degree Fahrenheit: 240 x (9/5) - 459.67
[5]> (- (* 240 (/ 9 5.0)) 459.67)
-27.670013

; calculate the golden ratio (phi):  (1 + sqrt(5)) / 2
[6]> (/ (+ 1 (sqrt 5)) 2)
1.618034

; calculate the average of min { 1 2 3 } and max { 4 5 6 }
[7]> (/ (+ (min 1 2 3) (max 4 5 6)) 2)
7/2

[8]> (/ (+ (min 1 2 3) (max 4 5 6)) 2.0)
3.5

; triple the sum of -2, 0, 5
[9]> (* 3 (+ -2 0 5))
9

; evaluate:  4^3 - 3^2 + 3^4
[10]> (+ (- (expt 4 3) (expt 3 2)) (expt 3 4))
136

; evaluate Avogardo number:  6.022140857 * 10^23
[12]> (* 6.022140857 (expt 10 23))
6.022141E23

; evaluate Plank constant:  6.62607004 * 10^-34
[13]> (* 6.62607004 (expt 10 -34))
6.62607E-34

; evaluate Plank constant and store in a variable
[14]> (setf plank (* 6.62607004 (expt 10 -34)))
6.62607E-34

; evaluate f(x) = 3x^2 - 5x + 2 when x = 2
[15]> (setf x 2)
[15]> (+ 2 (- (* 3 (expt x 2)) (* 5 x)))
4

; evaluate g(x) = x^3 - 6x^2 + 11x - 6
[16]> (setf x 3)
[16]> (+ (expt x 3) (* -6 (expt x 2)) (* 11 x) -6)
0

; evaluate:  5^2 + 5 * 2 - 4 / 2^2
[17]> (+ (expt 5 2) (* 5 2) (/ -4 (expt 2 2)))
34

; evaluate:  (2 * (4 + (5 + 3)))
[18]> (* 2 (+ 4 (+ 5 3)))
24

; evaluate:  (4 + 6) - ((((8 / 4) - 1) * 6))
[19]> (- (+ 4 6) (* (- (/ 8 4) 1) 6))
4

; evaluate:  ((8 / 4) + 6) - (2 * (9 - 8))
[20]> (- (+ (/ 8 4) 6) (* 2 (- 9 8)))
6

; format Plank constant as a string using FORMAT function
[21]> (format nil "~f" plank)
"0.000000000000000000000000000000000662607"

; print Plank constant to standard output stream using FORMAT function
[22]> (format t "~f" plank) 
0.000000000000000000000000000000000662607
NIL

{TopOfPage} {Resources}


Lisp Programs Stored in a File

The following was excuted using BASH on a Linux system. In BASH, # starts a comment that ends at end-of-line.

$ vim hw.lisp    # lisp code inserted into hw.lisp using vim text editor

$ ls             # lisp code stored in a dot-lisp file
hw.lisp

$ cat hw.lisp    # display contents of hw.lisp
;;; 
;;; This Lisp program prints the phrase "hello world"
;;; followed by a newline to the standard output stream.
;;;

(write "hello, world")

$ clisp -q -c hw.lisp   # submit file to the clisp compiler
;; Compiling file /home/gdt/lisp/src/hw.lisp ...
;; Wrote file /home/gdt/lisp/src/hw.fas
0 errors, 0 warnings

$ ls                    # dot-fas (bytecode) and dot-lib files created
hw.fas   hw.lib   hw.lisp

$ clisp hw              # execute the program using clisp
"hello, world"

$ clisp hw | od -c      # 'od' (octal dump) to see newline character
0000000   "   h   e   l   l   o   ,       w   o   r   l   d   "  \n
0000017

But... the phrase "hello, world" should not include double quotes.

$ vi hw2.lisp

$ cat hw2.lisp
(format t "~a" "hello, world")

$ clisp -q -c hw2.lisp
;; Compiling file /home/gdt/lisp/src/hw2.lisp ...
;; Wrote file /home/gdt/lisp/src/hw2.fas
0 errors, 0 warnings

$ clisp hw2
hello, world

$ clisp hw2 | od -c
0000000   h   e   l   l   o   ,       w   o   r   l   d  \n
0000015

{TopOfPage} {Resources}


Relational Functions

The relational functions (=, /=, <, >, <=, >=) evaluate to NIL to T.

$ clisp -q
[1]> (= 3 5)
NIL

[2]> (/= 3 5)
T

[3]> (> 3 5)
NIL

[4]> (< 3 5)
T

[5]> (>= 3 5)
NIL

[6]> (<= 3 5)
T

[7]> (= 5 5 5 5)
T

[8]> (= 5 5 2 5)
NIL

[9]> (/= 5 5 5 5)
NIL

[10]> (/= 5 4 8 2)
T

[11]> (/= 5 4 5 2)
NIL

[12]> (< 2 3 5 9)
T

[13]> (< 2 5 3 9)
NIL

[14]> (> 9 5 3 0)
T

[15]> (> 9 3 5 0)
NIL

[16]> (< 2 5 5 8)
NIL

[17]> (<= 2 5 5 8)
T

[18]> (> 3 2 2 1)
NIL

[19]> (>= 3 2 2 1)
T

; hmm...

[20]> (= 5)
T

[21]> (= 0)
T

[22]> (/= 5)
T

[23]> (/= 0)
T

[24]> (> 3)
T

; what about strings?

[25]> (= "foo" "foo")
*** - =: "foo" is not a number

; eq, eql, equal, equalp will be covered later...
; nutshell:
;    + eq compares addresses, while equal compares content
;    + never use eq to compare numbers
;    + eql is the "standard" comparison predicate

[26]> (eql 3 3)
T

[27]> (eql 3 2)
NIL

[28]> (equal 3 2)
NIL

[29]> (equal 3 3)
T

[30]> (eql 3 3.0)     ; different types... use =
NIL

[31]> (= 3 3.0)
T

[32]> (equal "Foo" "foo")
NIL

[33]> (equal "foo" "foo")
T

[34]> (eq "foo" "foo")    ; eq compares addresses
NIL

{TopOfPage} {Resources}


Home Previous Next