Replace Code with Documentation

Summary

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:

```
              k
       ∞  (-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:

```scala
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:

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

Let's try it out:

```scala
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
function:

```scala
@scala.annotation.tailrec
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:

```scala
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.

Demo

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 https://earldouglas.com/posts/itof/code-to-doc.md |
  codedown markdown |
  codedown scala |
  xargs -0 scala -e
2.666666666666667
3.232315809405594
3.1514934010709914
3.1425916543395442
3.141592663589793