Replace Code with Documentation


You have source code with various in-line comments, comment blocks, and accompanying forms of documentation.

Make the documentation first class alongside the source code by restructuring them as a unified product.

Literate programming

Literate programming is not strictly a functional pattern. In practice it has been popularized by Haskell, so we'll let it slide and call it functionally-inspired.

Self-coding documentation

Consider an imaginary article about approaches to approximating Pi using recursive summation in Scala:

# Approximating Pi through recursive summation

## Abstract

This is an imaginary article about approaches to estimating Pi using
recursive summation in Scala.

## Background

Pi can be represented as the sum of an infinite series:

       ∞  (-1)
π = 4  ∑  ------
      k=0 2k + 1

## Initial implementation

Let's write a recursive function that can be used to estimate this sum.

First, we need a way to compute each kth term:

def term(k: Int): Double = {
  val n = 4 * math.pow(-1, k)
  val d = 2 * k + 1
  n / d.toDouble

Next, we need a way to sum them:

def pi(k: Int): Double =
  if (k < 0) 0
  else term(k) + pi(k - 1)

Let's try it out:

println(pi(1))    // 2.666666666666667
println(pi(10))   // 3.232315809405594
println(pi(100))  // 3.1514934010709914
println(pi(1000)) // 3.1425916543395442

That's close, but not close enough.  Unfortunately, this implementation
can't do much better:

println(pi(10000)) // Throws java.lang.StackOverflowError

Attempting to run merely ten thousand iterations overflows the stack!

## Improved implementation

To avoid blowing the stack, we need a tail-recursive version of this

def piTR(k: Int, acc: Double = 0): Double =
  if (k < 0) acc
  else piTR(k - 1, term(k) + acc)

Let's put it to the test:

println(piTR(100000000)) // 3.141592663589793

Computing one hundred million terms may take a while, but it since
`piTR` is tail-recursive, it does eventually finish.

Using literate programming tools such as Codedown and sbt-lit, we can treat this not as an article but as our source code, and keep code and documentation inextricably linked.


This file is literate Scala, and can be run using Codedown.

For presentation purposes, the source uses Scala code blocks wrapped in Markdown code blocks. To get to the Scala, we first need to first extract the Markdown with an extra codedown markdown invocation:

$ curl |
  codedown markdown |
  codedown scala |
  xargs -0 scala -nc -e