一句话:以 Bird 的循环埃拉托斯特尼筛为例,探讨其生产性证明,并把它作为 Turner 总体函数式编程的挑战问题。
文章回顾 Turner 对惰性求值和列表推导的推广,特别是他普及的一行递归素数生成程序,即所谓埃拉托斯特尼筛。O’Neill 指出该程序并非真正筛法并用优先队列给出忠实实现;Bird 提出仅用列表与循环编程的变体。Bird 在教材中再次描述该循环程序并把正确性证明留作练习,但其提示有误。本文追问该循环程序为何具有生产性,正确证明应如何构造,并将 Bird 的循环筛作为 Turner“总体函数式编程”的挑战问题,讨论结构递归/余递归对终止性与生产性的保证,以及总体函数式风格能否覆盖此类算法。
Abstract Functional programmers have many things for which to thank the late David Turner: design decisions he made in his languages SASL, KRC, and Miranda over the last 50 years are still influential and inspirational now. In particular, Turner was a strong advocate of lazy evaluation and of list comprehensions. As an illustration of these techniques, he popularized a one-line recursive “sieve” to generate the infinite list of prime numbers. Turner called this algorithm The Sieve of Eratosthenes. In a lovely paper called “The Genuine Sieve of Eratosthenes”, Melissa O’Neill argued that Turner’s program is not in fact a faithful implementation of the algorithm, and gave a detailed presentation using priority queues of the real thing. She included a variation by Richard Bird, which uses only lists but makes clever use of circular programming. Bird describes his circular program again in his textbook “Thinking Functionally with Haskell”, and sets its proof of correctness as an exercise. In particular, why is this circular program productive? Unfortunately, Bird’s hint for a solution is incorrect. So what should a proof look like? One of the last projects Turner worked on was the notion of “Total Functional Programming”. He observed that most programs are already structurally recursive or corecursive, therefore guaranteed respectively terminating or productive; he conjectured that “with more practice we will find this is always true”. We explore Bird’s circular Sieve of Eratosthenes as a challenge problem for Turner’s Total Functional Programming.