Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Lisp
1. Aniruddha Chakrabarti
Associate Vice President & Chief Architect, Digital Practice, Mphasis
caniruddha@hotmail.com | in.linkedin.com/in/aniruddhac
Lisp (LISP)
2. The greatest single programming language ever designed.
Alan Kay, about LISP.
The most powerful programming language is Lisp. If you don't know Lisp (or its variant,
Scheme), you don't appreciate what a powerful language is. Once you learn Lisp you will
see what is missing in most other languages.
Richard Stallman [How I do my computing]
One of the most important and fascinating of all computer languages is Lisp, which was
invented by John McCarthy around the time Algol was invented.
Douglas Hofstadter, Gödel, Escher, Bach: an Eternal Golden Braid
Lisp is worth learning for the profound enlightenment experience you will have when you
finally get it; that experience will make you a better programmer for the rest of your days,
even if you never actually use Lisp itself a lot.
Eric S. Raymond, How to Become a Hacker
1958 - John McCarthy and Paul Graham invent LISP. Due to high costs caused by a post-
war depletion of the strategic parentheses reserve LISP never becomes popular...
Fortunately for computer science the supply of curly braces & angle brackets remains high.
Iry James, A Brief, Incomplete, and Mostly Wrong History of Programming Languages
Few remarkable quotes on Lisp
Source - http://www.paulgraham.com/quotes.html
3. Agenda
• What is Lisp, brief history and where Lisp is used
• Basic syntax, building blocks, prefix notation
• Data types
• Variables
• Constants
• IO (Read and Write/print)
• Control flow statements
• List and List comprehension
• Function and Lambda Expression
• Structure
4. What is Lisp
• Lisp (or LISP) is a family of computer programming languages with a long
history and a distinctive, fully parenthesized syntax.
• Invented in 1958 by John McCarthy
• Second-oldest high-level programming language in widespread use today;
only Fortran is older (by one year).
• Generally regarded as being the first functional programming language.
• Not a pure functional language as supports variable assignment.
• The name Lisp (historically LISP) derives from LISt Processor
• Multi paradigm – functional, procedural, reflective, meta
• First programming language that showed concepts and constructs of
functional programming
• Not an imperative programming language like C, C++, Java, C#
• Has many dialects, two of the following being most popular
– Common Lisp
– Scheme
5. History
• Invented by John McCarthy in 1958 while he was at MIT
• First implemented by Steve Russell on an IBM 704 computer.
• Common Lisp originated, during the 1980s and 1990s, in an attempt to unify
the work of several implementation groups.
Steve RussellJohn McCarthy
http://www.paulgraham.com/rootsoflisp.html
6. Where is Lisp (or it’s dialects) used
• AI (Artificial Intelligence)
• Academia / Education (in many CS courses)
– Structure and Interpretation of Computer Programs (MIT)
– DrRacket
• CAD (AutoCAD, CoCreate, and several others)
• Development environments (Emacs and others)
• Clojure a dialect of Lisp (targets the Java Virtual Machine, also CLR and
Javascript) has seen good acceptance in recent years
– http://dev.clojure.org/display/community/Clojure+Success+Stories
7. Lisp dialects & languages it influenced
• LISP 1 – First implementation.
• LISP 1.5 – First widely distributed version,
developed by McCarthy and others at MIT.
• Stanford LISP – This was a successor to LISP 1.5
developed at the Stanford AI Lab
• MACLISP – developed for MIT's Project MAC
• Common Lisp
• Scheme
• Emacs Lisp
• Clojure - a modern dialect of Lisp which
compiles to the Java virtual machine and
handles concurrency very well.
• Haskell
• Logo
• Lua
• Perl
• Python
• Racket
• JavaScript
• Ruby
• Smalltalk
• Tcl
• R
8. Lisp Program Structure
• LISP expressions are called symbolic expressions or s-
expressions. The s-expressions are composed of three valid
objects, atoms, lists and strings.
• Any s-expression is a valid program.
Example - (+ 1 2)
• LISP programs run either on an interpreter (REPL) or
as compiled code
• LISP expressions are case-insensitive, so the below lines are
same -
(write-line "Hello World")
(WRITE-LINE "Hello World")
• The basic numeric operations in LISP are +, -, *, and /
• LISP represents a function call f(x) as (f x), for example cos(45)
is written as (cos 45)
9. Basic Lisp Syntax
• Lisp has a different syntax than C like languages (C++, Java, C#)
• Uses parenthesis extensively - ( and )
• Uses prefix notation
For example the expression to add 1 and 2 would be (+ 1 2) in Lisp
Lisp C like languages
Math Operation (+ 1 2)
(+ 1 2 3 4)
1 + 2
1 + 2 + 3 + 4
Variable Assignment (defvar my-name "David") my-name = "David"
Invoking Functions (write-line "Hello World") printf("Hello World")
If, Else (if (> 2 3)
"bigger"
"smaller")
if (2 > 3){
"bigger"
}
else
"smaller"
}
Function definition (defun add (a b)
(+ a b))
int add(int a,int b){
return a + b;
}
10. Building Blocks of Lisp
• LISP programs are made up of three basic building blocks:
– Atom: An atom is a number or string of contiguous characters. It
includes numbers and special characters.
hello-from-lisp
name
123008907
*hello*
Block#221
Abc123
– List: Sequence of atoms and/or other lists enclosed in parentheses.
( i am a list)
(a ( a b c) d e fgh)
(father tom ( susan bill joe))
(sun mon tue wed thur fri sat)
( )
– String: Group of characters enclosed in double quotation marks.
" I am a string"
"a ba c d efg #$%^&!"
"Please enter the following details :"
"Hello from 'Tutorials Point'! "
12. Prefix / Polish Prefix notation
• No concepts of operators for primitive types
• Simple arithmetic operations also follow function calling syntax
function_name arg1 arg2... argN
operator arg1 arg2 ... argN
(+ 2 5)
7
(+ 2 5 3 4 9 20)
43
(+ 2.5 7.25)
9.25
13. Notations
Prefix Notation
(also called Polish
Notation or Polish Prefix
Notation)
places operators to the
left of their operands
operator arg1 arg2
+ 2 5
7
Infix Notation
operators are written
infix-style between the
operands they act on
arg1 operator arg2
2 + 5
7
Postfix Notation
(also called Reverse
Polish notation (RPN))
puts the operator in the
prefix position.
operator arg1 arg2
2 5 +
7
14. Comment
• A Lisp comment begins with a semi-colon.
; This is a Lisp comments - ignored by the interpreter.
(print "Hello World") ; this is an example of comment
; the following statement prints addition of 2 and 3
(print (+ 2 3))
• Supports multiple comment through #| … |#
#|
this is an example of multiple comment
as this comment is spread across multiple lines
|#
#| first line
this is an example of multiple comment
as this comment is spread across multiple lines
last line |#
15. Symbol
• Symbol is a name that represents data objects and interestingly
it is also a data object.
• A symbol is just a string of characters.
• There are restrictions on what you can include in a symbol and
what the first character can be, but as long as you stick to
letters, digits, and hyphens, you'll be safe.
17. Data types
• type-of function returns the data type of a given object
(defvar name "XYZ")
(defvar age 30)
(defvar salary 1234.567)
(defvar isMale T)
(print (type-of name))
(print (type-of age))
(print (type-of salary))
(print (type-of isMale))
(SIMPLE-BASE-STRING 3)
(INTEGER 0 281474976710655)
SINGLE-FLOAT
BOOLEAN
18. Declaring new variables (defvar)
• defvar – declares global dynamic variables. DEFVAR optionally sets it
to some value, unless it is already defined.
• defvar assigns a value only first time. variables are generally
immutable (meaning their value can not change)
(defvar my-name "David")
"David"
my-name
"David"
(defvar my-name "David")
(print my-name) ;prints “David”
(defvar my-name “Aniruddha") ;does not change the value of my-name
(print my-name) ;still prints “David”
"David"
"David"
(defvar a-variable 57)
57
a-variable
57
• In Scheme, define is used both for procedures and for
variables whose values aren't procedures.
• In Lisp (and Common Lisp), procedures are given
names by a mechanism separate from the general
variable mechanism; defun is only for procedures. To
define a variable, use defvar
19. Declaring new variables (defparameter)
• defparameter – also declares global dynamic variables similar
to defvar.
• defparameter always assigns a value (unlike defvar which
assigns the value only first time)
(defparameter my-name "David")
"David"
my-name
"David"
(defparameter my-name "David")
(print my-name)
(defvar my-name “Aniruddha") ;does change the value of my-name
(print my-name)
"David"
“Aniruddha"
20. Mutate existing variables (setq)
• SETQ's first argument is a symbol. This is not evaluated. The second argument is
assigned as the variable's value.
(setq my-name "David")
"David"
my-name
"David"
(setq a-variable 57)
57
a-variable
57
• SETQ form can actually take any even number of arguments, which should be
alternating symbols and values.
• SETQ performs the assignments from left to right, and returns the rightmost
value.
(setq year 2014 month "September" day 20)
(print year)
(print month)
(print day)
Output: 2014
"September"
20
21. Declaring Constants (defconstant)
• Constants are variables that never change their values during program
execution.
• Constants are declared using the defconstant construct.
(defconstant PI 3.14)
(print PI)
3.14
(setq PI 6.54)
SETQ: PI is a constant, may not be used as a variable
22. Basic Printing - print, prin1, terpri
• print always precedes its output
with a newline.
• Syntax:
(print what_to_print/expression/form)
(print "Hello World")
Output: "Hello World"
(print 100.459)
Output: 100.459
(print (+ 10 5))
(print “Hello World”)
Output:
15
"Hello World"
• prin1 just like print except that it
does not do a new line before
printing
• Syntax:
(prin1 what_to_print/expression/form)
(prin1 (+ 10 5))
(prin1 “Hello World”)
Output: "" 15"Hello World“
(+ (prin1 1) (prin1 2))
Output:
“12”
3
• terpri produces a newline. Can be called without any argument.
(prin1 (+ 10 5)) (terpri)
(prin1 "Hello World") (terpri)
(prin1 "Hello World 2")
15
"Hello World"
"Hello World 2"
23. Basic Printing – write, write-*
• write-string: It writes the characters of the specified substring of string to
the output-stream.
• write-line: It works the same way as write-string, but outputs a newline
afterwards.
• write: typically used with an object or structure
• write-*: there are other write methods like write-char and write-byte
(write-string "Hello")
(write-string “World")
‘ output Hello World
(write-line "Hello")
(write-line “World")
‘ output Hello
‘ World
(write "Hello")
‘ output Hello
24. Advanced Printing - format
• Allows string interpolation
(setq city "Bangalore")
(format t
"I like ~s as I live there. Current temp is ~s C"
city
(+ 10 20))
Output: I like "Bangalore" as I live there. Current temp is 30 C
25. Decision making (if)
• Has if condition (no else then keyword)
( if ‹condition expr›
‹if expr›
‹else or oterwise expr› )
> (if (> 2 3)
"bigger"
"smaller")
Output - "smaller"
(setq x 10)
(if (< x 10)
"x is less than 10" ;if x < 10 then returns this expression
"x is equal to or greater than 10") ;this is the else expression
Output - "x is equal to or greater than 10"
26. and
(define x 10)
(define y 20)
(if (and
(= x 10)
(= y 20))
"both conditions are true"
"false")
Output - "both conditions are true"
;next program
(define x 10)
(define y 20)
(define z 50)
(if (and
(= x 10)
(= y 20)
(= z 30))
"all conditions are true"
"all conditions are not true")
Output - "both conditions are not true"
27. or
(define x 10)
(define y 20)
(if (or
(= x 10)
(= y 10))
“one of the conditions is true"
“none of the conditions is true")
Output - "one of the condition is true"
;next program
(define x 10)
(define y 20)
(define z 50)
(if (or
(= x 15)
(= y 15)
(= z 15))
"one of the conditions is true"
"none of the conditions is true")
Output - " none of the conditions is true"
28. cond
• Allows multiple conditions
• Similar to switch case or select case
(define (check x)
(cond ((< x 0) "x is less than 0")
((= x 0) "x is equal to 0")
((> x 0) "x is greater 0")))
(check 10)
(check 0)
(check -10)
Output -
"x is greater 0"
"x is equal to 0"
"x is less than 0"
29. Data Structures - List
• List - core Lisp data structure (Lisp gets it’s name from List Processing)
Empty list: ()
> '(1 2 3 4)
(list 1 2 3 4)
> (cons 1 empty)
(1)
> (cons 1 (cons 2 empty))
(1 2)
> (list 1 2 3 4 5)
(list 1 2 3 4 5)
• A list can contain any data type
> (define lst (list 1 3 4 "Hello" 5 6 "Bangalore"))
> lst
(list 1 3 4 "Hello" 5 6 "Bangalore")
> (cons 1 (cons 2 (cons 3 (cons "Hello" (cons "World" (cons 4
empty))))))
(1 2 3 "Hello" "World" 4)
30. Data Structures - List
> (length lst) ; count the elements
7
> (list-ref lst 0) ; extract by position
1
> (list-ref lst 1)
3
> (list-ref lst 3)
"Hello"
> (list-ref lst 6)
"Bangalore"
> (reverse lst) ; reverse order
("Bangalore" 6 5 "Hello" 4 3 1)
> (append lst (list 7 8 9 "Kolkata")) ; combine lists
(1 3 4 "Hello" 5 6 "Bangalore" 7 8 9 "Kolkata")
> (member "Delhi" lst) ;check for an element
#f
> (member "Bangalore" lst)
("Bangalore")
31. List operations (car, cdr)
• car (pronounced kar) – returns the first element of the list
• cdr (pronounced kuder) – returns rest of the list without the first element.
• Alternatively called first and rest. In other languages typically called head
and tail
(define lst (list 1 3 4 "Hello" 5 6 "Bangalore"))
(car lst)
Output: 1
(cdr lst)
Output: (3 4 "Hello" 5 6 "Bangalore")
Lisp was originally implemented on the IBM 704 computer, in the late 1950s. The 704 hardware had special support
for splitting a 36-bit machine word into four parts, an "address part" and "decrement part" of 15 bits each and a
"prefix part" and "tag part" of three bits each.
- car (short for "Contents of the Address part of Register number")
- cdr ("Contents of the Decrement part of Register number")
http://en.wikipedia.org/wiki/CAR_and_CDR
1 3 4 Hello 5 6 Bangalore
car (head/first) cdr (tail/rest)
32. Moe List operations (cadr, cddr, caddr, caddr, …)
To get the second element from list – use cadr
(print (car (cdr lst)))
Alternately - (print (cadr lst))
Output: 3
All elements but first and second – use cddr
(print (cddr lst))
Output: (4 "Hello" 5 6 "Bangalore")
Third element , Forth Element -
(print (caddr lst))
Output: 4
(print (cadddr lst))
Output: "Hello"
1 3 4 Hello 5 6 Bangalore
car (head/first) cdr (tail/rest)
33. Moe List operations (cadr, cddr, caddr, caddr, …)
To get the first element from list – use first
(print (first lst)
Output: 1
To get the second element from list – use second
(print (second lst)
Output: 3
To get the third element from list – use third
(print (third lst)
Output: 4
To get the last element from list – use third
(print (last lst)
Output: “Bangalore”
1 3 4 Hello 5 6 Bangalore
first second third last
35. Associate List or alist (aka Object)
• Allows to keep key, value pairs.
• Very similar to Object
• Syntax is very similar to JavaScript object
(setf person '((first-name "Aniruddha")
(last-name "Chakrabarti")
(age 40)
(salary 123.456)))
(print person)
Output: ((FIRST-NAME "Aniruddha") (LAST-NAME "Chakrabarti") (AGE
40) (SALARY 123.456))
• Lisp provides a function, assoc, to retrieve information easily from
association lists given a retrieval key.
(print (assoc 'age person))
Output: (AGE 40)
(print (assoc 'first-name person))
Output: (FIRST-NAME "Aniruddha")
first-name Aniruddha
last-name Chakrabarti
age 40
salary 123.456
Person
36. Associate List (Cont’d)
(setf person '((first-name "Aniruddha")
(last-name "Chakrabarti")
(age 40)
(salary 123.456)))
(print person)
Output: ((FIRST-NAME "Aniruddha") (LAST-NAME "Chakrabarti") (AGE
40) (SALARY 123.456))
• rassoc, reverse assoc starts the matching from reverse direction
• copy-alist: returns a two-level deep copy of alist: it creates a new copy of
each association, so that you can alter the associations of the new alist
without changing the old one.
first-name Aniruddha
last-name Chakrabarti
age 40
salary 123.456
Person
37. Function Basics
• Functions are defined using defun statement
(defun <function name>(arg1 arg2 ... argN)
(statements))
(defun double (x) (* x 2))
(print (double 4))
8
(print (double 9.87))
19.74
(print (double "hello world"))
*** - *: "hello world" is not a number
(print (double (+ 3 5)))
16
(print (double (* 3 5)))
30
(defun printmessage (msg) (print msg))
(printmessage "Hello World")
"Hello World"
Parameter-less Function
(defun display_name ()
(print "Hello")
)
(display_name)
"Hello"
38. Function Basics
(defun add (a b)
(+ a b))
(add 10 20)
(add 10.345 20.456)
Output:
30
30.801000000000002
> (add 20 "hello")
. . +: contract violation
expected: number?
given: "hello"
argument position: 2nd
other arguments...:
20
39. Multiline Functions
(defun add (a b)
(setq res (+ a b))
(print res)
)
(add 20 30)
(add 10.345 20.456)
Output:
50
30.800999
40. Lambda Expression
• Lambda defines anonymous functions
• Function name is not declared while defining the method
((lambda (arg1 arg2 ... argN)
(statements)) value1 value2 ... valueN)
((lambda (x) (* x 2))10)
20
((lambda (x) (* x x))10)
100
((lambda (x y) (+ x y)) 10 20)
30
((lambda (x y) (* x y)) 10 20)
200
41. Structure
• Structures are one of the user-defined data type, which allows you to
combine data items of different kinds.
• Structures are used to represent a record.
• defstruct macro in LISP allows you to define an abstract record structure.
defstruct statement defines a new data type, with more than one member
for your program.
(defstruct employee
name
age
designation
salary
is-name
)
• An implicit function named make-employee is created, which is a
constructor - when invoked will create a data structure with four
components
name String
age Integer
designation String
salary Float
is-male Boolean