Title: Programming Languages
1Programming Languages
- COMP 321
- Spring 2012
- Practicum 4
2Practicum 4
- Functional Forms
- Functional abstraction
- Function Composition
- Construction
- Mapping
- Dynamic code
3reference
- reference
- Teach Yourself Scheme in Fixnum Days, section 6.4.
4Fundamentals of Functional Programming
Languages
- FPL objective to mimic mathematical functions
to the greatest extent possible - basic process of computation in a FPL vs an
imperative language - In an imperative language, operations are done
and the results are stored in variables for later
use - Management of variables is a source of complexity
for imperative programming - In an FPL variables are used as unknowns (as is
the case in mathematics)
5Fundamentals of Functional Programming Languages
- In an FPL, the evaluation of a function always
produces the same result given the same
parameters - This is called referential transparency
- Is this true in an imperative language?
6Abstraction
- Programming is all about abstraction
- Variables, Data structures abstract on memory
- control structures abstract on the processor
- How?
7Abstraction
- Programming is all about abstraction
- OOP abstracts on data (ADTs)
- Encapsulation
- Polymorphism
- OOP provides higher level abstractions
- Inheritance
- How is this abstraction?
8OOP Abstraction
Class A Public f() Private x, y
Class B Public g() Private a,b
Class C Public h() Private i,j
These classes build on class A dont know how it
is implemented.
9Abstraction
- Programming is all about abstraction
- Functional programming languages (FPL) abstract
on functions
(define A (lambda (b) )
Receive new function B that performs some task.
Call function A and pass function f (A f)
10Mathematical Functions
- Functional Forms
- Def A higher-order function, or functional form,
is one that either takes functions as parameters
or yields a function as its result, or both
11Mathematical Functions
- Functional Forms
- Functional abstraction
- Function Composition
- Construction
- Mapping
- Dynamic code
12Functional Forms
- 0. Functional abstraction
- Passing functions as arguments
- Returning functions as results
- Powerful technique that can be used in
conjunction with other techniques
13Functional Forms
- 0. Functional abstraction
- In an OOP language (like Java) we abstract over
classes - Example Javas abstract classes
- An abstract class cannot be implemented
- It represents the structure of the class
14Functional Forms
- 0. Functional abstraction
- (define doubler
- (lambda (f)
- (lambda (x) (f x x))))
- (define double (doubler ))
- (double 13/2) 13
- (double 5) 10
15Functional Forms
- 0. Functional abstraction
- (define doubler
- (lambda (f)
- (lambda (x) (f x x))))
- (define double-cons (doubler cons))
- (double-cons a) (a . a)
16Functional Forms
- 0. How does doubler work?
- ((doubler ) 2)
- 1. (define doubler
- (lambda (f)
- (lambda (x) (f x x))))
-
f
1. create closure
(lambda (x) (f x x))))
2. doubler returns the closure (which contains
the lambda)
3. returned function is executed in the context
of the closure
2. ((doubler ) 2)
x 2
(lambda (x) (f x x))))
17Functional Forms
- 0. Functional abstraction
- (define doubler
- (lambda (f)
- (lambda (x) (f x x))))
- (define double-any
- (lambda (f x)
- ((doubler f) x)))
18Functional Forms
- 0. How does double-any work?
- (define doubler
- (lambda (f)
- (lambda (x) (f x x))))
- (define double-any
- (lambda (f x)
- ((doubler f) x)))
Doubler returns a function that takes one
parameter. The function is defined within the
scope of doubler where f is bound.
19Functional Forms
- 0. How does double-any work?
- (double-any 2)
- 1. (define double-any
- (lambda (f x)
- ((doubler f) x)))
-
f x 2
((doubler f) x)))
4. Call the returned function
3
2
g
2. (define doubler (lambda (g) (lambda (x)
(g x x))))
(lambda (x) (g x x))))
20Functional Forms
- 0. Functional abstraction
- Exercise create a function that takes a
one-argument function f and a list, applies f to
the first item in the list, and returns the
result.
21Functional Forms
- Solution
- (define change-first
- (lambda (f)
- (lambda (x)
- (f (car x)))))
- gt (add1_first '(2 3 4))
- 3
- gt
(define incr (lambda (x) ( 1
x))) (define add1_first (lambda (x)
((change-first incr) x)))
22Functional Forms
- 1. 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 application of the second - Form h ? f g
- which means h (x) ? f ( g ( x))
- For f (x) ? x x x and g (x) ? x
3, - h ? f g yields (x 3) (x 3) (x
3)
23Functional Forms
- 1. Function Composition
- Most scheme functions use composition.
- Example the list-copy function applies cons to
list-copy and car - (define list-copy
- (lambda (ls)
- (if (null? ls)
- ( )
- (cons (car ls)
- (list-copy (cdr ls)))
- )
- )
- )
24Functional Forms
- 1. Function Composition
- Can abstract composition also
- (define compose
- (lambda (f g)
- (lambda (x)
- (f (g x)))
- ))
- gt (define safeSqr (compose sqrt abs))
- gt (safeSqr -100)
- 10
- gt
25Functional Forms
- 2. Construction
- A functional form that takes a list of functions
as parameters and yields a list of the results of
applying each of its parameter functions to a
given parameter - Form f, g
- For f (x) ? x x x and g (x) ? x 3,
- f, g (4) yields (64, 7)
26construction
- construct applies two functions to an argument
and puts the result in a list. - (define construct
- (lambda (x)
- (cons (sqrt x) (cons (abs x) ()))
- )
- )
27construction
- Can abstract construction
- (define construct2
- (lambda (f g)
- (lambda (x)
- (cons (f x) (cons (g x) ()))
- )
- ))
- gt (define test (construct2 sqrt abs))
- gt (test 100)
- (10 100)
- gt
28Functional Forms
- 3. Apply-to-all or mapping
- 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 x
- ?( h, (3, 2, 4)) yields (27, 8, 64)
29mapping
- mapping applies a function over all elements of a
list - abs-all maps abs over the input list to produce
the output list - (define abs-all
- (lambda (ls)
- (if (null? ls)
- ( )
- (cons (abs (car ls))
- (abs-all (cdr ls)))
- )
- )
- )
30mapping
- Scheme supplies a built-in map function
- (define abs-all2
- (lambda (ls)
- (map abs ls)
- )
- )
(map abs (1 -2 3 -4 5 -6)) (map (lambda (x) ( x
x)) (1 -3 -5 7)) (map cons (a b c) (1 2 3))
31mapping
- Can abstract mapping, but need a letrec
- (define mapper
- (lambda (f)
- (lambda (ls)
- (if (null? Ls)
- ()
- (cons (f (car ls))
- (?? (cdr ls)))
- )
- )
- )
How do we call ourselves?
32mapping
- Can abstract mapping, but need a new construct (a
letrec) - (define mapper
- (lambda (f)
- (lambda (ls)
- (letrec ( (mapRec
- (lambda (lst)
- (if (null? lst)
- ()
- (cons (f (car ls))
- (mapRec (cdr lst)))
- ) end if
- ) end
lambda - ) end mapRec
- ) end definitions
- (mapRec ls)
- ) end letrec
- )))
33Functional Forms
- 4. Dynamic 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
34Functional Forms
- 4. Dynamic Code
- Example suppose we have a list of numbers that
must be added together - (define adder (lambda (lis)
- (cond
- ((null? lis) 0)
- (else ( (car lis)
- (adder(cdr lis ))))
- )
- ))
35Abstracting
list is the build-in scheme operator to make lists
- (define adder2 (lambda (lis)
- (cond
- ((null? lis) 0)
- (else (eval (cons (list (car lis) (adder2
(cdr lis)))))) - )))
- The parameter is a list of numbers to be added
adder inserts a operator - eval causes the resulting list to be interpreted
36Abstracting
- (define adder3 (lambda (op lis)
- (cond
- ((null? lis) 0)
- (else (eval (cons op (list (car lis) (adder3
op (cdr lis)))))) - )))
- (adder3 (3 4 5))
- What happens if you leave out the eval?
37Abstracting
- (define adder4
- (lambda (op)
- (lambda (lis)
- (letrec ( (addUp
- (lambda (lis)
- (cond
- ((null? lis) 0)
- (else (eval (cons op (list (car lis)
- (addUp (cdr lis))))))))
- ) end addUp
- ) end definitions
- (addUp lis)
- ) end letrec
- )))
- this is useful if op only takes two arguments