functions as data - profs area scienze ed...

21
Functions as data Massimo Merro 9 November 2011 Massimo Merro The Lambda language 1 / 21

Upload: others

Post on 30-Apr-2020

9 views

Category:

Documents


0 download

TRANSCRIPT

Functions as data

Massimo Merro

9 November 2011

Massimo Merro The Lambda language 1 / 21

The core of sequential programming languages

In the mid 1960s, Peter Landin observed that a complex programminglanguage can be understood by focussing on a tiny core calculuscapturing the language’s essential mechanisms ....

... together with a collection of convenient derived constructs whosebehaviour is understood by translating them into the core calculus.

The core language used by Landin was the λ-calculus, a formalsystem invented by Alonzo Church in the 1930’s as a universallanguage of computable functions.

In 1960, John McCarthy published the design of the programminglanguage Lisp based on the λ-calculus.

Since then, the λ-calculus has seen a widespread use in

the specification of programming language featuresin language design and implementationin the study of type systems.

Massimo Merro The Lambda language 2 / 21

Expressiveness of the λ-calculus

The λ-calculus can be viewed as a very simple programming languagein which computations can be described as mathematical objects.

It is a formal language in which

every term denotes a functionany term (function) can be applied to any other term, so functions areinherently higher-order

Despite its simplicitiy, it is a Turing-complete language: it can expresscomputations on natural number as does any other knownprogramming language.

Church’s Thesis: any conceivable notion of computable function onnatural numbers is equivalent to the λ-calculus.

The force of Church’s Thesis is that it postulates that all futurenotions of computation will be equivalent in expressive power to theλ-calculus.

Massimo Merro The Lambda language 3 / 21

Encoding language features in λ-calculus

The λ-calculus can be enriched in a variety of ways.

It is often convenient to add special constructs for features likenumbers, booleans, tuples, records, etc.

However, all these features can be encoded in the λ-calculus, so theyrepresent only “syntactic sugar”.

Such extensions lead eventually to programming languages such asLisp (McCarthy, 1960), ML (Milner et al., 1990), Haskell (Hudak etal., 1992), or Scheme (Sussman and Steele, 1975).

In the next slide, we propose the Lambda language a simple extensionof the λ-calculus with built-in operators for manipulating naturalnumbers and Booleans.

Massimo Merro The Lambda language 4 / 21

The language Lambda

M ∈ Lambda ::= n∣∣ true

∣∣ false∣∣ x∣∣ (M1 + M1)

∣∣ (M1 ×M2)∣∣ . . .∣∣ M1 and M2

∣∣ M1 or M2

∣∣ M1 = M2

∣∣ M1 < M2 . . .∣∣ if M1 then M2 else M3∣∣ λx .M∣∣ M1M2

x ∈ Vars

The constructs in red constitute Churchs’ λ-calculus

M1M2: apply function M1 to argument M2

λx .M: called λ-abstraction, define anonymous function which whenapplied to data N executes MN/x.Massimo Merro The Lambda language 5 / 21

Examples of anonymous functions

λx .x + 3- from numerals to numerals

λf .(f (2))- from functions to numerals

λx .if x = 0 then λy .y else λy .x- from numerals to functions

λf .λx .if x = 0 then 1 else (let y = f (x − 1)x × y in )- from functions to functions

λf .λg .λx .f (g(x))- from pairs of functions to functions.

Massimo Merro The Lambda language 6 / 21

Conventions

We recall the grammar given before describes the abstract syntax of thelanguage; when we come to write terms down concretely we will often usebrackets, as above, to clarify the structure of terms.

So, to keep brackets to a minimum in this part, we will use someconventions for writing λ-terms:

applications associates left: MNP means the same as (MN)P

the scope of λ extends as far to the right as possible: λx .MN meansλx .(MN), not (λx .M)N

we sometimes write λxy .M for λx .λy .M.

Massimo Merro The Lambda language 7 / 21

Free variables

The construct λx .M for function definition is the only bindingoperator.

In λx .M the variable x is bound in M which represents the scope of x .

Let us provide a formal definition of free variables by structuralinduction:

fv(x) = xfv(n) = fv(true) = fv(false) = ∅fv(M1 op M2) = fv(M1) ∪ fv(M2)fv(M1M2) = fv(M1) ∪ fv(M2)fv(λx .M) = fv(M) \ x

Closed terms

M is closed if fv(M) = ∅Closed terms corresponds to programs.

Massimo Merro The Lambda language 8 / 21

Small-step semantics

Judgements:

M _ N

where M and N are programs

Intuition:

M performs

one function application

or one built-in operation

and N remains to be evaluated.

Massimo Merro The Lambda language 9 / 21

Semantic rules

Standard rules:

(S-Left)M1 _ M ′

1

M1 + M2 _ M ′1 + M2

(S-Right)M2 _ M ′

2

n1 + M2 _ n1 + M ′2

(S-Add)−

n1 + n2 _ n3n3 = add(n1, n2)

Similar rules for ×, and , if then else, . . .

Massimo Merro The Lambda language 10 / 21

Function application

To evaluate M1M2:

First evaluate M1 to a function λx .M

Then it depends on the evaluation strategy.

If Call-by-value:

evaluate M2 to a value v

v ∈ Val ::= n∣∣ true

∣∣ false∣∣ λx .N

evaluate Mv/x.

If Call-by-name:

evaluate MM2/x

Massimo Merro The Lambda language 11 / 21

Function application rules

(L-App)M1 _ M ′

1

M1M2 _ M ′1M2

Call-by-value:

(L-CBV.A)M2 _ M ′

2

(λx .M)M2 _ (λx .M)M ′2

(L-CBV)−

(λx .M)v _ Mv/x

