a meditation on pure functional programming
a meditation on pure functional programming
In the beginning, there was the lambda calculus. Alonzo Church, working in the quiet corridors of Princeton in the 1930s, conceived a formal system of such austere beauty that it would take decades for the world to understand its implications. From that single insight -- that computation is nothing more than the application of functions to arguments -- an entire universe of programming emerged.
haskell.monster is a tribute to that lineage. Named for Haskell Brooks Curry, the logician whose work on combinatory logic laid the foundations for functional programming, and bearing the word "monster" as a nod to the magnificent, sometimes fearsome power of pure abstraction -- this site is an archive of ideas.
Here, purity is not a constraint but a liberation. Laziness is not sloth but wisdom. And types are not restrictions but proofs -- mathematical guarantees that your program means what you think it means. Welcome to the monster's library.
pure :: a -> f a
A pure function is a mathematical function in the truest sense: given the same input, it will always produce the same output. No side effects, no hidden state, no temporal dependencies. In Haskell, purity is not a guideline -- it is enforced by the type system. The world outside your function exists only through the IO monad, a controlled gateway between the mathematical and the material.
take 5 [1..] -- [1,2,3,4,5]
Haskell is lazy by default. Expressions are not evaluated until their results are needed. This seemingly simple idea has profound consequences: you can work with infinite data structures, compose computations without penalty, and let the runtime decide what to compute and when. Laziness transforms programming from imperative command into declarative description.
class Monad m where (>>=) :: m a -> (a -> m b) -> m b
Haskell's type system is its crown jewel. Built on the Hindley-Milner foundation with extensions reaching into dependent types and type-level programming, it transforms the compiler into a proof assistant. Types are not annotations for the machine -- they are theorems about your program. If it compiles, it is very likely correct.
Alonzo Church publishes his paper on the lambda calculus, establishing the theoretical foundation for functional programming.
John McCarthy creates LISP at MIT, the first functional programming language, bringing Church's lambda calculus to life in code.
Peter Landin publishes "The Next 700 Programming Languages," envisioning a future built on functional foundations.
John Backus delivers his Turing Award lecture, "Can Programming Be Liberated from the von Neumann Style?" advocating functional programming.
The Haskell Committee forms at the FPCA conference in Portland. The goal: an open standard for a purely functional, lazy programming language.
Haskell 1.0 is released, named after Haskell Brooks Curry. The monster is born.
The Haskell 98 Report is revised. GHC becomes the de facto compiler. The ecosystem matures.
Haskell 2010 is published. The language continues to evolve through GHC extensions, pushing the boundaries of type theory in practice.
-- The Sieve of Eratosthenes
-- An elegant demonstration of lazy evaluation
module Main where
primes :: [Integer]
primes = sieve [2..]
sieve :: [Integer] -> [Integer]
sieve (p:xs) =
p : sieve [x | x <- xs, x `mod` p /= 0]
main :: IO ()
main = do
putStrLn "The first 20 primes:"
print (take 20 primes)