Presentation is loading. Please wait.

Presentation is loading. Please wait.

Chapter 15: Functional Programming Languages

Similar presentations


Presentation on theme: "Chapter 15: Functional Programming Languages"— Presentation transcript:

1 Chapter 15: Functional Programming Languages
Introduction Mathematical Functions Fundamentals of Functional Programming Languages (FPL) Introduction to Scheme COMMON LISP ML Applications of Functional Languages Comparison of Functional and Imperative Languages

2 Introduction The design of the imperative languages is based directly on the von Neumann architecture Efficiency is the primary concern, rather than the suitability of the language for software development The design of the functional languages is based on mathematical functions A solid theoretical basis that is also closer to the user, but relatively unconcerned with the architecture of the machines on which programs will run

3 Mathematical Functions
A mathematical function is a mapping of members of one set, called the domain set, to another set, called the range set A lambda expression (nameless function) specifies the parameter(s) and the mapping of a function in the following form (x) x * x * x for the function cube (x) = x * x * x Lambda expressions are applied to parameter(s) by placing the parameter(s) after the expression e.g., ((x) x * x * x)(2) which evaluates to 8

4 Functional Forms A higher-order function, or functional form, is one that either takes functions as parameters or yields a function as its result, or both Function composition Apply-to-all

5 Function Composition A functional form that takes two functions as parameters, and yields a function whose value is the first actual parameter function applied to the result of the second Form: h  f ° g which means h (x)  f ( g ( x)) For f (x)  x + 2 and g (x)  3 * x, h  f ° g yields (3 * x)+ 2

6 Apply-to-all A functional form that takes a single function as a parameter, and yields a list of values obtained by applying the given function to each element of a list of parameters Form:  For h (x)  x * x ( h, (2, 3, 4)) yields (4, 9, 16)

7 Fundamentals of Functional Programming Languages
The objective of the design of a FPL is to mimic mathematical functions to the greatest extent possible In an imperative language, operations are done and the results are stored in variables for later use Management of variables is a constant concern and source of complexity for imperative programming In an FPL variables are not necessary, as is the case in mathematics The simplicity and power of functional languages is due to properties like pure values, first-class functions, and implicit storage management.

8 LISP Data Types and Structures
Data object types: originally only atoms and lists List form: parenthesized collections of sublists and/or atoms e.g., (A (B C) D (E (F G)))

9 LISP Interpretation Lambda notation is used to specify function definitions. Function applications and data have the same form. e.g., for the list (A B C) interpreted as data it is a simple list of three atoms, A, B, and C interpreted as a function application, it means that the function named A is applied to the two parameters, B and C The first LISP interpreter basically a universal function that could evaluate any other function. Dynamic scoping

10 Origins of Scheme A mid-1970s dialect of LISP, designed to be a cleaner, more modern, and simpler version than the contemporary dialects of LISP Uses only static scoping Functions are first-class entities They can be the values of expressions and elements of lists They can be assigned to variables and passed as parameters

11 Function Evaluation Parameters are evaluated, in no particular order
The values of the parameters are substituted into the function body The function body is evaluated The value of the last expression in the body is the value of the function Will discuss this more on Page 56.

12 How to write an expression
Use prefix notation, in which parentheses surround an operator and its operands. e.g., ( * 3 5 ) 15 The operators “+” and “*” could have several arguments, e.g., ( ) 10 Expressions with several operators are processed by following the subexpession structure, e.g., ( + 4 ( * 5 7 ) ) 39

13 Primitive Functions Arithmetic: +, -, *, /, ABS, SQRT, REMAINDER, MIN, MAX QUOTE: takes one parameter; returns the parameter without evaluation QUOTE is required because the Scheme interpreter, named EVAL, always evaluates parameters to function applications before applying the function. QUOTE is used to avoid parameter evaluation when it is not appropriate QUOTE can be abbreviated with the apostrophe prefix operator '(A B) is equivalent to (QUOTE (A B))

