LISP - "LISt Processing"
PhD MEng Tomasz Białaszewski Department of Decision Systems
Email: [email protected] http://www.eti.pg.gda.pl/katedry/ksd/pracownicy/Tomasz.Bialaszewski/
LISP 1 Introduction
Types of computer programming languages
Programming
Imperative Declarative
Functional Logical
LISP 2 Introduction
Imperative programming: • strongly associated with computer architecture (von Neuman model) • computation in terms of statements that change a program state • sequences of commands for the computer to perform • e.g. FORTRAN, ALGOL, COBOL, BASIC, Pascal, C/C++, JAVA, PHP
LISP 3 Introduction
Declarative programming: • what the program should accomplish without prescribing how to do it • clear correspondence to mathematical logic • lack side effects • funcional and logical programming
LISP 4 Introduction
Logic programming: • logic is used as a purely declarative representation language • Prolog is a general purpose logic programming language associated with artificial intelligence and computational linguistics • a program logic is expressed in terms of relations, represented as facts and rules
LISP 5 Introduction
Functional programming: • computation as the evaluation of mathematical functions • avoidance of state and mutable data • lambda calculus (λ-calculus) - a formal system designed to investigate functions and recursion
LISP 6 Introduction
λ-calculus (A. Church & S. C. Kleene, 1930): • a powerful and elegant model of computation • an idealized, minimalist programming language • abstraction for modeling computation (cousin of the Turing machine) • stateless
LISP 7 Introduction (λ-calculus) • produce no side effects in 'state‘ • do not make alterations to incoming data • only three basic constructs: – definition – assignment – application • two special operators: – the ‘λ’ sign – the dot ‘’ LISP 8 Introduction (λ-calculus)
Defintion of a function: λ x . Body A function which takes a single argument x, evaluates the body - usually an expression using x - and returns the result. Example. Defined doubles the value of the argument x and then adds 3: λ x . 2*x+3
LISP 9 Introduction
LISP - LISt Processing (John McCarthy, 1958): • a family of computer programming languages • fully parenthesized syntax • second-oldest high-level programming language in widespread use today • lists are one of major data structures • source code is itself made up of lists
LISP 10 Introduction (LISP)
• a practical mathematical notation for computer programs (λ-calculus) • favored programming language for artificial intelligence (AI) research e.g.: – tree data structures – automatic storage management – dynamic typing – the self-hosting compiler
LISP 11 Introduction (LISP)
LISP program code: • a data structure • s-expressions, or parenthesized lists • a list with the function or operator's name first, and the arguments following (f arg1 arg2 arg3)
LISP 12 Introduction (LISP)
• First implementation: – Steve Russell on an IBM 704 computer • LISP interpreter - evaluate LISP expressions • Two assembly language macros for IBM 704 - primitive operations for lists: – car (Contents of the Address part of Register number) – cdr (Contents of the Decrement part of Register number)
LISP 13 Introduction (LISP)
• the term „Register” is used here to mean „Memory Register” („Memory Location”) • Lisp dialects still use car and cdr (pronounced /ˈkɑr/ and /ˈkʊdər/) • for the operations: – car returns the first item in a list – cdr returns the rest of the list
LISP 14 Introduction (LISP)
• a difficult system to implement with the compiler techniques and stock hardware of the 1970s • garbage collection routines (Daniel Edwards) – practical to run LISP on general-purpose computing systems – efficiency was still a problem • LISP machines: – dedicated hardware for running LISP environments and programs
LISP 15 Introduction
• LISP machines commercially pioneered many now-commonplace technologies: – effective garbage collection – laser printing – windowing systems – computer mice – high-resolution bit-mapped graphics – computer graphic rendering
LISP 16 Introduction • A LISP dialects - many variations on the core theme of S-expression language • The major dialects of Lisp: – Scheme – Common Lisp – Clojure • Application as scripting languages: – Emacs Lisp in the Emacs editor – Visual Lisp in AutoCAD
– Nyquist in Audacity LISP 17 Introduction
Common Lisp: • a successor to MacLisp • a large language standard including many built-in data types, functions, macros etc. • an object system (Common Lisp Object System, CLOS) • borrowed certain features from Scheme such as lexical scoping and lexical closures LISP 18 Introduction
Clojure: • a dynamic programming dialect of Lisp that targets the Java Virtual Machine (and CLR ) • a scripting language for multithreaded programming • a compiled language (directly to JVM bytecode) remains completely dynamic • every feature is supported at runtime LISP 19 Introduction
Scheme (1975, Gerald Sussman & Guy Steele Jr.) • first dialect of LISP to fully support: – lexical scoping – first-class procedures and – continuations • in earliest form - a very small language intended primarily for research and teaching • supporting only a handful of predefined syntactic forms and procedures LISP 20 Introduction (Scheme)
• early implementations of the language were interpreter-based and slow • some current Scheme implementations boast sophisticated compilers that generate code on par with code generated by the best optimizing compilers for lower-level languages such as C and Fortran
LISP 21 Introduction (Scheme)
• a more minimalist design • a much smaller set of standard features • certain implementation features: – tail-call optimization – full continuations (not necessarily found in Common Lisp) • a statically scoped and properly tail-recursive dialect of the Lisp programming language
LISP 22 Introduction (Scheme)
• an exceptionally clear and simple semantics • few different ways to form expressions • a wide variety of programming paradigms including: – imperative – functional – message passing styles • find convenient expression in Scheme
LISP 23 Introduction (Scheme)
• interpreter makes it particularly popular for embedded scripting: – SIOD and TinyScheme in the GIMP image processor („Script-fu“) – LIBREP (originally based on the Emacs Lisp) in the Sawfish window manager – Guile interpreter is used in GnuCash
LISP 24 Scheme Syntax
Scheme programs are made up of: • keywords • variables • structured forms • constant data (numbers, characters, strings, quoted vectors, quoted lists or symbols, etc.) • whitespace • comments
LISP 25 Scheme Syntax
Identifiers (keywords, variables, and symbols ) - formed from the set of characters: • the lower-case letters a through z • the upper-case letters A through Z • the digits 0 through 9 • the characters ?!.+-*/<=>:$%^&_~@
LISP 26 Scheme Syntax
Identifiers cannot start with : • @ • any character that may start a number, i.e.: – a digit – plus sign ( + ) – minus sign ( - ) – or decimal point ( . ) Exceptions: +, -, ..., which are valid identifiers For example: hi, Hello, x, x3, ?$&*!!!
LISP 27 Scheme Syntax
Identifiers must be delimited by: • whitespace • parentheses • a string (double) quote ( " ) • the comment character ( ; ) Notice: all implementations must recognize as identifiers any sequences of characters that adhere to these rules
LISP 28 Scheme Syntax
• No limit on the length of a identifier • Usage as many characters as necessary • Identifiers may be written in any mix of upper- case and lower-case letters • The case is not important, in that two identifiers differing only in case are identical For example: abcde, Abcde, AbCdE, ABCDE all refer to the same identifier LISP 29 Scheme Syntax
• Scheme systems typically print an identifier in either all upper-case or all lower-case letters regardless of the way it is entered • Structured forms and list constants are enclosed within parentheses, e.g.: (a b c) (* (- x 2) y) • The empty list is written ()
LISP 30 Scheme Syntax
• Some implementations permit the use of brackets ([]) in place of parentheses, and brackets are sometimes used to set off particular subexpressions for readability • The boolean values representing true and false are written as #t and #f • Scheme conditional expressions actually treat #f as false and all other objects as true, so 3, (), "false", and nil all count as true.
LISP 31 Scheme Syntax
• Vectors - #(a vector of symbols) • Strings - "This is a string" • Characters are preceded by #\, e.g., #\a • Case is important within character and string constants, unlike within identifiers • Numbers: - 12, 1/2, 1.4, 1e2456, 1.3777-2.7i, -1.2@73
LISP 32 Scheme Syntax
• Expressions may span several lines, and no explicit terminator is required • Since the number of whitespace characters (spaces and newlines) between expressions is not significant • Scheme programs are normally indented to show the structure of the code in a way that is pleasing to the author of the program
LISP 33 Scheme Syntax
Comments: • between a semicolon( ; ) and line end • placed at the same indentation level as the expression, on the line before the expression • explaining of procedures are normally placed before the procedures, without indentation • used to set off the latter kind of comment, e.g. ;;; The following procedures
LISP 34 Scheme Naming Convention
• Predicate names end in a question mark ( ? ) For example: eq?, zero?, and string? • Type predicate is created from the type name • The names of procedures start with the prefix char-, string-, vector- , list- e.g., string-append
LISP 35 Interacting with Scheme
• The simplest interaction with Scheme follows a "read-evaluate-print" cycle • A program (often called a read-evaluate-print loop, or REPL) • A program reads each expression you type at the keyboard, evaluates it, and prints its value.
LISP 36 Simple Expressions
• Numbers are constants: 12345678784978 12345678784978 3/4 3/4 3.141592653 3.141592653 2.2+1.1i 2.2+1.1i 7/2 3½ 1.14e-10 1.14e-010
LISP 37 Simple Expressions
• Arithmetic procedures +, - , *, / (+ 1/2 1.2 3/4) 2.45
(- 1/2 5/6 3/4) -111/12 (* 3 -2/3 5/4) -21/2 (/ 3 -2.5 5/4) -0.96 • Scheme employs prefix notation (procedure arg1 arg2 … argn)
LISP 38 Simple Expressions
• Nested procedures
(+(+ 2 2)(+ 2 2)) 8
(- 2 (* 4 1/3)) 2/3
(* 2 (* 2 (* 2 (* 2 2)))) 32
(/(* 6/7 7/2)(- 4.5 1.5)) 1.0
LISP 39 Simple Expressions
List: • basic aggregate data structure • objects sequences of surrounded by ( … ) e.g.: (1 2 3 4 5) ;list of numbers ("a" "list") ;strings list (4.2 "hi") ;a valid list ((1 2) (3 4)) ;a nested list
LISP 40 Simple Expressions
Question: How does Scheme distinguish between a list of objects
(obj1 obj2 ...) and a procedure application (procedure arg ...)? Answer: We must tell Scheme explicitly to treat a list as data rather than as a procedure application d LISP 41 Simple Expressions
• The quote forces a list to be treated as data (quote (1 2 3 4)) (1 2 3 4) (quote ("a" "bb")) ("a" "bb") (quote (+ 3 4)) (+ 3 4) • Quotation mark (') - abbreviation for quote '(1 2 3 4) (1 2 3 4) '((1 2)(3 4)) ((1 2)(3 4)) '(/ (* 2 -1) 3) (/ (* 2 -1) 3)
LISP 42 Simple Expressions
• A quote expression: – is not a procedure application – inhibits the evaluation of its subexpression – is an entirely different syntactic form • Scheme supports several other syntactic forms • Each syntactic form is evaluated differently
LISP 43 Simple Expressions
Example (quote hello) hello • Symbol hello must be quoted in order to prevent Scheme from treating hello as a variable • Symbols and variables in Scheme are similar to symbols and variables in mathematical expressions and equations
LISP 44 Simple Expressions
• Quoting a list tells Scheme to treat a parenthesized form as a list rather than as a procedure application • Quoting an identifier tells Scheme to treat the identifier as a symbol rather than as a variable • Symbols are commonly used to: – represent variables in symbolic representations of equations or programs – as words in the representation of natural language
sentences. LISP 45 Simple Expressions
• Scheme procedures for manipulating lists: – car (the first element of a list) – cdr (the remainder of the list) Each requires a nonempty list as its argument • For example: (car '(a b c)) a (cdr '(a b c)) (b c) (cdr '(a)) ()
LISP 46 Simple Expressions
• For example: (car (cdr '(a b c))) b
(cdr (cdr '(a b c))) (c) (car '((a b) (c d))) (a b) (cdr '((a b) (c d))) ((c d))
LISP 47 Simple Expressions
• The procedure for constraction of a list – cons: – Requires a two arguments – Adding an element to the beginning of a list – Referred to as consing the element onto the list (cons 'a '()) (a) (cons 'a '(b c)) (a b c) (cons 'a (cons 'b ())) (a b) (cons '(a b) '(c d)) ((a b) c d) LISP 48 Simple Expressions
• Examplary of cons procedure call (car (cons 'a '(b c))) a (cdr (cons 'a '(b c))) (b c) (cons (car '(a b c)) (cdr '(d e f))) (a e f) (cons (car '(a b c)) (cdr '(a b c))) (a b c)
LISP 49 Simple Expressions
• Remarks for cons: – The procedure cons actually builds pairs – The cdr of a pair need not be a list • A list is a sequence of pairs • Each pair's cdr is the next pair in sequence
a b c d ()
LISP 50 Simple Expressions
• Proper list – the cdr of the last pair in a list is the empty list – the empty list is a proper list – any pair whose cdr is a proper list is a proper list • Improper list – An improper list is printed in dotted-pair notation (cons 'a 'b) (a . b) (cdr '(a . b)) b (cons 'a '(b . c)) (a b . c) LISP 51 Simple Expressions
• Dotted pair - a pair whose cdr is not a list • Proper lists always is printed without dots '(a . (b . (c . ()))) (a b c) • The procedure list (similar to cons) – takes an arbitrary number of arguments – always builds a proper list (list 'a 'b 'c) (a b c) (list 'a) (a) (list) () LISP 52