Among the huge variety of programming languages Haskell is interesting because of its cult status and proselytising zeal of its fans. An example like the one below is the best explanation why this has happened. These four lines are an implementation of the Sieve of Eratosthenes, a classical algorithm for listing prime numbers (G. Hutton, Programming in Haskell. Cambridge: Cambridge University Press, 2007):
> primes :: [Int]
> primes = sieve [2..]
> sieve :: [Int] => [Int]
> sieve (p : xs) = p : sieve [x | x <= xs, x `mod` p ≠ 0]
What happening here is that function sieve is applied to the infinite list
[2..] = [2, 3, 4, 5, 6, 7,...].
The function sieve takes as argument a list of integers and returns a list of integers; it accepts the first number p being prime and then calls itself recursively with a new list obtained by filtering out all multiples of p from the list. In Haskell, expressions are evaluated using call-by-name evaluation, not by call-by-value evaluation. This is like manipulating with symbols or formulae in a mathematical calculation and substituting the numerical values in an expression at the very last step. This method of evaluation results in the function primes returning a (potentially infinite, hardware limitations and the expected life span of the Solar System permitting) list of infinite numbers:
[2, 3, 5, 7, 11, 13, 17, …
For a mathematician, the above four lines of Haskell code are a revelation.
First of all, the programme (and the computer running this programme) appear to successfully manipulate with infinite sets. Secondly, the modest four lines of code simply brush aside the centuries long dispute about the actual and potential infinity and blend the apparently irreconcilable concepts together in the spirit of “internal set theory” (E. Nelson, Internal set theory, a new approach to NSA, Bulletin of the American Mathematical Society, 83 (1977), 1165-1198; A. M. Robert, Nonstandard Analysis. Mineola, NY: Dover Publications, 2003.): an infinite set is treated as a real object because it is given a name which is then used as a name of an actual object. On the other hand, we have access only to those elements in the set that we have already explicitly constructed. The set is like a cookies jar which contains only those cookies that we have put in it – but we can take the jar from a shelf and place it on a table regardless of how many cookies it contains.