330 likes | 680 Views
Functional Programming. Some Functional Languages. Lisp Scheme - a dialect of Lisp Haskell Miranda. What is Functional Programming. Functional programming is a third paradigm of programming languages. Each paradigm has a different ‘view’ of how a computer ‘computes’.
E N D
Some Functional Languages • Lisp • Scheme - a dialect of Lisp • Haskell • Miranda
What is Functional Programming • Functional programming is a third paradigm of programming languages. • Each paradigm has a different ‘view’ of how a computer ‘computes’. • Imperative paradigm alters the state of variables in memory • Object oriented alters the state of objects.
How does the functional paradigm view computation ? • Functional languages work on the premise that every statement is a function of its input. • Each function (statement) is then evaluated. • This means that a program as a whole is a nested set of function evaluations… and the whole program is a function of its inputs .. which includes functions !
Features of Functional Languages • First class functions • Higher order functions • List types and operators • Recursion • Extensive polymorphism • Structured function returns • Constructors for aggregate objects • Garbage collection
Some concepts • Side effects • pure functional languages are said to be ‘side effect free’ • side effects occur in imperative and OO languages because memory contents change • functional languages are not concerned with memory contents.
First class functions and higher order functions • Functions are first-class values • Have the same status as variables in imperative languages • Have the same status as objects in object oriented languages • They can be • assigned values • used as parameters
So how does this work ? • Through the read-eval-print loop • The interpreter (“listener”) waits until it : • (read) sees a complete list and interprets it as a function ( unless instructed not to ) • (eval) then evaluates it • (print) prints the final result • As it evaluates a list….. it evaluates all nested lists
Read • Get input (recall that these languages are often interpreted… so the whole program is input :) • Input is interpreted as a function with arguments that may be: • atomic values • numbers, strings, etc • lists • evaluted • unevaluated
Evaluation An atomic value evaluates to itself A function evaluates to the functional value of the input. • > 23 • 23 • > ( + 3 4 ) • 7 • > ( 8 4 5 ) • procedure application: expected procedure, given: 8; arguments were: 4 5 • > ( * 8 7 ) • 56 Some Scheme examples:
> (hello ) . reference to undefined identifier: hello > '(hello) (hello) > (display 'hello) hello > (display ( * 2 3 )) 6 > (* 2 3) 6 > (define x 2) > (+ x x) 4 > x 2 > (define x ( + 2 3)) > x 5
Print • The result of evaluating the entire function is printed…. If it has a value. • Functions must return a value to be used in other functions. • A call to the function display allows the programmer to print to the screen… but it has no return value.
Scheme • Scheme is a dialect of LISP • Input is in the form of lists, as mentioned before.
List Types • A list in scheme ‘( a b c d ) • Another list in scheme (gcd a b) • How are they different ? • ‘( a b c d ) • a simple list that is not evaluated • (gcd a b) • a function call for gcd with arguments a and b • Nested Lists: • ‘((a b) (c d e) f) is a list of 3 lists.
List operators • car - the first item of the list • cdr - the tail of the list… always a lists • Examples : • (car ( 1 2 3 4 )) is 1 • (cdr ‘(1 2 3 4 ) )is (2 3 4) • (car ‘((a b) (c d e) f) ) is the list (a b) • (cdr ‘((a b) (c d e) f) ) is the list ((c d e) f)
We can ‘nest’ List Operators • (caar ( (a b) (c d e) f) ) • a • (cadr ( (a b) (c d e) f) ) • (c d e) • (cdar ( (a b) (c d e) f) ) • ( b ) • (cddr ( (a b) (c d e) f) ) • ( f )
Is it a list or not ? • (define x ‘(a b c)) • (list? ‘(a b c)) # t • (list? (car x)) #f
Creating lists ( define x '(a b c d)) ( define y '( 1 2 3 4)) x y ; cons adds item to front ; of a list (display '(cons of x and y)) (define z ( cons x y)) x y z (a b c d) (1 2 3 4) (cons of x and y) (a b c d) (1 2 3 4) ((a b c d) 1 2 3 4)
; append joins 2 lists (display '(append of x and y)) (define z ( append x y)) x y z ; make a list (display '( make a list)) (list 1 22 333 444) (define z (list 1 22 333 444)) z (append of x and y) (a b c d) (1 2 3 4) (a b c d 1 2 3 4) (make a list) (1 22 333 444) (1 22 333 444)
Greatest Common Divisor • Given two positive integers x and y find a number z such that x mod z = 0 y mod z = 0 and there is no integer > z which meets the above conditions. • Examples: • GCD( 3,12) = 3 GCD ( 15, 50) = 5 • GCD( 27, 81) = 27 GCD ( 34, 51) = 17
Mathematical Functions • Functions have domain and range • domain restricts the inputs • range restricts the output • Example: • Greatest Common Divisor for positive integers • domain: N , N ( ie. Both inputs are natural numbers) • range: N (result is also a natural number)
GCD Recursively GCD( 15, 50) = GCD(50-15, 15) => GCD ( 35,15) = GCD(35- 15, 15)=> GCD (20, 15) = GCD(20-15, 15) => GCD(5,15) = GCD(15-5, 5) => GCD ( 10, 5) = GCD(10-5,5) => GCD (5,5) = 5 • If x == y then GCD(x, y) is x • Otherwise: • Let max = larger of x and y • Let min = smaller of x and y • Let new = max - min • Recursively call GCD(new, min)
GCD to an Imperative Programmer • Imperative programmer says: • To determine the gcd of a and b • Check : is a = b ? • Yes - print or return one of them and stop. • No - replace the larger with their difference and then repeat ( possibly recursively).
#include <stdio.h> /* This version of gcd PRINTS the result */ void gcd1(int x, int y) { if(x==y) printf("GCD is %d \n",x); else if( x < y) gcd1(y-x, x); else gcd1(x-y,x); } /* This version of gcd RETURNS the result */ int gcd2(int x, int y) { if(x==y) return x; else if( x < y) return gcd2(y-x, x); else return gcd2(x-y,x);} /********************************** The main program to demonstrate the difference between gcd1 and gcd2 ********************************/ int main() { int x,y,z; printf("Enter 2 numbers to find their gcd \n"); scanf("%d %d",&x, &y); gcd1(x,y); /*illegal statement z=gcd1(x,y); because gcd1 has no return value */ z = gcd2(x,y); printf("gcd2 return %d\n",z); }
GCD functionally • What does the functional programmer say ? gcd : N x N -> N is if a == b then a; if (a<b) then gcd (a, b-a) if ( a > b) then gcd ( b, a-b) Notation: domain -> range domain1 * domain2 indicates pairs of inputs to the function. This can be extended to n-tuples of inputs
Displaying is NOT Returning • The GCD in c displayed the desired information… it did not return it. • In functional languages this is also true… but the paradigm assumes that every function has a return value. • To be able to use the value of a function we must return it.
Defining functions ; gcd in scheme (define gcd1 (lambda (x y) (cond [(= x y ) x] [( > x y) (gcd1 y ( - x y))] [ (< x y)(gcd1 x ( - y x))]))) ;This RETURNS the value
Defining functions ; gcd in scheme (define gcd2 (lambda (x y) (cond [(= x y ) (display x)] [( > x y) (gcd2 y ( - x y))] [ (< x y)(gcd2 x ( - y x))]))) ;This PRINTS the value.. But the value can’t ; be used again.
Welcome to DrScheme, version 103. Language: Graphical Full Scheme (MrEd). > (gcd1 4 2) 2 > (gcd2 4 2) > (+ (gcd1 6 2) (gcd1 5 4)) 3 > (+ (gcd2 6 2) (gcd2 5 4)) > gcd1 vs. gcd2 2 21f +: expects type <number> as 1st argument, given: #<void>; other arguments were: #<void>