+ All Categories
Home > Documents > © Kenneth C. Louden, 20031 Chapter 11 - Functional Programming, Part III: Theory Programming...

© Kenneth C. Louden, 20031 Chapter 11 - Functional Programming, Part III: Theory Programming...

Date post: 31-Dec-2015
Category:
Upload: kristin-carson
View: 226 times
Download: 5 times
Share this document with a friend
29
© Kenneth C. Louden, 2003 1 Chapter 11 - Chapter 11 - Functional Functional Programming, Part III: Programming, Part III: Theory Theory Programming Languages: Principles and Practice, 2nd Ed. Kenneth C. Louden
Transcript
Page 1: © Kenneth C. Louden, 20031 Chapter 11 - Functional Programming, Part III: Theory Programming Languages: Principles and Practice, 2nd Ed. Kenneth C. Louden.

© Kenneth C. Louden, 2003 1

Chapter 11 - Functional Chapter 11 - Functional Programming, Part III: TheoryProgramming, Part III: Theory

Programming Languages:

Principles and Practice, 2nd Ed.

Kenneth C. Louden

Page 2: © Kenneth C. Louden, 20031 Chapter 11 - Functional Programming, Part III: Theory Programming Languages: Principles and Practice, 2nd Ed. Kenneth C. Louden.

Chapter 11 - Part III K. Louden, Programming Languages 2

Recursive FunctionsRecursive Functions Abstractly, a function f is a rule that associates to

each x in some set X (the domain), a y in another set Y (the range): f: X Y.

