via statements. • Based on the Von Neumann computer architecture • Models implementa6on details of the computer (or what the computer used to be) • program variables ↔ computer storage cells • control statements ↔ computer test-and-jump instruc6ons • assignment statements ↔ fetching, storing instruc6ons • expressions ↔ memory reference and arithme6c instruc6ons.
transi1on • Poorly suited to concurrent and parallel computa1on • Lacks a useful founda1on fom which to reason about computa1on • correctness, testability, etc.
• Dynamic and repe55ve; to understand it you must mentally execute it • Computes the result word-at-a-5me by repe55on of assignment and modifica5on • Entangles housekeeping opera5ons with the rest of the code, making them impossible to extract and reuse
m; double[,] a; public Matrix(int n, int m) { if (n <= 0 || m <= 0) throw new ArgumentException("Matrix dimensions must be positive"); this.n = n; this.m = m; a = new double<n, m>; } //indices start from one public double this<int i, int j> { get { return a[i - 1, j - 1]; } set { a[i - 1, j - 1] = value; } } public int N { get { return n; } } public int M { get { return m; } } public static Matrix operator*(Matrix _a, Matrix b) { int n = _a.N; int m = b.M; int l = _a.M; if (l != b.N) throw new ArgumentException("_a.M must be equal b.N"); Matrix result = new Matrix(_a.N, b.M); for(int i = 0; i < n; i++) for (int j = 0; j < m; j++) { double sum = 0.0; for (int k = 0; k < l; k++) sum += _a.a[i, k]*b.a[k, j]; result.a[i, j] = sum; } return result; } }
You cannot pass them as arguments to a func6on • You cannot build higher abstrac6ons from them • No formal “algebra” by which to op6mize or evaluate the correctness of programs. • statements cannot be reduced (operate on hidden state) • None of their uses are unique to statements • usually used to approximate expression composi6on in an impera6ve way.
expression and, if true, returns the result of evalua6ng the then expression; otherwise, returns the result of evalua6ng the else expression eq(a, b) If a is func)onally equivalent to b, returns true; otherwise, false
language • Func&ons can be passed as arguments to other func&ons • Higher Order func&ons: • Func&ons that take func&ons as arguments or return func&ons as results
a set of poten'al outputs with the property that each input is related to exactly one output. • Implies no side-effects • Enables referen%al transparency • an expression can be replaced with its value without changing the behavior of a program • Makes many op7miza7ons possible (e.g., memoiza7on) • Work hand-in-hand with immutable data
created • New values are func%ons of old values • Values can always be observed and new values calculated from old values without coordina8on • Values will never change "in hand" • Values can be safely shared between threads • No need for defensive copying (or any copying)
the hood • safe to do share data between data- structures because all data is immutable • Unreachable data can be garbage- collected at op7mal granularity • Crea7ng new data-structures from exis7ng ones requires li=le or no copying of member data
did, they'd be different values) • e.g., 72, {–, ‖, —, ―}, "cat", [2, 3, 5, 7] • An IdenGty is an enGty that is associated with different values over Gme • State is a value at a point in Gme • IdenGGes give us conGnuity across state changes
been adding or seen widespread adop7on the aforemen7oned features at an increasingly rapid pace • Java Lambdas • Ruby Lazy Sequences • JavaScript ImmutableJS • For the past 50+ years impera7ve languages have been slowly adding func7onal features • Adding func7onal features to impera7ve languages is a double-edged sword (complexity, sub-op7mal implementa7on)
func%onal language, rather than using a func%onal style in an impera%ve language is: • Simpler, and o;en easier • Allows you to lean on features (e.g., pure func%ons and immutable data) • O;en more performant (e.g., persistent immutable datastructures)