14 Function Definition: LAMBDA
Lambda Expressions: anonymous function (unnamed function) Form is based on  notation e.g., (LAMBDA (x) (* x x)) x is called a bound variable Lambda expressions can be applied e.g., ((LAMBDA (x) (* x x)) 7) Recursion is not supported since there is no name.

15 Special Form Function: DEFINE
A Function for Constructing Functions DEFINE To bind a symbol to an expression e.g., (DEFINE pi ) Example use: (DEFINE two_pi (* 2 pi)) Note: pi ‘pi pi To bind names to lambda expressions ( define ( <function-name> <formal-parameters>) <expression> ) e.g., (DEFINE (square x) (* x x)) Example use: (square 5) 25

16 Functions provided in Scheme
Output Functions (DISPLAY expression) (NEWLINE) Numeric Predicate Functions Operator: =, <>, >, <, >=, <= names ending in ``?’’: EVEN?, ODD?, ZERO?, NEGATIVE? Two boolean values: #T is true: any non-null list () is false (課本用 #F )

17 Control Flow: IF Selection: IF (IF predicate then_exp else_exp) e.g.,
(IF (<> count 0) (/ sum count) 0)

18 Control Flow: COND Multiple Selection: COND
(predicate_1 expr {expr}) ... (ELSE expr {expr})) Returns the value of the last expr in the first pair whose predicate evaluates to true Example: (DEFINE (compare x y) ((> x y) (DISPLAY “x is greater than y”)) ((< x y) (DISPLAY “y is greater than x”)) (ELSE (DISPLAY “x and y are equal”)) )

19 The Structure of lists A list is written by enclosing its elements within parentheses. The empty list is written as ( ) in Scheme. The list (a) is different from the list (a ( )). (+ 2 3) is both an expression and a list. Quoting will tell the interpreter to treat it as a list E.g, ( ) 5 ‘( ) ( )

20 List Construction Functions: CONS and LIST
takes two parameters, the first of which can be either an atom or a list the second of which is a list returns a new list that includes the first parameter as its first element, and the second parameter as the remainder of its result e.g., (CONS 'A '(B C)) returns (A B C) (cons a x) can be represented as (a . X) LIST takes any number of parameters returns a list with the parameters as elements (list ‘x ‘y)  (x y) e.g., (list ‘it ‘seems) = (it seems)

21 List Functions: CAR and CDR
CAR takes a list parameter; returns the first element of that list e.g., (CAR '(A B C)) yields A (CAR '((A B) C D)) yields (A B) CDR takes a list parameter; returns the list after removing its first element e.g., (CDR '(A B C)) yields (B C) (CDR '((A B) C D)) yields (C D)

22 List Functions: CAR and CDR (cont)
Example of lists Use of car and cdr

23 Predicate Functions: LIST? and NULL?
LIST? takes one parameter; it returns #T if the parameter is a list; otherwise() NULL? takes one parameter; it returns #T if the parameter is the empty list; otherwise() Note that NULL? returns #T if the parameter is()

24 The Function member member takes an atom and a simple list; returns #T if the atom is in the list; () otherwise (DEFINE (member atm lis) (COND ((NULL? lis) '()) ((EQ? atm (CAR lis)) #T) ((ELSE (member atm (CDR lis))) )) Example: (member ‘B ‘(A B C)) returns #T (member ‘B ‘(A C D E)) returns ( )

25 Linear functions on lists
Most functions on lists consider the elements of a list one by one; typically linear recursive, that is, a function f appears just once on the function body. fun f(x) = if list x is empty then … else something involving (car x), (cdr x), f. the two phases of linear recursive functions 1. A winding phase: in which the function examines the tail of the list; 2. An unwinding phase: in which control unwinds back to the beginning of the list.

26 The function append This function concatenates or appends two lists.
takes two lists as parameters; returns the first parameter list with the elements of the second parameter list appended at the end Ex1: (append ‘(1 2) ‘(3 4 5) ) ( ) Ex 2: (append ‘( ) z )  z (append (cons (a y)) z)  cons(a (append (y z))) Definitions of the function append: (DEFINE (append lis1 lis2) (COND ((NULL? lis1) lis2) (ELSE (CONS (CAR lis1) (append (CDR lis1) lis2))) ))

