SLIDE 1 equational programming 2020 10 26 lecture 1
introductory remarks lambda terms towards beta reduction
introductory remarks lambda terms towards beta reduction
functional programming
a functional program is an expression, and is executed by evaluating the expression (use definitions from left to right) focus on what and not so much on how the functions are pure (or, mathematical) an input always gives the same output the course is about the foundations of functional programming
SLIDE 2
example functional programming style
in Haskell: applying functions to arguments sum [1 .. 100] in Java: changing stored values total = 0; for (i = 1; i < 100; ++i) total = total + i;
taste of Haskell
definition of sum: sum [] = 0 sum (n:ns) = n + sum ns type of sum: Num a => [a] -> a that is: for any type a of numbers, sum maps a list of elements of a to a use of sum: application of the function sum to the argument [1,2,3] sum [1,2,3]
evaluation by equational reasoning
definition: double x = x + x evaluation: double 2 = { unfold definition double } 2 + 2 = { applying + } 4 double (double 2) = { unfold definition inner double } double (2 + 2) = {unfold definition double } (2 + 2) + (2 + 2) = {apply first +} 4 + (2+2) = {apply last +} 4 + 4 = {apply +} 8
functional programming: properties
high level of abstraction concise programs more confidence in correctness (read, check, prove correct) higher-order functions foundations: equational reasoning and λ-calculus
SLIDE 3
Haskell: properties
lazy evaluation strategy static typing type inference system purely functional ]
functional programming: some history
Lisp John McCarthy (1927–2011), Turing Award 1971 FP John Backus (1924–2007), Turing Award 1977 ML Robin Milner (1934-2010), Turing Award 1991, et al Miranda David Turner (born 1946)
Haskell
Haskell a group containing ao Philip Wadler and Simon Peyton Jones
functional programming languages
typed untyped strict ML Lisp lazy Haskell See also F# (Microsoft), Erlang (Ericsson), Scala (Java plus ML)
SLIDE 4 functional programming and lambda calculus
Based on the lambda calculus, Lisp rapidly became ... (from: wikipedia page John McCarthy) Haskell is based on the lambda calculus, hence the lambda we use as a logo. (from: the Haskell website) Historically, ML stands for metalanguage: it was conceived to develop proof tactics in the LCF theorem prover (whose language, pplambda, a combination of the first-order predicate calculus and the simply typed polymorphic lambda calculus, had ML as its metalanguage). (from: wikipedia page of ML)
course equational programming (EP)
lambda calculus equational specifications exercises functional programming: Haskell
introductory remarks lambda terms towards beta reduction
lambda calculus
inventor: Alonzo Church (1936) a language expressing functions or algorithms concept of computability and basis of functional programming a language expressing proofs untyped and typed
SLIDE 5 historical note: notation for functions
Frege defined the graph of a function (1893) Russell and Whitehead and Russell (1910) Sch¨
- nfinkel defined function calculus (1920)
Curry defined combinary logic (1920)
language and theory
alphabet Σ: finite set of symbols language L ⊆ Σ∗: set of sentences over the alphabet theory T ⊆ L: set of correct sentences equational theory sentences of the form l = r with l and r ‘terms’ in Σ∗
notation for (anonymous) functions
mathematical notation: f : N → N f (x) = x2
f : N → N f : x → x2 lambda notation for functions: λx. x2 and notation for application of a function to an argument: (λx. x2) 7
lambda terms: intuition
abstraction: λx. M is the function mapping x to M λx. x is the function mapping x to x λx. x2 is the function mapping x to x2 application: F M is the application of the function F to its argument M (not the result of applying)
SLIDE 6 from alphabet to langage: inductive definition of lambda terms
we assume a countably infinite set of variables (x, y, z . . .) sometimes we in addition assume a set of contstants the set of λ-terms is defined inductively by the following clauses: a variable x is a λ-term a constant c is a λ-term if M is a λ-term, then (λx. M) is a λ-term, called an abstraction if F and M are λ-terms, then (F M) is a λ-term, called an application
famous terms
I = (λx. x) K = (λx. (λy. x)) S = (λx. (λy. (λz. ((x z) (y z))))) Ω = ((λx. (x x)) (λx. (x x)))
- mit outermost parentheses
abstraction is associative to the right application is associative to the left lambda extends to the right as far as possible
terms as trees: example
x λx
y @
❅
x
terms as trees: general
x M λx F M @
a subterm corresponds to a subtree subterms of λx. y are λx. y and y
SLIDE 7 parentheses
application is associative to the left (M N P) instead of ((M N) P)
- utermost parentheses are omitted
M N P instead of (M N P) lambda extends to the right as far as possible λx. M N instead of λx. (M N) sometimes we combine lambdas λx1 . . . xn. M instead of λx1 . . . . λxn. M (λx. λy. M) instead of (λx. (λy. M)) (M λx. N) instead of (M (λx. N)) λxy. M instead of λx. λy. M
inductive definition of terms
definitions recursively on the definition of terms example: definition of the free variables of a term proofs by induction on the definition of terms example: every term has finitely many free variables
bound variables: definition
x is bound by the first λx above it in the term tree examples: the underlined x is bound in λx. x λx. x x (λx. x) x λx. y x λx. λx. x
free variables: definition
a variable that is not bound is free alternatively: define recursively the set FV(M) of free variables of M: FV(x) = {x} FV(c) = ∅ FV(λx. M) = FV(M)\{x} FV(F P) = FV(F) ∪ FV(P) a term is closed if it has no free variables
SLIDE 8
introductory remarks lambda terms towards beta reduction
from language to theory
β-axiom: (λx. M) N = M[x := N] ( what is this? ) reflexivity, symmetry, transitivity: M = M if M = N then N = M if M = N and N = P then M = P compatible with term formation: if M = N then L M = L N if M = N then M R = N R if M = N then λx. M = λx. N
examples
(λx. M) N = M[x := N] M[x := N] is the result of substituting N for the free occurrences of x in M (λx. x2) 7 = 72 = 49 (λx. x + 3) 7 = 7 + 3 = 10 (λx. x + x) 7 = 7 + 7 = 14 (λx.5) 7 = 5 and also in a ‘context’: λy. (λx.5) 7 = λy. 5, and ((λx.5) 7) z = 5 z, and z ((λx.5) 7) = z 5
theory about computation: use the axiom from left to right
β-axiom: (λx. M) N →β M[x := N] compatible with term formation: if M →β N then L M →β L N if M →β N then M R →β N R if M →β N then λx. M →β λx. N
SLIDE 9
examples
(λx. M) N →β M[x := N] M[x := N] is the result of substituting N for the free occurrences of x in M (λx. x2) 7 →β 72 = 49 (λx. x + 3) 7 →β 7 + 3 = 10 (λx. x + x) 7 →β 7 + 7 = 14 (λx.5) 7 →β 5 and also in a ‘context’: λy. (λx.5) 7 →β λy. 5, and ((λx.5) 7) z →β 5 z, and z ((λx.5) 7) →β z 5
the definition of substitution needs more care
((λx. λy. x) y) z →β (λy. y) z →β z This is incorrect! It should be: ((λx. λy′. x) y) z →β (λy′. y) z →β y
intuitive approach to solution
we work ‘modulo renaming of bound variables’, or α-conversion we rename (use another representative of the same α-equivalence class) whenever necessary to avoid capturing of free variables we define substitution recursively: x[x := N] = N a[x := N] = a with a = x a variable or a constant (P Q)[x := N] = (P[x := N]) (Q[x := N]) (λx. P)[x := N] = λx. P (λy. P)[x := N] = λy. (P[x := N]) (so: we assume that λy does not capture free occurrences of y in N)
substitution: examples
(λx. x)[x := c] = λx. x (λx. y)[y := c] = λx. c (λx. y)[y := x] = λz. x (λy. x (λw. v w x))[x := u v] = λy. u v(λw. v w (u v)) (λy. x (λx. x))[x := λy. x y] = λy.(λy. x y) (λx. x)