Functional Languages

Download Report

Transcript Functional Languages

COEN 171 - Functional Languages












Functional programming basics
Atoms and lists; cons
Useful primitive functions
Predicates
Arithmetic functions
Built-in functions
Constructing new functions
Temporary variable scopes
Control structures: if, case, iteration
Output
Debugging
Comparing functional and imperative languages
(5.1)
Functional Programming
(5.2)
 Recall the concept of a function from mathematics
– f(x) = x + 5
f(10) = 15
– g(x) = x / 3
g(10) = 3 1/3
– x is the parameter, everything to right of = is the definition
 Functions can be composed
– g(f(10)) = g(15) = 5
– f(g(10)) = f(3 1/3) = 8 1/3
 Pure functional programming follows this model: a
functional language provides
– a set of primitive functions
– a set of functional forms to construct complex functions from
the primitives
– an operation to apply functions
– some structure(s) for storing data
LISP and Variants
(5.3)
 LISP is the most widely available example of a functional
language
 Original MIT LISP spawned host of variants
 Most widely available now are
– Common LISP
– Scheme
» static scoping
» dynamic typing
 Function calls are expressed in “Cambridge Polish”
– (function-name arg1 arg2 arg3)
 In LISP, everything is evaluated unless the programmer
explicitly says not to
Atoms and Lists
(5.4)
 An atom is
– a symbol
» a string of letters or digits, not starting with a digit and not
including spaces or parentheses
– an integer
– a real number
– nil
» the Boolean false value
» the empty list
 A list is a sequence of atoms and lists surrounded by ( )
and separated by blanks
– (John Mary)
– (foo (John Mary) 115)
(5.5)
Atoms and Lists (continued)
 Lists are composed of nodes,
or conses, each of which has
a CAR and a CDR
 A list is a chain of nodes,
each of whose CDRs is either
another list or the empty list
CAR
CDR
– the CARs of the nodes of a
list are the elements of the list
 A dotted list has a last node
whose CDR is not nil
– we’ll generally deal only with
“true lists” ending with a nil
CDR
John
Mary
(5.6)
Primitive Functions
 QUOTE is a primitive function to avoid evaluation
–
–
–
–
essentially makes something a literal
(QUOTE (A B C)) returns a list (A B C)
(QUOTE A) returns an atom A
usually abbreviated ‘A ‘(A B C)
 CONS builds a node: the first argument becomes the CAR and the
second becomes the CDR
– (CONS ‘A ‘B)
A
B
– (CONS ‘A ‘(B C))
A
B
C
(5.7)
Primitive Functions (continued)
 CONS (continued)
– (CONS ‘(A B) ‘(C D))
– ((A B) C D)
 CONS can be composed
– (CONS ‘A
–
(CONS (CONS ‘B
–
(CONS ‘C nil))
–
(CONS ‘D nil)))
– (A (B C) D)
C
A
D
B
 LIST avoids dotted pair
problem of previous slide
– (LIST ‘A ‘B)
A
A
B
D
B
C
Primitive Functions (continued)
(5.8)
 CONS and LIST build lists
 Also need functions to retrieve components of list
 CAR returns the CAR of the argument list