27 Evaluation of reverse and append

28 The function reverse It reverses the order of elements in a list.
Ex 1: (reverse ‘(1 2 3) ‘( ) ) (3 2 1) Ex 2: (reverse ‘(2 3 4) ‘(1) )  (reverse ‘(3 4) (cons 2 ‘(1)))  (reverse ‘(4) (cons 3 (cons 2 ‘(1))))  (reverse ‘( ) (cons 4 (cons 3 (cons 2 ‘(1))))) = ( ) Ex 3: (reverse ‘( ) z )  z (reverse (cons a y) z )  (reverse y (cons a z) ) Definitions of the function reverse: (define (reverse x z) (cond ((null? x) z) (else (reverse (cdr x) (cons (car x) z))) ))

29 Predicate Function: EQ?
EQ? takes two symbolic parameters; it returns #T if the two parameters are the same e.g., (EQ? 'A 'A) yields #T e.g., (EQ? 'A 'B) yields () Note that if EQ? is called with list parameters, the result is not reliable (see below) equal? : if both objects are structurally equal, e.g., > (define x '(1 2)) ;assign the value of x > (define y '(1 2)) > (eq? x y) ( ) > (equal? x y) #t

30 The Function equalsimp
equalsimp takes two simple lists as parameters; returns #T if the two simple lists are equal; () otherwise (DEFINE (equalsimp lis1 lis2) (COND ((NULL? lis1) (NULL? lis2)) ((NULL? lis2) '()) ((EQ? (CAR lis1) (CAR lis2)) (equalsimp(CDR lis1)(CDR lis2))) (ELSE '()) ))

31 The Function equal equal takes two general lists as parameters; returns #T if the two lists are equal; ()otherwise Need to process sublist, atom (DEFINE (equal lis1 lis2) (COND ((NOT (LIST? lis1))(EQ? lis1 lis2)) ((NOT (LIST? lis2)) '()) ((NULL? lis1) (NULL? lis2)) ((NULL? lis2) '()) ((equal (CAR lis1) (CAR lis2)) (equal (CDR lis1) (CDR lis2))) (ELSE '()) ))

32 Example Scheme Function: LET
General form: (LET ( (name_1 expression_1) (name_2 expression_2) ... (name_n expression_n)) body ) Factor out common subexpressions and name them. Evaluate all expressions, then bind the values to the names; evaluate the body

