Functional Programming Flashcards
Untyped lambda-calculus
N ::= x | λx.N | NN
Variable capture
When a term with free variable x is substituted inside λx.N, by which the variable x becomes bound.
Simple type syntax
τ ::= o | τ → τ
Outermost reduction
- Given a redex (λx.N)M, reduces the redex before any reductions in N and M
- Guarantees to reach normal form but duplicates work as much as possible
Innermost reduction
- Given a redex (λx.N)M, reduces the redex after any reductions in N and M
- Does not duplicate work but does not necessarily reach normal form
Zip
zip :: [a] -> [b] -> [(a,b)]
zip _ [] = []
zip [] _ = []
zip (x:xs) (y:ys) = (x,y) : zip xs ys
Weakly normalising term
- A term that has reduction to normal form
- For example, (λy.x)((λx.xx)(λx.xx))
Strongly normalising term
- A term that is weakly normalising and has no infinite reduction sequence
- For example, (λy.x)(λx.xx)
Example term that is neither weakly nor strongly normalizing
(λx.xx)(λx.xx)
Fixed-point combinator
- A fixed-point combinator is a λ-term F that satisfies M =β F M for any M, where β is beta-equivalence
- For example: λf.(λx.f(xx))(λx.f(xx))
Fixed-point combinator proof
For any lambda-term M, Y M = β M(Y M)
Y M
→ (λx.M(xx))(λx.M(xx))
→ M((λx.M(xx))(λx.M(xx)))
← M(Y M)
Capture-avoiding substitution
M[y/x] = M with x renamed to y
Examples of capture-avoiding substitution
1) Example: (λx.xy)[λz.z/y]
This means change y to λz.z
Therefore = λx.x(λz.z)
2) Example: (λx.xy)[λz.zx/y]
Therefore = λw.w(λz.zx)
The x changes to w to avoid capturing the free x in λz.zx
3) Example: (f(λx.yx)yx)[fy/x]
Therefore = f(λx.yx)y(fy)
The bound x in λx.yx is not substituted
4) Example: (λf.f(λx.yx)yx)[fy/x]
Therefore = λg.g(λx.yx)y(fy)
The bound f is renamed to g avoiding capturing the free f
Church-Rosser Property
- M =β N if and only if there is a term P s.t. M → ∗β P and N → ∗β P
- This proves that a lambda term can’t have more than one normal form
Confluence
Whenever M →∗ N1 and M →∗ N2, there is some P such that N1 →∗ P and N2 →∗ P
Local Confluence
Whenever M → N1 and M → N2, there is some P such that N1 →∗ P and N2 →∗ P
Free and bound variables
If the first occurrence of a variable appears when defining a lambda, then it is bound to that lambda.
For example, in λx.x, variable x is bound as it first occurs in λx
Otherwise, it is a free variable. For example, in (λx.x)(λy.yx):
- the variable x in λx.x is bound to
the first lambda
- the variable y in λy.yx is bound to
the second lambda
- the variable x in λy.yx is free
Example 3 - (λx.xy)(λy.y):
- the variable y in λx.xy is free
- the variable y in λy.y is bound to the second lambda
Lazy evaluation
- A reduction strategy that uses graphs to ensure a term is evaluated at most once, if its result is needed for the overall computation, and otherwise not evaluated at all.
- When a redex (λx.M)N is reduced, instead of substituting N for every free variable x in M, each variable x functions as a pointer to N.
- Then N is evaluated at most once, and when its output is needed after that, the stored result is used
- It always reaches normal form if one exists, and is efficient since it doesn’t evaluate terms more than once
Fixed point in the λ-calculus
- A λ-term M such that M = βF M
- Every term in the lambda calculus has a fixed point
Simply typed lambda-calculus
M ::= x | λx^τ.M | MM
Typing rules
Referential transparency
- Means that the output of a function depends only on its inputs and not on other, less visible factors
- A function that always returns the same values given the same inputs
- Lazy evaluation needs referential transparency otherwise the evaluation steps do not preserve the meaning of a program
Computational effects
- May give different outputs on different occasions, even with the same input
- They destroy referential transparency
Functions that use computational effects
- Example 1: mutable state
- This interferes with referential transparency because the stored values in the state may have changed
- Example 2: random values
- This interferes with referential transparency because the random number generator may produce different numbers each time
- Example 3: user inputs
- This interferes with referential transparency because a user may give different input on
each occasion