Alternatively, a function can be viewed as a subset S of the Cartesian product X Y with the property that (x,y), (x,y') S implies y = y'.

Functions can be given as sets simply by listing their elements (definition by extension).

More usually, functions are given by a formula (definition by comprension), which may or may not be recursive.

Page 3: © Kenneth C. Louden, 20031 Chapter 11 - Functional Programming, Part III: Theory Programming Languages: Principles and Practice, 2nd Ed. Kenneth C. Louden.

Chapter 11 - Part III K. Louden, Programming Languages 3

Recursive Functions (2)Recursive Functions (2) Chapter 8 shows how to implement recursive

functions. But how are such functions mathematically defined?

One way to think abstractly about a recursive definition is to consider it to imply a (countably infinite) union of sets that are built, one element at a time, out of the base case or cases.

Factorial example:fact n = if n = 0 then 1 else n * fact (n-1)

The "base" point is (0,1): fact0 = { (0,1) }

Now consider the formula as a set equation:fact = fact0 U fact', where fact' is the function formed for each n by the formula n * fact (n-1).

Page 4: © Kenneth C. Louden, 20031 Chapter 11 - Functional Programming, Part III: Theory Programming Languages: Principles and Practice, 2nd Ed. Kenneth C. Louden.

Chapter 11 - Part III K. Louden, Programming Languages 4

Recursive Functions (3)Recursive Functions (3) Unfortunately, we don't yet know either fact or fact'. But consider what would happen if we used fact0 as

an approximation for fact in the formula for fact': fact1 = fact0 U fact0' , where

fact0' = { (n,m) | (n-1,p) fact0 , m = n*p }= { (1,1) } [since (1-1,1) = (0,1) fact0]

Then fact1 = { (0,1) } U { (1,1) }. We have a new point!

So apply the equation again, this time using fact1 as an approximation for fact in fact'. We get yet another point! Call this function fact2 . Continue.

Now let fact = Un = 1.. factn . What function is this?

Page 5: © Kenneth C. Louden, 20031 Chapter 11 - Functional Programming, Part III: Theory Programming Languages: Principles and Practice, 2nd Ed. Kenneth C. Louden.

Chapter 11 - Part III K. Louden, Programming Languages 5

Recursive Functions (4)Recursive Functions (4) If we try the process once again, we find that we

get no new points: fact = fact0 U fact '. The function fact is said to be a fixed point of the

recursive equation for fact. Indeed, fact is the smallest such set with this

property and is essentially unique. So it makes sense to define the fact function to be

fact : we say that the recursive definition has least-fixed-point semantics.

Not all sets allow least fixed point solutions to recursive equations. Sets that do are called domains.

Domain theory tells us when recursive definitions will work (and when they won't).

Page 6: © Kenneth C. Louden, 20031 Chapter 11 - Functional Programming, Part III: Theory Programming Languages: Principles and Practice, 2nd Ed. Kenneth C. Louden.

Chapter 11 - Part III K. Louden, Programming Languages 6

Fixed pointFixed point

In mathematics, a fixed point is a point that is mapped to itself by the function.

• For example, if f is defined in real number by f(x) = x2 –3x + 4, then 2 is a fixed point of f, because f(2) = 2.

• Not all functions have fixed points: f(x)=x+1 has no fixed point on the reals.

Page 7: © Kenneth C. Louden, 20031 Chapter 11 - Functional Programming, Part III: Theory Programming Languages: Principles and Practice, 2nd Ed. Kenneth C. Louden.

Chapter 11 - Part III K. Louden, Programming Languages 7

Factorial functionFactorial function fact n = if n = 0 then 1 else n * fact (n-1) f(n )= if n = 0 then 1 else n * g (n-1) Two parameters on the right: n and gWe can think of this as defining a

higher-order function H as follows

H(g)(n) = if n = 0 then 1 else n * g (n-1)

H (fact)(n) = fact(n) for all n

Thus, the factorial function is a Fixed point of H!

Page 8: © Kenneth C. Louden, 20031 Chapter 11 - Functional Programming, Part III: Theory Programming Languages: Principles and Practice, 2nd Ed. Kenneth C. Louden.

Chapter 11 - Part III K. Louden, Programming Languages 8

Least fixed pointLeast fixed point

We want the smallest solution to this equation to be chosen definition of the fact function.

For this reason, recursive function definitions are said to have least fixed point semantics, and fact is taken to be the least fixed point of the function H.

Page 9: © Kenneth C. Louden, 20031 Chapter 11 - Functional Programming, Part III: Theory Programming Languages: Principles and Practice, 2nd Ed. Kenneth C. Louden.

Chapter 11 - Part III K. Louden, Programming Languages 9

Examples of least fixed pointsExamples of least fixed points

Page 89 • Exp ->exp + exp|number• E = E + E U N

Page 523• fact = Un = 1.. factn

They are smallest solutions to the given set equetions!

Page 10: © Kenneth C. Louden, 20031 Chapter 11 - Functional Programming, Part III: Theory Programming Languages: Principles and Practice, 2nd Ed. Kenneth C. Louden.

Chapter 11 - Part III K. Louden, Programming Languages 10

Lambda CalculusLambda Calculus The lambda calculus is an abstraction and

simplification of a functional programming language, much as a Turing machine is an abstraction and simplification of a computer.

Lambda calculus is Turing-complete, so it it can be used as a model for computation instead of TMs.

Issues such as delayed evaluation, recursion, and scope can be studied with mathematical precision in the lambda calculus.

Page 11: © Kenneth C. Louden, 20031 Chapter 11 - Functional Programming, Part III: Theory Programming Languages: Principles and Practice, 2nd Ed. Kenneth C. Louden.

Chapter 11 - Part III K. Louden, Programming Languages 11

Syntax of Lambda CalculusSyntax of Lambda Calculus Two sets of basic expressions:

Variables: x,y,z, etc. (essentially identifiers representing parameters)

Constants: numbers like 1, 2, 3; "built-in" functions like +, *, cons.

Two operations:Abstraction (like lambda expressions in Scheme,

ML, or Haskell - anonymous function creation).

Application (like function call).

Grammar:lexpr variable . lexpr | lexpr lexpr

| ( lexpr ) | variable | constant

abstraction

application

Page 12: © Kenneth C. Louden, 20031 Chapter 11 - Functional Programming, Part III: Theory Programming Languages: Principles and Practice, 2nd Ed. Kenneth C. Louden.

Chapter 11 - Part III K. Louden, Programming Languages 12

Example of Lambda Calculus Example of Lambda Calculus AbstractionAbstraction (x . + 1 x) -- lambda abstraction This can be interpreted exactly as the lambda

expression in Scheme

(lambda (x) ( + 1 x) )

Page 13: © Kenneth C. Louden, 20031 Chapter 11 - Functional Programming, Part III: Theory Programming Languages: Principles and Practice, 2nd Ed. Kenneth C. Louden.

Chapter 11 - Part III K. Louden, Programming Languages 13

Example of Lambda Calculus Example of Lambda Calculus ApplicationApplication (x . + 1 x) 2 => (+ 1 2) => 3 The basic operation of lambda calculus is the

application of expression such as the lambda abstraction.

The application of the function that adds 1 to x to the constant 2.

Lambda calculus expresses this by providing a reduction rule that permits 2 to be substituted for x in the lambda (and removing the lambda) yielding the desired value.

Page 14: © Kenneth C. Louden, 20031 Chapter 11 - Functional Programming, Part III: Theory Programming Languages: Principles and Practice, 2nd Ed. Kenneth C. Louden.

Chapter 11 - Part III K. Louden, Programming Languages 14

Examples of Lambda Calculus Examples of Lambda Calculus ExpressionsExpressions

x . + ((y. (x. x y) 2) x) y

(x . x y) y

((y. 2) ((x. x x) (x. x x)))

( h. ( x. h (x x)) ( x. h (x x)))

Page 15: © Kenneth C. Louden, 20031 Chapter 11 - Functional Programming, Part III: Theory Programming Languages: Principles and Practice, 2nd Ed. Kenneth C. Louden.

Chapter 11 - Part III K. Louden, Programming Languages 15

The notion of CurryingThe notion of CurryingLouden page 505-506Louden page 505-506

A function of multiple parameters that can be viewed as a (higher order) function of a single parameter that returns a function of the remaining parameters is said to be Curried.

We will call a language fully Curried if function definitions are automatically treated as Curried.

Page 16: © Kenneth C. Louden, 20031 Chapter 11 - Functional Programming, Part III: Theory Programming Languages: Principles and Practice, 2nd Ed. Kenneth C. Louden.

Chapter 11 - Part III K. Louden, Programming Languages 16

NotesNotes Lambda calculus is fully Curried. Application works left to right, abstraction right

to left. Application has higher precedence than

abstraction. The set of variables is unspecified, but doesn't

matter very much, as long as it is (countably) infinite.

The set of constants isn't specified either, and this can make a difference in terms of what you want to express. This set may be infinite (all integers) or finite or even empty (pure lambda calculus). Thus, there are really many kinds of lambda calculus.

Page 17: © Kenneth C. Louden, 20031 Chapter 11 - Functional Programming, Part III: Theory Programming Languages: Principles and Practice, 2nd Ed. Kenneth C. Louden.

Chapter 11 - Part III K. Louden, Programming Languages 17

Notes (continued)Notes (continued) There are no semantic restrictions on the

syntactically legal expressions in the lambda calculus: all expressions given by the syntax are legal.

By the previous statement, there can be no type checking in the lambda calculus. There is in fact an alternate version called the typed lambda calculus that does have types.

Not all lambda expressions make sense as programs: (x x) is legal, and so is (2 x).(Exercise: try typing x . x x in ML or Haskell.)

Page 18: © Kenneth C. Louden, 20031 Chapter 11 - Functional Programming, Part III: Theory Programming Languages: Principles and Practice, 2nd Ed. Kenneth C. Louden.

Chapter 11 - Part III K. Louden, Programming Languages 18

Semantics of Lambda CalculusSemantics of Lambda Calculus Some expressions are equivalent to

others in lambda calculus even though they are syntactically distinct: x . x is equivalent to y . y ()

x . y x is equivalent to y ()

( x . x) y is equivalent to y ()

These equivalences have historical names: alpha-conversion (-conversion), eta-conversion (-conversion), and beta-conversion (-conversion). When a conversion simplifies an expression it is called a reduction.

Page 19: © Kenneth C. Louden, 20031 Chapter 11 - Functional Programming, Part III: Theory Programming Languages: Principles and Practice, 2nd Ed. Kenneth C. Louden.

Chapter 11 - Part III K. Louden, Programming Languages 19

Semantics (2)Semantics (2) Conversion operations depend on the

notion of the scope (or binding) of a variable in an abstraction.

The variable x in the expression (x.E) is said to be bound by the lambda. The scope of the binding is the expression E.

An occurrence of a variable outside the scope of any binding of it by a lambda is a free occurrence. An occurrence that is not free is a bound occurrence. Thus, in the expression x. E, all occurrences of x in E are bound.

Page 20: © Kenneth C. Louden, 20031 Chapter 11 - Functional Programming, Part III: Theory Programming Languages: Principles and Practice, 2nd Ed. Kenneth C. Louden.

Chapter 11 - Part III K. Louden, Programming Languages 20

Examples of bound and free vars:Examples of bound and free vars: In the expression (x . x y) y the variable x

is bound and both instances of the variable y are free.

In the expression x . + ((y. (x. x y) 2) x) y both instances of x are bound (but by different lambdas), and the first instance of y is bound, while the second one is free (arrows point to bindings):

x . + ((y. (x. x y) 2) x) y

Page 21: © Kenneth C. Louden, 20031 Chapter 11 - Functional Programming, Part III: Theory Programming Languages: Principles and Practice, 2nd Ed. Kenneth C. Louden.

Chapter 11 - Part III K. Louden, Programming Languages 21

Conversion RulesConversion Rules First, let E[F/x] represent the expression

obtained by substituting all free occurrences of x by F in the expression E.

-conversion: x . E is equivalent to y . E[y/x], provided E contains no free occurrences of y.

-conversion: ( x . E) F is equivalent to E[F/x], provided F contains no free variables that are bound in E.

-conversion: x . E x is equivalent to E, provided E contains no free occurrences of x.

Page 22: © Kenneth C. Louden, 20031 Chapter 11 - Functional Programming, Part III: Theory Programming Languages: Principles and Practice, 2nd Ed. Kenneth C. Louden.

Chapter 11 - Part III K. Louden, Programming Languages 22

Name CaptureName Capture Each of the above rules has a side

condition which represents a name capture issue: if you substitute an expression with free variables into a lambda, one or more of those free variables may conflict with names bound by lambdas (and be captured by them), giving incorrect results (since variable bound/free status should not change):() : x . y y . y() : ( x . y . x y) y y . y y() : x . x x x

Page 23: © Kenneth C. Louden, 20031 Chapter 11 - Functional Programming, Part III: Theory Programming Languages: Principles and Practice, 2nd Ed. Kenneth C. Louden.

Chapter 11 - Part III K. Louden, Programming Languages 23

Name Capture (2)Name Capture (2) The solution is to use -conversion to

change bound variable names that clash with free variables in -reduction:( x . y . x y) y = ( x . z . x z) y = z . y z

In the other two cases, we simply cannot perform that particular conversion.

Page 24: © Kenneth C. Louden, 20031 Chapter 11 - Functional Programming, Part III: Theory Programming Languages: Principles and Practice, 2nd Ed. Kenneth C. Louden.

Chapter 11 - Part III K. Louden, Programming Languages 24

Semantics (3)Semantics (3) An expression is a normal form if there are

no -reductions that can be performed on it.

The semantics of an expression in lambda calculus is expressed by converting it to a normal form, if possible. Such a normal form, if it exists, is unique, by the famous Church-Rosser Theorem.

Not all reduction sequences lead to a normal form: ( y. 2) (( x. x x)( x. x x))

Page 25: © Kenneth C. Louden, 20031 Chapter 11 - Functional Programming, Part III: Theory Programming Languages: Principles and Practice, 2nd Ed. Kenneth C. Louden.

Chapter 11 - Part III K. Louden, Programming Languages 25

Normal vs. Applicative OrderNormal vs. Applicative Order A -reduction ( x. E) F => E[F/x] that

substitutes F for x before reducing F is called a normal-order reduction. It corresponds to the lazy evaluation of Haskell (without the memoization).

If on the other hand, the -reduction ( x. E) F => E[F/x] is performed only after reducing F, it is called an applicative order reduction. This corresponds to the evaluation rule of Scheme, where all arguments are evaluated before a call.

Page 26: © Kenneth C. Louden, 20031 Chapter 11 - Functional Programming, Part III: Theory Programming Languages: Principles and Practice, 2nd Ed. Kenneth C. Louden.

Chapter 11 - Part III K. Louden, Programming Languages 26

Semantics (4)Semantics (4) Main result (also a consequence of the

Church-Rosser Theorem): if a normal form exists, a normal-order sequence of conversions will find it.

Example 1: a normal form for ( y. 2) (( x. x x)( x. x x)) is 2, but an applicative-order -reduction gets into an infinite loop.

Example 2: x . + ((y. (x. x y) 2) x) y reduces to x . + ( 2 x) y using either normal-order or applicative-order.

Page 27: © Kenneth C. Louden, 20031 Chapter 11 - Functional Programming, Part III: Theory Programming Languages: Principles and Practice, 2nd Ed. Kenneth C. Louden.

Chapter 11 - Part III K. Louden, Programming Languages 27

RecursionRecursion Can recursion be expressed in lambda calculus?

Note that lambda calculus has no mechanism for resolving free names, which is the usual way of expressing recursion:fact = n.if n==0 then 1 else n*fact(n-1)

To get rid of the free name in the right-hand side, make it a parameter:Hfact = g.n.if n==0 then 1 else n*g(n-1)

Now if Hfact f = f, then f must be fact! Such an f is called a fixed point of Hfact.

Is there a lambda expression that can produce fixed points? YES!

Page 28: © Kenneth C. Louden, 20031 Chapter 11 - Functional Programming, Part III: Theory Programming Languages: Principles and Practice, 2nd Ed. Kenneth C. Louden.

Chapter 11 - Part III K. Louden, Programming Languages 28

Recursion (2)Recursion (2) The lambda expression

Y = h.( x. h (x x))( x. h (x x)) produces arbitrary fixed points: let H be any lambda expression. Then Y H = ( x. H (x x))( x. H (x x))

= H (( x. H (x x)) ( x. H (x x))) = H (Y H), so Y H is a fixed point of H.

Unfortunately, Y has no type in ML or Haskell (try it!), but we can fall back on the fixed point property itself as a definition of Y, in either ML, Haskell, or Scheme: y h = h (y h)

To what extent this works in the actual languages is Exercise 11.50.

Page 29: © Kenneth C. Louden, 20031 Chapter 11 - Functional Programming, Part III: Theory Programming Languages: Principles and Practice, 2nd Ed. Kenneth C. Louden.

Chapter 11 - Part III K. Louden, Programming Languages 29

Implementing standard language Implementing standard language features in lambda calculusfeatures in lambda calculus Recursion can be implemented (as we have just

seen). So can numbers (Exercise 11.47). So can lists (Exercise 11.46). So can Booleans and if-then-else:

true = x. y. x, false = x. y. y,if = x. y. z. x y z, and now(if true E F) = E and (if false E F) = F

Indeed, everything can (with some huffing and puffing, as with Turing Machines)!


Recommended