where v ∈ Val ::= n∣∣ true

∣∣ false∣∣ λx .N

Call-by-name

(L-CBN)−

(λx .M)M2 _ MM2/x

where M2 is a closed term (i.e. a program).

Massimo Merro The Lambda language 12 / 21

Substitution of closed terms

N closed:

xN/x = N

yN/x = y if y 6= x

(λx .M)N/x = λx .M

(λy .M)N/x = λy .MN/x if y 6= x

(M1M2)N/x = (M1N/x)(M2N/x)(M1 op M2)N/x = (M1N/x) op (M2N/x). . . . . .

N open:

requires α-conversion, i.e. renaming of bound variables.

Massimo Merro The Lambda language 13 / 21

Self-application

Is it possible to express non-terminating programs in Lambda?

Yes, of course!

For example, the divergent combinator

Ωdef= (λx .xx)(λx .xx)

contains just one redex, and reducing this redex yields exactly Ω again!

Ω _ Ω _ Ω _ . . . . . . Ω . . . . . .

Non-termination is built-in in Lambda!

Massimo Merro The Lambda language 14 / 21

Call-by-name vs. call-by-value

Note that unlike the Fpl language, having function definitions among theconstructs may lead to different results.

They give different results:

(λx .0)(Ω) _cbn 0

(λx .0)(Ω) _cbv (λx .0)(Ω) _cbv . . . _cbv . . .

Even more surprisingly:

(λx .λy .x)(Id 0) _∗cbn λy .(Id 0)

(λx .λy .x)(Id 0) _∗cbv λy .0

For different evaluation strategies see Benjamin C. Pierce’s “Types andProgramming Languages” at pp. 56.

Massimo Merro The Lambda language 15 / 21

Fixpoints

In Mathematics, a fixpoint p (also known as an invariant point) of afunction f is a point that is mapped to itself, i.e. f (p) = p.

Fixpoints represent the core of what is known as recursion theory.

Kleene’s recursion theorems are a pair of fundamental results aboutthe application of computable functions to their own descriptions.

The two recursion theorems can be applied to construct fixed pointsof certain operations on computable functions, to generate quines 1,and to construct functions defined via recursive definitions.

Kleene’s recursion theorems is used to prove a fundamental result incomputability theory: the Rice’s Theorem!

Rice’s Theorem: “For any non-trivial property of partial functions,there is no general and effective method to decide whether analgorithm computes a partial function with that property”.

1A quine is a computer program which produces a copy of its own source code as itsonly output.

Massimo Merro The Lambda language 16 / 21

Fixpoints (via Turing’s combinator)

So, it is very important to prove that Lambda can express fixpoints.

Let us define the two following terms in Lambda:

Adef= λx .λy .y(xxy)

fixdef= AA

fix is a recursive function that given a term M returns a fixpoint of M,denoted with fix M.

In fact, for any term M, using a call-by-name evaluation, we have:

fix M _ (λy .y(AAy))M

_ M(fix M) .

Very often this operator is denoted using the greek letter Θ.

Massimo Merro The Lambda language 17 / 21

Example: the factorial function

Fdef= λf .λx .if x = 0 then 1 else x × f (x − 1)

Facdef= ΘF

ΘF _∗ λx .if x = 0 then 1 else x ×ΘF (x − 1)

ΘF 3 _∗ (λx .if x = 0 then 1 else x ×ΘF (x − 1)) 3

_∗ 3 × ΘF 2

_∗ 3 × (λx .if x = 0 then 1 else x ×ΘF (x − 1)) 2

_∗ 3 × 2 × ΘF 1

_∗ 3 × 2 × 1 × ΘF 0

_∗ 3 × 2 × 1 × 1

_∗ 6

Massimo Merro The Lambda language 18 / 21

Fixpoints (via Curry’s combinator)

Notice that there are infinitely many forms of fixpoint combinators.Probably, the best known is the one by Curry and most commonly calledY :

Ydef= λf .(λx .f (xx))(λx .f (xx))

We can easily check that is has the required property:

Y Mdef=

(λf .

(λx .f (xx))(λx .f (xx)

))M

_(λx .M(xx))(λx .M(xx)

)_ M

((λx .M(xx))(λx .M(xx))

)=

M(Y M) _ M((λx .M(xx))(λx .M(xx))

)Massimo Merro The Lambda language 19 / 21

Applicative order fixpoint combinator

The Curry Y -combinator does not work in languages like Lisp, because ofthe applicative order (call-by-value) reduction strategy: Y M will keepevaluating forever.

A different fixpoint combinator does work, though: the applicative orderfixpoint combinator which is

λf .(λg .gg)(λx .f (λa.xxa))

or alternativelyλf .(λx .f (λa.xxa))(λx .f (λa.xxa))

Exercise

Check that this is a fixpoint combinator.

Notice that it only differs from Curry’s Y by replacing terms of the formxx with λa.xxa. Inserting this λ stops Lisp’s evaluation mechanism fromgetting into an infinite loop.

Massimo Merro The Lambda language 20 / 21

Some fun: Klop’s fixpoint combinator

Jan Klop came up with this ridiculous one: if we define

Ldef= λabcdefghijklmnopqstuvwxyzr .r(thisisafixedpointcombinator)

where

λabcdef . . . means λa.λb.λc .λd .λe.λf . . . .

thisisafixe... means ((((((((((th)i)s)i)s)a)f )i)x)e)....

thenLLLLLLLLLLLLLLLLLLLLLLLLLL (26 times)

is indeed a fixpoint combinator.

Exercise

Check that Klop’s combinator works. Hint: the phrase ”this is a fixedpoint combinator” contains 27 letters.

Massimo Merro The Lambda language 21 / 21