Functional Programming I - National Chung Cheng University
Download
Report
Transcript Functional Programming I - National Chung Cheng University
Chapter 3
Functional Programming
Outline
Introduction to functional programming
Scheme: an untyped functional programming
language
Storage vs. Value
In imperative languages, stroage is visible:
variables are names of storage cells.
assignment changes the value in a storage cell.
explicit allocation and deallocation of storage.
computation is a sequence of updates to storage.
Functional languages manipulates values,
rather than storage. There is no notion of
storage in functional languages.
variables are names of values.
Assignment vs. Expression
In pure functional programming, there is no
assignment and each program (or function) is
an expression.
v == 0 ? u :
gcd(v, u % v);
(define gcd
(lambda (u v)
(if (= v 0) u
(gcd v (remainder u v))
)
)
)
Referential Transparency
Due to the lack of assignment, the value of a
function call depends only on the values of its
arguments.
gcd(9, 15)
There is no explicit notion of state.
This property makes the semantics of
functional programs particularly simple.
Loops vs. Recursion
Due to the lack of assignment, repetition
cannot be carried out through loops. A loop
must have a control variable that is
reassigned as the loop executes.
Repetition is carried out through recursion in
functional languages.
Functions as Values
In functional languages, functions are viewed
as values. They can be manipulated in
arbitrary ways without arbitrary restrictions.
Functions can be created and modified
dynamically during computation.
Functions are first-class values.
Higher-Order Functions
As other first-class values, functions can be
passed as arguments and returned as
values.
A function is called a higher-order function if it
has function parameters or returns functions.
Scheme: A Dialect of Lisp
The development of Lisp begins in 1958.
Lisp is based on the lambda calculus.
Lisp was called Lisp (List processor) because
its basic data structure is a list.
Unfortunately, no single standard evolved for
the Lisp language, and many different
dialects have been developed over the years.
Scheme is one of the dialects of Lisp.
Starting Scheme
We will use the MIT Scheme interpreter to
illustrate the features of Scheme.
When we start the MIT Scheme interpreter,
we will enter the Read-Eval-Print Loop (REPL)
of the interpreter.
It displays a prompt whenever it is waiting for
your input. You then type an expression.
Scheme evaluates the expression, prints the
result, and gives you a prompt.
An Example
1 ]=> 12
;Value: 12
1 ]=> foo
;Unbound variable: foo
;To continue, call RESTART with an option number:
; (RESTART 3) => Specify a value to use instead ...
; (RESTART 2) => Define foo to a given value.
; (RESTART 1) => Return to read-eval-print level 1.
2 error>
Leaving Scheme
You can leave Scheme by calling the
procedure exit.
1 ]=> (exit)
Kill Scheme (y or n)? y
Scheme Syntax
The syntax of Scheme is particularly simple:
expression atom | list
atom number | string | identifier
| character | boolean
list ‘(’ expression-sequence ‘)’
expression-sequence
expression expression-sequence
| expression
Some Examples
42
“hello”
hello
#\a
#t
(2.1 2.2 2.3)
(+ 2 3)
a number
a string
an identifier
a character
the Boolean value “true”
a list of numbers
a list consisting of an
identifier “+” and two
numbers
Scheme Semantics
A constant atom evaluates to itself.
An identifier evaluates to the value bound to it.
A list is evaluated by recursively evaluating
each element in the list as an expression (in
some unspecified order); the first expression
in the list evaluates to a function. This
function is then applied to the evaluated
values of the rest of the list.
Some Examples
1 ]=> 42
1 ]=> #t
;Value: 42
;Value: #t
1 ]=> “hello”
1 ]=> (+ 2 3)
;Value 1: “hello”
;Value: 5
1 ]=> #\a
1 ]=> (* (+ 2 3) (/ 6 2))
;Value: #\a
;Value: 15
Numerical Operations
The following are type predicates:
(number? x)
(complex? x)
(real? x)
(rational? x)
(integer? x)
;(number? 3+4i)
;(complex? 3+4i)
;(real? -0.25)
;(rational? 6/3)
;(integer? 3.0)
Numerical Operations
The following are relational operators:
(= x y z …)
(< x y z …)
(> x y z …)
(<= x y z …)
(>= x y z …)
Numerical Operations
The following are more predicates:
(zero? x)
(positive? x)
(negative? x)
(odd? x)
(even? x)
Numerical Operations
The following are arithmetic operators:
(+ x …)
(* x …)
(- x …)
(/ x …)
(max x y …)
(min x y …)
;(+ 3 4 5)
;(* 3 4 5)
;(- 3 4 5)
;(/ 3 4 5)
;(max 3 4 5)
;(min 3 4 5)
Numerical Operations
The following are arithmetic operators:
quotient
abs
gcd
ceiling
exp
remainder
numerator
lcm
truncate
log
modulo
denominator
floor
round
sqrt
Boolean Operations
The following are boolean operations:
(boolean? x)
(not x)
(and x …)
(or x …)
;(boolean? #f)
;(not 3)
;(and 3 4 5)
;(or 3 4 5)
Pairs
A pair (sometimes called a dotted pair) is a
record structure with two fields called the car
(contents of the address register) and cdr
(contents of the decrement register) fields.
(4 . 5)
x
car x
4
cdr x
5
Lists
Pairs are used primarily to represent lists. A
list is an empty list or a pair whose cdr is a list
()
(a . ())
(a . (b . ()))
; ()
; (a)
; (a b)
Literal Expressions
(quote x) evaluates to x.
(quote a)
(quote (+ 1 2))
;a
; (+ 1 2)
(quote x) may be abbreviated as ‘x.
‘a
‘(+ 1 2)
;a
; (+ 1 2)
List Operations
(cons x y)
; return a pair whose car
is x and cdr is y
(cons ‘a ‘(b c))
; (a b c)
(cons ‘(a) ‘(b c)) ; ((a) b c)
(car x)
; return the car field of x
(car ‘(a b c)); a
(car ‘((a) b c))
; (a)
(cdr x)
; return the cdr field of x
(cdr ‘(a b c)); (b c)
(cdr ‘((a) b c))
; (b c)
List Operations
(caar x)
(cadr x)
(pair? x)
(null? x)
(length x)
(list x …)
(append x …)
(reverse x)
; (caar ‘((a) b c))
; (cadr ‘((a) b c))
; (pair? ‘(a b c))
; (null? ‘(a b c))
; (length ‘(a b c))
; (list ‘a ‘b ‘c)
; (append ‘(a) ‘(b) ‘(c))
; (reverse ‘(a b c))
Conditionals
(if test consequent)
(if test consequent alternate)
(if (> 3 2) ‘yes ‘no)
(if (> 3 2) (- 3 2) (+ 3 2))
Special form
Evaluation of arguments are delayed
Conditionals
(cond (test1 expr1 …)
(test2 expr2 …)
…
(else expr …))
(cond ((> 3 2) ‘greater)
((< 3 2) ‘less)
(else ‘equal))
Function Definition
Functions can be defined using the function
define
(define (variable formals) body)
(define (gcd u v)
(if (= v 0) u
(gcd v (remainder u v))
)
)
An Example
(append ‘(1 2 3) ‘(4 5 6))
;(1 2 3 4 5 6)
(define (append x y)
(if (null? x) y
(cons (car x) (append (cdr x) y))
)
)
An Example
(reverse ‘(1 2 3))
; (3 2 1)
(define (reverse x)
(if (null? x) x
(append (reverse (cdr x))
(cons (car x) ‘()))
)
)
Tail Recursion
A recursion is called tail recursion if the
recursive call is the last operation in the
function definition.
(define (gcd u v)
(if (= v 0) u
(gcd v (remainder u v))
)
)
Scheme compiler or interpreter will optimize a
tail recursion into a loop.
An Example
(define (reverse x)
(if (null? x) x
(append (reverse (cdr x)) (cons (car x) ‘()))
)
)
(define (reverse x) (reverse1 x ‘()))
(define (reverse1 x y)
Accumulator
(if (null? x) y
(reverse1 (cdr x) (cons (car x) y)))
)
)
Lambda Expressions
The value of a function is represented as a
lambda expression.
(define (square x) (* x x))
(define square (lambda (x) (* x x)))
A lambda expression is also called an
anonymous function
An Example
(define gcd
(lambda (u v)
(if (= v 0) u
(gcd v (remainder u v))
)
)
)
Higher-Order Functions
The procedure (apply proc args) calls the
procedure proc with the elements of args as
the actual arguments. Args must be a list.
(apply + ‘(3 4))
;7
(apply (lambda (x) (* x x)) ‘(3))
;9
Higher-Order Functions
The procedure (map proc list1 list2 …)
applies the procedure proc element-wise to
the elements of the lists and returns a list of
the results.
(map cadr ‘((a b) (d e) (g h)))
; (b e h)
(map (lambda (x) (* x x)) ‘(1 2 3))
; (1 4 9)
Higher-Order Functions
An example of returning lambda expressions
is as follows:
(define (make-double f)
(lambda (x) (f x x)))
(define square (make-double *))
(square 2)
Equivalence Predicates
(eqv? obj1 obj2) returns #t if obj1 and obj2
are the same object
(eqv? ‘a ‘a)
(eqv? (cons 1 2) (cons 1 2)
(equal? obj1 obj2) returns #t if obj1 and obj2
print the same
(equal? ‘a ‘a)
(equal? (cons 1 2) (cons 1 2)
Input and Output
the function read reads a representation of an
object from the input and returns the object
(read)
the function write writes a representation of
an object to the output
(write object)
Load Programs
Functions and expressions in a file can be
loaded into the system via the function load
(load filename)
(load “C:\\user\\naiwei\\ex.txt”)