– (CAR (CONS ‘(A B) ‘(C D))
– (A B)
 CDR returns the CDR of the argument list
– (CDR (CONS ‘(A B) ‘(C D))
– (C D)
 Also want a way to assign a name to a list
–
–
–
–
–
–
(DEFINE LIST1 (CONS ‘A (CONS (CONS ‘B (CONS ‘C nil))
(CONS ‘D nil))))
(A (B C) D)
(DEFINE LIST2 ())
(SET! LIST2 (CONS ‘(A B) ‘(C D)))
((A B) C D)
(5.9)
Primitive Functions (continued)
 CAR and CDR can also be
composed, and there is even
a shorthand notation
–
–
–
–
–
(CDR (CDR LIST2))
(D)
(CDDR LIST2)
(CADADR LIST1)
C
 Works for up to 4
compositions
 NOTE that SET! violates the
definition of the pure
functional model
C
A
B
A
LIST1
D
LIST2
D
B
C
Predicates
(5.10)
 Predicates are LISP primitive functions that return a true or
false value
– in Scheme, false is #f, everything else is true
– in Common LISP, false is nil, everything else is true
 By convention, predicates usually have names that end in
P (Common LISP) or ? (Scheme)
–
–
–
–
–
–
–
–
(atom? X) returns true if X is an atom
(list? X) returns true if X is a list
(number? X) returns true if X is a numeric value
(zero? X)
(positive? X)
(negative? X)
(null? X) returns true if X = nil
(not X) performs a Boolean negation of the value in X
Arithmetic Functions
 Operations
–
–
–
–
–
–
–
(+ X Y) or (+ X Y Z ... W)
(- X Y)
X -Y
(* X Y) or (* X Y Z ... W)
(/ X Y)
X / Y
(remainder X Y)
(modulo X Y)
(abs X)
 Testing
– (EQ? X Y) returns true if X and Y are the same object
– (EQUAL? X Y) returns true if X and Y print out the same
» (EQUAL 2 2.0) returns #f
– (= X Y) return true based on numeric equality
» also <, <=, >, >=
(5.11)
Useful Built-in Functions
(5.12)
 List manipulations
– (LENGTH X) returns number of top level nodes in list X
» (LENGTH LIST1) returns 3
– (LAST X) returns last cons cell at top level of list X
» (LAST LIST1) returns (D)
– (FIRST X) returns first element of list X
» similarly SECOND, ..., TENTH
– (LIST-REF X num) returns the (num)th element of list X, where
the first element has index 0
– (APPEND X Y ... Z) copies all the lists except the last and
returns a list with the copy of X followed by the copy of Y
followed by... followed by the original of Z
– (APPEND! X Y ... Z) appends lists without copying
» not a part of standard Scheme
– (REVERSE X) returns a copy of list X with top level reversed
» (REVERSE! X) reverses without copying
Constructing New Functions
(5.13)
 (DEFINE (name param1 ... paramk) expr1 ... expn )
– defines a new function name with arguments param1 to
paramk, with “body” expr1 to expn; value returned is last
expression evaluated
– parameter values are not changed
– (DEFINE (second L) (CAR (CDR L)))
»
»
»
»
returns the CAR of the second top level node in L
(DEFINE X ‘(A B C D))
(SECOND X)
returns B
 Then writing a program in LISP consists of defining
functions which use the built-in functions, which in turn are
called by higher level definitions, until the top level
program is a single function call
Temporary Variable Scopes
 LET is the Scheme mechanism for temporarily binding
values to names
– (LET (
–
(name_1 expression_1)
–
(name_2 expression_2)
–
<S-expressions>
–
))
 Evaluate expression_i and bind result to name_i
 Name_1 and name_2 can only be used in the <Sexpressions> in the body of the LET
– static scoping
– name_i can’t have a different value assigned
(5.14)
Conditional Control Structures
(5.15)
 COND is like a nested if-then-else
– COND has sets of (logical predicate) (expression) pairs
– each predicate is evaluated in turn, first one that’s true has
expression executed and value returned as result
– (DEFINE (factorial N)
–
(COND ((< N 0) nil)
–
((= N 1) 1)
–
(ELSE (* N (factorial (- N 1))))))
» expressions can be expression sequences
 IF is a simple if-then or if-then-else
– (IF (ZERO? X) (+ Y X) (/ Y X))
» then or else clause can be sequences using begin
» (IF (ZERO? X) (BEGIN (+ X 1) (+ Y X)) (/ Y X))
(5.16)
Conditional Control Structures (continued)
 Logical connectives
– (AND expr1 expr2 expr3 ...) evaluates the expressions in
turn until #f is found [one is false]; if never found, result of last
expression evaluation is returned
» (AND (= 2 2) (> 2 1)) returns #t
» (AND (= 2 2) (< 2 1)) returns #f
– (OR expr1 expr2 expr3 ...) works same way except
evaluation stops when first #t result is found; if never found,
return result of last expression evaluation
» (OR (= 2 2) (< 2 1)) returns #t
(5.17)
Example
(DEFINE (MEMBER ATM LIS)
(COND ((NULL? LIS) #f)
((EQ? ATM (CAR LIS)) #t)
(ELSE (MEMBER ATM (CDR LIS)))))
(DEFINE (MYST LIST1 LIST2)
(COND ((NULL? LIST1) ())
((MEMBER (CAR LIST1) LIST2)
(CONS (CAR LIST1)
(MYST (CDR LIST1) LIST2)))
(ELSE (MYST (CDR LIST1) LIST2))))
(5.18)
Iteration
 DO is an iteration construct that allows for local variables
 (DO ((var init step)...) (test expr1 expr2 ...) body1...)
– assign all init values to vars
– evaluate test
» if true, evaluate expr1, expr2...; return value of last expr as
value of DO and terminate
» if false, evaluate body1, body2,...; evaluate step expressions
and assign to vars; re-evaluate test
 Example
(DEFINE (POWER M N)
(DO ((RESULT 1 (* M RESULT))
(EXPON N (- EXPON 1)))
)
)
((ZERO? EXPON) RESULT)
; NOTE NO BODY!!
Output
 (NEWLINE) skips to beginning of new line
 (DISPLAY EXPRESSION) outputs value of expression
 To record screen output
– (TRANSCRIPT-ON “filename”)
– (TRANSCRIPT-OFF) stops recording
(5.19)
Debugging Helps
(5.20)
 (LOAD “filename”) loads a text file into Scheme
 (DEBUG) invokes debugger after error
 (TRACE function-name) traces entry and exit from function
named
– (TRACE-ENTRY) or (TRACE-EXIT) trace one or the other
– (UNTRACE function-name) stops tracing
 (BREAK function-name) causes a breakpoint on entry to
and exit from function named
–
–
–
–
–
(BREAK-ENTRY) and (BREAK-EXIT) break on one or the other
(UNBREAK function-name) kills breakpoint
once
(*args*) gets value of arguments to function
(*result*) shows value about to be returned at exit broken
(PROCEED) continues after breakpoint
 (EXIT) leaves Scheme
– or (QUIT)
Scheme Examples
(5.21)
(DEFINE (roulette-wheel bet-1 bet-2)
(compare-with-bet (RANDOM 37) bet-1 bet-2))
(DEFINE (compare-with-bet wheel-spin bet-1 bet-2)
(IF (OR (= wheel-spin bet-1) (= wheel-spin bet-2))
(DISPLAY “You won! ”)
(DISPLAY “You lost! “))
wheel-spin)
(RANDOM X) is a built-in function that returns
a value between 0 and X
(compare-with-bet) returns wheel-spin as a
value (the last s-expression evaluated)
Scheme Examples (continued)
(5.22)
(DEFINE (leap-year? year)
(COND ((divisible? year 400) #t)
((divisible? year 100) #f)
((divisible? year 4) #t)
(ELSE #f)))
(DEFINE (length list-of-objects)
(COND ((NULL? list-of-objects) 0)
(ELSE (1+ (length (CDR list-of-objects))))))
Scheme Examples (continued)
(5.23)
(DEFINE (maximum list-nums)
(COND ((NULL? (CDR list-nums))(CAR list-nums))
(ELSE (LET ((maxtail (maximum (CDR list-nums)))
(first (CAR list-nums)))
(IF (> first maxtail)
first
maxtail)))))
use recursion to find maximum value in CDR of list, compare
to first value in list - maximum is larger of those two
Scheme Examples (continued)
(DEFINE (inc-list list-nums)
(COND ((NULL? list-nums) NIL)
(ELSE (CONS (1+ (CAR list-nums))
(inc-list (CDR list-nums))
)
)
)
)
returns a new list containing all the values of the
argument list incremented by 1
(5.24)
(5.25)
Comparing Functional and Imperative PLs
 Functional languages eliminate consideration of variable
allocation and assignment
– programming at higher level
– some reduction in execution efficiency
 Functional languages have simpler (and more uniform)
syntax
– only problems are when imperative features (DO) creep in
 Simpler to deal with concurrent execution
 Much more limited number of trained programmers for
functional languages, fewer commercial tools
Executing Scheme Programs
 Design Center
– type scheme at system prompt
» invokes DrScheme programming environment
– helpme has good information
 Get your own copy
– www.cs.indiana.edu/scheme-repository/imp.html
– particularly DrScheme or MIT Scheme
(5.26)