Functional Programming

Download Report

Transcript Functional Programming

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’.
– 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.
Some Scheme examples:
> 23
23
>(+34)
7
>(845)
procedure application: expected procedure, given: 8; arguments were: 4 5
>(*87)
56
> (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))
• (list? (car x))
#t
#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( 27, 81) = 27
GCD ( 15, 50) = 5
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
• 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
GCD( 15, 50) =
GCD(50-15, 15) =>
GCD ( 35,15) =
GCD(35- 15, 15)=>
GCD (20, 15) =
GCD(20-15, 15) =>
– Recursively call GCD(new, min)
GCD(5,15)
=
GCD(15-5, 5) =>
GCD ( 10, 5) =
GCD(10-5,5) =>
GCD (5,5)
=5
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
Notation:
if a == b then a;
domain -> range
if (a<b) then gcd (a, b-a)
domain1 * domain2
indicates pairs of
inputs to the function.
if ( a > b) then gcd ( b, a-b)
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.
gcd1 vs. gcd2
Welcome to DrScheme, version 103.
Language: Graphical Full Scheme (MrEd).
> (gcd1 4 2)
2
> (gcd2 4 2)
2
> (+ (gcd1 6 2) (gcd1 5 4))
3
> (+ (gcd2 6 2) (gcd2 5 4))
21f
+: expects type <number> as 1st argument,
>given: #<void>; other arguments were: #<void>