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. , ALGOL, COBOL, BASIC, Pascal, /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 associated with 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 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.: – data structures – automatic storage management – dynamic typing – the self-hosting

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 - evaluate LISP expressions • Two 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 – • Application as scripting languages: – Lisp in the Emacs editor – Visual Lisp in AutoCAD

– Nyquist in Audacity LISP 17 Introduction

Common Lisp: • a successor to • 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 for multithreaded programming • a compiled language (directly to JVM ) remains completely dynamic • every feature is supported 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 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 minimalist design • a much smaller set of standard features • certain implementation features: – -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 • 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 ) 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, , 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 # 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? • 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 – : – 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