Title: CSC301CPE425SC433: Programming Languages
1CSC301/CPE425/SC433 Programming Languages
- Topic 3 Programming Paradigms
- Functional Programming (FP)
Paradigm - SubTopic 3.2 Example FP Language SCHEME
- Reference Louden, Ch. 11
2Topic 3.2 SCHEME
- Scheme
- Basic components
- Objects
- Binding forms lambda, let, define, set
- Data structures lists, vectors
- Functions primitive, user-defined
- b) Comparison of Functional and Imperative
Languages
3Functions
- Any function application is written in prefix
form - e.g.
- ( 10 20) 1020
- (/ ( ( 10 20) 5) 2) (1020) 5 / 2
(function_name arg1 arg2 arg3 )
f(10, 20)
g( )
h( )
4Objects
- Scheme (like LISP) is a language for symbolic
computation (AI applications) - Values are represented by symbolic expressions
(or S-expressions) - An expression is either
- atoms e.g. a, 1, hello world
- lists e.g. (a b c d), (hello world)
- Vector e.g. (a b c d)
5Binding Forms
- Syntactic forms used to bind or assign
identifiers - Lambda
- Let
- Definitions
- Assignments
6? - Calculus
- Developed by Alonzo Church
- Mathematical theory for anonymous functions
- A fundamental goal
- To describe what can be computed
- LISP is based on ?-calculus
7? - Function
- A mathematical function may be expressed in
?-form - e.g.
- The lambda form clearly shows which variables are
bound or free - e.g.
f(x) x 3 (?x . x3)
f(x) x 3a (?x . x3a)
8Lambda Expression in Scheme
(lambda (idspec) expr1 expr2 )
- Aka lambda expression
- Analogous to ?-calculus expressions
- idspec (list of the) formal parameters of
procedure - The expressions expr1, expr2, are evaluated in
sequence - Creates (returns) an anonymous procedure
9Lambda Expression in Scheme (contd)
f(x) x 3
f(x) x 3 x7
f(x) x x
x11
((lambda (f x) (f x x )) 11)
((lambda ( x) ( x x )) 11)
f( ) 3 4
nothing
((lambda ( ) ( 3 4)) )
10Lambda Expression in Scheme (contd)
((lambda (x) ((lambda (y) (- x y)) 15)) 20)
The variable x is free in the body of the inner
lambda expr, but its binding is found in the
local environment for the outer lambda expr
5
Global environment
?x . (?y . x-y 15) 20
X -15
Local environment 1 x
20 -15
int f1 (int x) int f2( int y)
return (x-y) f2(15)
public static void main ( ) Console.Write(out
put is 1, f1(20)
Local environment 2 y
11Local Binding using Let
- Temporary (local) binding of identifiers to
values in the body of let - Order of evaluation of val_, expr_ is at
discretion of Scheme implementation - Any free (i.e. unbound) variable appearing in
val1, val2, is looked up in a non-local
environment
(let ( (id1 val1) (id2 val2) ) expr1 expr2 )
12Local Binding using Let (contd)
- Examples
- (let ((a 2) (b 3))
- ( a b))
- (let ((sum ( 2 4)))
- ( sum sum))
- (let ((b 3))
- (let ((b 10) (c b))
- c))
Global environment
Local environment 1-a a, b
Local environment 1-b sum
Local environment 1-c b
Local environment 2 b, c
13Let and Lambda
- The let construct does not add any new semantic
facility to Scheme - Every let expression can be rewritten as a lambda
expression applied to arguments - (let ((x 3) (y ( 2 5))) ( x y))
((lambda (x y) ( x y)) 3 ( 2 5))
14Using Let
(let ( (id1 val1) (id2 val2) ) expr1 expr2 )
- Syntax is similar to let
- Behaves as though the successive bindings are in
nested let expressions - i.e. equivalent to
(let ((id1 val1)) (let ((id2 val2))
expr1 expr2 ) )
15(No Transcript)
16(let ((a 0) (lower (- a 3)) (upper (
a 4))) )
lower ?? upper ??
(let ((a 0) (let ((lower (- a 3))
(upper ( a 4))) )) )
a 0 lower -3 upper 4
(let ((a 0) (lower (- a 3)) (upper
( a 4))) )
a 0 lower -3 upper 4
17Definitions
- Binding of an identifier id to a value of expr
- Binding of an identifier id to a procedure
(define id expr)
(define (id idspec) expr1 expr2 )
equivalent to
(define id (lambda (idspec) expr1 expr2 ))
In short
Give a name to a lambda expression
(define id lambda_expression)
18Example Bindings
- e.g.
- (define a 2) top-level definition
- a 2
- (let ((b 3) (c 4)) ( b c)) 7
- b reference to undefined identifier b
- ( a a) 4
- (define (double x) ( 2 x))
- (double 3) 6
19Example Bindings (contd)
- e.g.
- (define add_b
- (let ((b 100))
- (lambda (x) ( x b))
- )
- )
- (let ((b 10)) (add_b 25)) 125
(define id (lambda (idspec) expr1 expr2 ))
20Example Bindings (contd)
- e.g.
- (define (func1 x)
- (define (func2 y) ( x y))
- (define (func3 x) (func2 ( 2 x)))
- (func3 x)
- )
- (func1 3) 9
(define id (lambda (idspec) expr1 expr2 ))
21Assignment
(set! id expr)
- Assign a new value to an existing identifier
- Imperative feature
- Before the assignment, the identifier must be
bound - example
(let ((x 3) (y 4)) (set! x 5) ( x y))
9
22Lists and Pairs
- The pair is the most fundamental object type in
Scheme - A pair is a record structure with two fields
called the car and cdr fields - Lists are built up from pairs
- Lists are ordered sequences of pairs linked to
the next by the cdr field - Linked list
- The elements of the list occupy the car field of
each pair
23Proper and Improper Lists
- Proper list
- The cdr of the last pair is the empty list ( )
- e.g. (a b c)
- Improper list
- The cdr of the last pair can be anything other
than the empty list ( ) - e.g. (a . b)
( )
Z
first pair
24Vectors
- Elements in a vector are accessed directly by
their positions in the vector - May have heterogeneous data
- Elements have indices from 0 to (length of
vector) 1 - A prefix n specifies the length of the vector
- Examples
- (a b c)
- (a a a) and 3(a a a) and 3(a) are equivalent
- (define v '(1 (a b) hello))
- (vector-ref v 1) (a b)
- (vector-length v) 3
25Data and Functions
- How do we represent data?
- e.g.
- ( 2 3) 5
- S-expression represents function application
- To prevent function evaluation, use quote
function - e.g.
- (quote ( 2 3)) or '( 2 3) ( 2 3)
26Data Type
A strongly-typed language is one in which each
variable has a single type associated with it,
and that type is known at compile time
- Scheme is weakly typed
- Aka dynamic typing
- Uses run-time type checking, i.e. a variable
assumes the type of the value bound to it during
run-time - (define (square x) ( x x))
- (square 3) 9
- (square 3.3) 10.8899999999999
- (square hello)
- expects type ltnumbergt as 1st argument, given
hello other arguments were hello
27Functions
- Function application
- S-expression is used to express function
applications - e.g.
- ( 6 9) 15
- (Anonymous) function definition is based on
lambda expression
(function_name param )
(lambda (idspec) expr1 expr2 )
28Functions (contd)
- Building a name to a function
- Use defined
- or
-
- example
- (define (add x y) ( x y))
- or
- (define add (lambda (x y) ( x y)))
(define (id idspec) ltfunction_bodygt)
(define id (lambda_expression))
29Built-in Functions List Operations
- Use car to return the first element of the list
- Use cdr to return the remaining of the list with
the first element removed - examples
- (car '(a b c)) a
- (cdr '(a b c)) (b c)
- (car '((a b) c d)) (a b)
- (cdr '(a)) nil
- (car (cdr '(a b c))) b
- (car '(cdr (a b c))) cdr
30Built-in Functions List Operations (contd)
- Abbreviate composition of car and cdr
applications - Example
- (cdr (cdr (car '((a b c) (d e)))))
- can be abbreviated as
- (cddar '((a b c) (d e))) (c)
31Built-in Functions List Operations (contd)
- cons creates a new pair
- Construct a list using cons
- Example
Z
(define Z (cons 'a (cons 'b (cons 'c '() )))) (a
b c)
32Built-in Functions List Operations (contd)
(cons 'a '(b c)) (a b c)
(cons '(a) '(b c)) ((a) b c)
33Cell Model Representation
(a (b (c) d))
34Built-in Functions List Operations (contd)
- Creating lists using list
- Return a list of objects
(list 'a 'b 'c) (cons 'a (cons 'b (cons 'c '()
)))
Examples (list) ( ) (list 1 2 3) (1 2
3) (list 1 '(2 3)) (1 (2 3)) (cons 1 (cons
'(2 3) '() )) (list 1 '(2 3) '() ) (1 (2 3)
()) (cons 1 (cons '(2 3) (cons '() '() )))
35Built-in Functions Vector Operations
Examples (vector) 0() (vector 1 2
3) 3(1 2 3) (vector 1 'a 3) 3(1 a
3) (make-vector 5) 5() (make-vector 5
\space) 5(\space) (vector? (1 2
3)) t (vector-length (1 2 3)) 3 (vector-ref
(10 20 30) 2) 30 (vector-fill! (10 20 30)
222) 3(222)
36Built-in Functions Predicates
- A predicate is a function whose result is always
t or f
Examples (even? 4) t (integer?
4) t (number? 14/3) t (null? '(1 2
3)) f (real? 4.3) t (string?
hello) t (eq? a 3) f use for
atoms (equal? '(1 3 4) '(1 3 4)) t use for
lists ( 3 4) f use for numbers
37Built-in Functions Numbers
- A number in Scheme can be exact or inexact
- Depends on the operations used to derive the
number and the inputs to these operations - An exact integer is normally written as a
sequence of numerals preceded by an optional sign - An exact rational number is normally written as
two sequences of numerals separated by a slash
and preceded by an optional sign - Inexact integers and rational numbers are
normally written in either floating-point or
scientific notation
38Built-in Functions Numbers (contd)
Examples (quotient 30 4) 7 (remainder 30
4) 2 (truncate 30/4) 7 (round
30/4) 8 (floor 30/4) 7 (ceiling
30/4) 8 (abs -30/4) 30/4 (numerator
30/4) 15 (denominator 30/4) 2 (max 4 -2 1 30
21) 30
39Built-in Functions Sequencing
- Begin
-
- Each expr is evaluated from left to right, in
sequence - Used to package a sequence of expressions into a
single expression
(begin ltexprgt )
(define (begin_ex) (define number 0)
(newline) (display Enter number) (set!
number (read)) (if (zero? number) (display
You enter 0.) (begin (display Number
is) (display number) ) ) )
(if ltpredicategt ltexpr_if_truegt
ltexpr_if_falsegt )
40Built-in Functions Conditionals
- Test function using if
- Test function using cond
(if ltpredicategt ltexpr_if_truegt
ltexpr_if_falsegt )
(let ((x 0)) (cond ((lt x 0) (list
'minus (abs x))) ((gt x 0) (list 'plus
x)) (else (list 'zero x)) ) )
(cond (lttest-1gt ltexpr-1gt) (lttest-2gt
ltexpr-2gt) (lttest-ngt ltexpr-ngt) (else
ltexpr-pgt) )
41Built-in Functions Conditionals (contd)
(case val (ltkey-1gt ltexpr-1gt) (ltkey-2gt
ltexpr-2gt) (else ltexpr-pgt) )
(let ((x 4) (y 5)) (case ( x y)
((1 3 5 7 9) 'odd) ((0 2 4 6 8) 'even)
(else 'out-of-range) ) )
42Built-in Functions Conditionals (contd)
(and expr )
- Evaluates each arg in sequence from left to right
and stops if any expr evaluates to false - Example
- (let ((x 3))
- (and (gt x 2) (lt x 4) ( x 5))) f
(or expr )
- Evaluates each arg in sequence from left to right
and stops if any expr evaluates to true - Example
- (let ((x 3))
- (or (gt x 2) (lt x 4) ( x 5))) t
43Built-in Functions Controls
(do ((id val update) ) (test res ) expr )
(define factorial (lambda (x) (do
( ( i x (- i 1)) initial value of i is
x, decrement i (a 1 ( a i)) initial
value of a is 1, a a i ) ((zero? i)
a) termination test if i 0, return a
) ) ) (factorial 3)
44Built-in Functions Controls (contd)
(map proc list1 list2)
- Applies proc to corresponding elements of the
lists list1, list2, - Each list1, list2, must have the same length
- Returns a list
Examples (map abs '(1 -2 3 -4)) (1 2 3
4) (map (lambda (x y) ( x y)) '(1 2) '(4 5)) (4
10)
45Built-in Functions Controls (contd)
(for-each proc list1 list2)
- Applies proc to corresponding elements of the
lists list1, list2, - Elements are processed in left-to-right sequence
- Does not return a list
- Mainly used for side-effects (e.g. display)
(let ((same-count 0)) (for-each (lambda (x
y) (cond (( x y) (set! same-count (
same-count 1))) ) ) '(1 2 3 4 5) '(2 4 5 7
0) ) same-count or (display same-count) )
46Recursive Functions
- Example to count number of elements in formal
parameter
(define (mylength list) (if (null? list)
0 ( 1 (mylength (cdr list)))
) )
mylength '(a (b c) d)
Function call (mylength '(a (b c) d)
47Recursive Functions (contd)
(define (factorial x) (cond ((lt x 0) ())
(( x 0) 1) (else ( x
(factorial (- x 1)))) ) )
factorial 3
Function call (factorial 3)
48Tail Recursion
- A call is tail-recursive
- If nothing has to be done after the call returns
- When the call returns, the returned value is
immediately returned from the calling function - A call is not tail-recursive
- If some operation is performed on the result of
the recursive call - Scheme guarantees to optimize tail recursion into
loops - So tail recursion does not build up any sort of
control stack that might be associated with
normal (not tail) recursion (which gives poor
performance)
49Tail Recursion (contd)
- Example factorial (tail-recursive version)
(define (factorial n) (define (fact result
n) (if (zero? n) result (fact ( result
n) (- n 1)) ) ) (fact 1 n) )
factorial 3
helper function
Function call (factorial 3)
50Tail Recursion (contd)
factorial 3
factorial 3
Non tail-recursive
6
3 factorial 2
2
2 factorial 1
1
1 factorial 0
Tail-recursive
51Topic 3.2 SCHEME
- Scheme
- Basic components
- Objects
- Binding forms lambda, let, define, set!
- Data structures lists, vectors
- Functions primitive, user-defined
- b) Comparison of Functional and Imperative
Languages
52Comparison of Functional and Imperative Languages
- Imperative languages
- Based on conventional computer
- More efficient in terms of execution time because
they reflect structure and operations of machines - Programmer must pay attention to machine level
details - Presence of side-effects
53Comparison of Functional and Imperative
Languages (contd)
- Functional languages
- Based on mathematical functions
- Allows (problem-oriented) design of data
structures without concern for memory cells - No mutation (or side effects)
- E.g. an object passed as an arg to a proc, a new
object is created but the original object remains
unchanged - Appears to be at a higher level than imperative
languages - Inefficient to execute due to numerous function
calls and dynamic object creation and
deallocation - Natural way of exploiting parallel machine
architecture
54Summary
- Scheme departs from functional model established
by FP in two ways - Use of variables concept with let, set!
- Ability to specify sequential execution of
functions - S-expression used for expressing function
applications in Scheme - Cell model used by Scheme to represent
S-expressions
55Summary (contd)
- Scheme constructs
- cons
- predicates
- car
- cdr
- let
- define
- lambda
56Lambda Expression in Scheme (contd)
(let ((a 2) (b 3)) ( a b))
int f1 (int a, int b) return (ab)
((lambda(a b) ( a b)) 2 3)
5
Global environment
public static void main ( ) Console.Write(out
put is 1, f1(2, 3)
Local environment 1 a 2 b 3
57Lambda Expression in Scheme (contd)
(let ((sum ( 2 4))) ( sum sum))
int f1 (int sum) return (sumsum)
36
((lambda(sum) ( 2 4)) ( sum sum) )
Global environment
public static void main ( ) Console.Write(out
put is 1, f1(24)
Local environment 1 sum 6
58Lambda Expression in Scheme (contd)
(let ((b 3)) (let ((b 10) (c b)) c))
public static void main ( ) Console.Write(out
put is 1, f1(3)
(let ((b 3)) (let ((z 10) (c b)) c))
Global environment
3
Local environment 1 b 3
int f1 (int b) int f2(int b, int c)
return (c) return f2(10, b)
z,
Local environment 2 z (renamed b), c note that
here z (renamed b) 10 c3
(let ((b 3)) (let ( (c b) (b 10) ) c))
59Lambda Expression in Scheme (contd)
(let ((a 0) (lower (- a 3)) (upper (
a 4))) )
int f1 (int a, int lower, int upper) return
()
Undefined lower , upper ..
((lambda (a lower upper)) 0 (- a 3) ( a 4))
Global environment a .. should have somevalue
here ..
Local environment 1 a0 lower upper
public static void main ( ) Console.Write(out
put is 1, f1(0, a-3, a4)
60Lambda Expression in Scheme (contd)
public static void main ( ) Console.Write(out
put is 1, f1(0)
(let ((a 0) (let ((lower (- a 3))
(upper ( a 4))) .. .. )) )
ok..
Global environment
Local environment 1 a 0
int f1 (int a) int f2(int lower, int
upper) .. .. return () return(
f2(a-3, a4) )
Local environment 2 lower -3 upper 4
61Lambda Expression in Scheme (contd)
public static void main ( ) Console.Write(out
put is 1, f1(0)
(let ((a 0)) (let ((lower (- a 3))) (let
(upper ( a 4))) ) )
(let ((a 0) (lower (- a 3)) (upper
( a 4))) )
Global environment
ok..
int f1 (int a) int f2(int lower)
int f3(int upper) return
() f3(a4)
f2(a-3)
Local environment 1 a 0
Local environment 2 lower -3
Local environment 3 upper 4
62Lambda Expression in Scheme (contd)
(let ((a 0) (lower (- a 3)) (upper
( a 4))) )
int f1 (int a, int lower, int upper) return
()
??? Undefined a ..
Global environment a .. should have somevalue
here ..
Local environment 1 a lower upper
public static void main ( ) Console.Write(out
put is 1, f1(0, a-3, a4)
((lambda (a lower upper)) 0 (- a 3) ( a 4))
63Local Binding using Let (contd)
- Examples
- (let ((a 2) (b 3))
- ( a b))
- (let ((sum ( 2 4)))
- ( sum sum))
- (let ((b 3))
- (let ((b 10) (c b))
- c))
Global environment
Local environment 1-a a, b
Local environment 1-b sum
Local environment 1-c b
Local environment 2 b, c
64Lambda Expression in Scheme (contd)
public static void main ( ) Console.Write(out
put is 1, f1(0)
(let ((a 0) (let ((lower (- a 3))
(upper ( a 4))) .. .. )) )
ok..
Global environment
((lambda (a (lambda (lower upper) ) (- a 3) ( a
4) ) 0)
Local environment 1 a 0
int f1 (int a) int f2(int lower, int
upper) .. .. return () return(
f2(a-3, a4) )
Local environment 2 lower -3 upper 4