Theory and Design of PL (CS 538)
February 3, 2020
Principle: program behavior should be defined by behavior of its components
val = 𝔹 | ℤ | var | λ var . exprexpr = 𝔹 | ℤ
     | λ var . expr | expr expr
     | add(expr, expr) | sub(expr, expr)
     | and(expr, expr) | or(expr, expr)
     | if expr then expr else expr | ...true 11 + falseLanguage designer defines when e \Downarrow v
lotsOfOnes :: [Int]
lotsOfOnes = 1 : lotsOfOnes  -- [1, 1, ...
firstOne   = head lotsOfOnes -- Returns 1
onesAndTwos :: [Int]         -- [1, 2, 1, 2, ...
onesAndTwos = x where x = 1 : y
                      y = 2 : x
firstTwo = head $ tail onesAndTwos -- Returns 2
fibonacci :: [Int]           -- [1, 1, 2, 3, ...
fibonacci = 1 : 1 : zipWith (+) fibonacci (tail fibonacci)expr = ... | fix var . expr