33 LET Example (DEFINE (quadratic_roots a b c) (LET ( (root_part_over_2a
(/ (SQRT (- (* b b) (* 4 a c)))(* 2 a))) (minus_b_over_2a (/ (- 0 b) (* 2 a))) (DISPLAY (+ minus_b_over_2a root_part_over_2a)) (NEWLINE) (DISPLAY (- minus_b_over_2a root_part_over_2a)) ))

34 let and let* The let* function binds name_i to the value of expression_i before expression_i+1 is evaluated, that is, sequential binding. Example: (define x 0) ( let ( ( x 2 ) ( y x ) ) y ) ;bind y before redefining x ( let* ( ( x 2 ) ( y x ) ) y ) ;bind y after redefining x 2

35 Scheme Functional Forms
Composition The previous examples have used it (CDR (CDR ‘(A B C))) returns (C) Apply to All One form in Scheme is map (課本叫mapcar) applies the given function to all elements of the given list; Example: (map car ‘((a 1) (b 2) (c 3) (d 4))) (a b c d) Definition (DEFINE (map fun lis) (COND ((NULL? lis) '()) (ELSE (CONS (fun (CAR lis)) (map fun (CDR lis)))) ))

36 More higher-order functions
(define (remove-if f x) (cond ((null? x) ‘() ) ((f (car x)) (remove-if f (cdr x))) (else (cons (car x) (remove-if f (cdr x)))))) (define (reduce f x v) (cond ((null? x) v) (else (f (car x) (reduce f (cdr x) v))))) (see pages for explanations in ML)

37 Functions That Build Code
It is possible in Scheme to define a function that builds Scheme code and requests its interpretation This is possible because the interpreter is a user-available function, EVAL

38 Adding a List of Numbers
Example: ((DEFINE (adder lis) (COND ((NULL? lis) 0) (ELSE (EVAL (CONS '+ lis))) )) The parameter is a list of numbers to be added; adder inserts a + operator and evaluates the resulting list Use CONS to insert the atom + into the list of numbers. Be sure that + is quoted to prevent evaluation Submit the new list to EVAL for evaluation

39 Association list An association list, or a-list, is a list of pairs. Each pair is an association or binding, consisting of a key and a value, e.g., ( ( a 1 ) ( b 2 ) ( c 3 ) ) There are three operations: ( bind key value a-list ): returning an association list with a new binding for a key. ( bind-all keys values a-list ): pairing each key with the corresponding value. (assoc key a-list ): returning the most recent binding for the key.

40 Association list (cont)
Example: ( bind-all ‘(a b c) ‘(1 2 3) ‘()) ( (a 1) (b 2) (c 3) ) ( assoc ‘a ‘((a 1 ) ( b 2 ) ( a 3 ) ) ) ( a 1 )

41 Association list (cont)
Definition: (define (bind key value env) (cons (list key value) env) ) (define (bind-all keys values env) (append (map list keys values) env))

42 Storage allocation for lists
Lists are built out of cells capable of holding pointers to the head (car) and tail (cdr) of a list. Each execution of cons returns a pointer to a newly allocated cell. e.g., ( cons ‘it ( cons ‘seems ( cons ‘that ‘( ) ) ) ) car (contents of the address part of the register): returns the pointer in the first field. cdr (contents of the decrement part of the register): returns the pointer in the second field. it seems that ( )

43 Notions of Equality Example: (define x ‘(it seems that)) x
(define y (cons (car x) (cdr x))) y (equal? x y) #t (eq? x y) ( )

44 COMMON LISP A combination of many of the features of the popular dialects of LISP around in the early 1980s A large and complex language--the opposite of Scheme Features include: records arrays complex numbers character strings powerful I/O capabilities packages with access control iterative control statements

45 ML A static-scoped functional language with syntax that is closer to Pascal than to LISP Uses type declarations, but also does type inferencing to determine the types of undeclared variables It is strongly typed (whereas Scheme is essentially typeless) and has no type coercions Includes exception handling and a module facility for implementing abstract data types Includes lists and list operations

46 ML Specifics The val statement binds a name to a value (similar to DEFINE in Scheme) See the next page for examples. Function declaration form: fun name (parameters) = body; e.g., fun cube (x : int) = x * x * x;

47 Lexical scope It uses the program text to determine the context in which nonlocal names are evaluated. Val binding: let val x = E1 in E2 end is called a binding of x. e.g., let val x = 2 in x + x end All occurrences of x in E2 are said to be within the scope of this binding, but occurrences x in E1 are not in the scope of this binding of x. For nested binding of the same variable, first applying renaming to the inner binding. e.g., let val x=2 in let val x = x+1 in x+x end end (y) (y) (y)

48 Type Inferencing ML infers the type of an expression if possible:
2 + 2 ; ( input to the interpreter; an semicolon marks the and of an expression.) val it = 4 : int (response from the interpreter) Explicit types can be given to resolve overloading. e.g., fun add (x, y) = x + y; Error: overloaded variable “+” cannot be resolved. e.g., fun add (x, y): int = x + y; val add = fn : int * int -> int e.g., fun add (x, y) = x + (y: int);

49 Parameterized type (polymorphism)
ML uses a leading quote, e.g, ‘a, to identify a type parameter. Example (see the next page for list representation) hd [1, 2, 3]; val it = 1 : int hd [ “a”, “b”, “c”] ; val it = “a”: string hd; val it = fn : ‘a list -> ‘a (a function from a list of any type ‘a to type ‘a ) .

50 Basic operations on lists
A list in ML is a sequence of zero or more elements of the same type, written between brackets [ and ], e.g., [1, 2, 3]. An empty list is written as [ ] or nil. Basic operations : Null - null; test for emptiness; hd - head; return first element; t tail; return all except the first element; :: cons; infix list constructor.

51 Functions as first-class values
A function is called higher order if either its arguments or its results are themselves functions. ML provides the function map to apply a function f to each element of a list x. Example: square ( 3 ) = 9 map square [1, 2, 3, 4, 5] = [1, 4, 9, 16, 25] Definitions of the function map: fun map f [ ] = [ ] | map f ( a :: y ) = ( f a ) :: ( map f y )

52 Example of Using Map Example: map square [1, 2, 3];
val it = [1, 4, 9]: int list map first [(1, “a”), (2, “b”), (3, “c”)]; val it = [1, 2, 3]: int list map square (map first [(1, “a”), (2, “b”), (3, “c”)]); hd [ [11, 12, 13, 14], [21, 22, 23, 24], [31, 32, 33, 34]]; val it = [11, 12, 13, 14]: int list <- the first row map hd [ [11, 12, 13, 14], [21, 22, 23, 24], [31, 32, 33, 34]]; val it = [11, 21, 31]: int list <- the first column

53 Anonymous functions in ML
functions without a name; having the form: fn < formal-parameter > => < body > It helps for adapting exiting functions. Example: The function map expects a change function to be unary. Anonymous functions are used to adapt the binary operator *. map ( f n x => x * 2 ) [ 1, 2, 3, 4, 5 ] ; val it = [ 2, 4, 6, 8, 10 ] : int list

54 The function remove_if
It provides “selective copying”, that is, it copies list elements a, unless predicate f is true on a. Definitions of the function remove_if: fun remove_if f [ ] = [ ] | remove_if f ( a :: y ) = if f ( a ) then remove_if f y else a :: (remove_if f y ) Example: Define the function odd: fun odd x= (x mod 2) = 1 remove_if odd [0, 1, 2, 3, 4, 5]; val it = [0, 2, 4] : int list

55 The function reduce It accumulates a result, such as computing the sum or product of a list of integers. The function reduce has three parameters: a binary operator f, a list, and an initial value v. Definitions of the function reduce: fun reduce f [] v = v | reduce f (a::y) v = f (a, reduce f y v) Example: Define the function add: fun add (x, y): int = x + y; reduce add [1, 2, 3, 4, 5] 0; val it = 15: int

56 Approaches to expression evaluation in functional languages
The innermost-evaluation rule for the function application <name> <actual-parameter> : Evaluate the expression represented by <actual-parameter>. Substitute the result for the formal in the function body. Evaluate the body. Return its value as the answer. Example: fun successor n = n + 1 The application: successor ( ) -> activate plus -> get value 5 -> activate successor -> get value 6

57 Outermost-evaluation
Outermost-evaluation from left to right: Substitute the actual for the formal in the function body. Evaluate the body. Return its value as the answer. Sometimes outermost evaluation does redundant work because it re-evaluates an actual parameter. A clever implementation would have kept track of the substituted copies and recognize that its value has already been computed. Example : The 91-function: fun f(x) = if x > 100 then x-10 else f(f(x+11))

58 Evaluation of f(100) of the 91-function

59 Short-circuit evaluation
Innermost and outermost evaluation produce the same result if both terminate with a result. Sometimes innermost evaluation does not terminate; while outermost evaluation terminate. Example : innermost evaluation for or (true, F) results in a non terminating computation if the evaluation of F does not terminate. However, for outermost evaluation, the nonterminating computation F is never reached. (Suppose F=f(3); fun f (x)=if x>0 then f(x+1)) In ML, andalso and orelse performs short-circuit evaluation of boolean expressions, in which the right operand is evaluated only if it has to be.

60 Applications of Functional Languages
LISP is used for artificial intelligence Knowledge representation Machine learning Natural language processing Modeling of speech and vision Scheme is used to teach introductory programming at a significant number of universities

61 Comparing Functional and Imperative Languages
Efficient execution Complex semantics Complex syntax Functional Languages: Simple semantics Simple syntax Inefficient execution


Download ppt "Chapter 15: Functional Programming Languages"

Similar presentations


Ads by Google