Functional and display math in technical documents

| categories: emacs, orgmode | tags:

I have been thinking about a way to have functional and readable mathematics in technical documents. It has always bothered me that I have to write a LaTeX version of an equation, and then a separate implementation of the equation in code somewhere. At least twice in my life these separate representations have not agreed!

One solution might be if my functional code could be converted to LaTeX easily. I explore one simple approach to this here. It is somewhat inspired by this work here on writing LaTeX in emacs-lisp, and from my work with org-mode in mixing narrative text, LaTeX and code.

The idea is to use emacs-lisp for the code, so it is functional, but provide an alternative output for the same code for a document conversion. In other words, we accept there is more than one version we need: a functional version for working, and a consumption version for presentation. We will generate the consumption version from the functional version.

I know emacs-lisp is not ideal for mathematics the way we are accustomed to seeing it, but it enables the idea I want to explore here so we will try it.

Here is the simplest example I could come up with for functional math. We can run it ourselves, and verify it is correct.

(+ 1 2 3)

Now, I can change the meaning of this code temporarily, so that it not only evaluates the form, but also represents the equation and result in LaTeX code. If this was incorporated into a preprocessor of the document, we could have a functional version representing our equations, in code form, and a presentation version generated from this version. The code that follows isn't how I would do this is in some production setting; it is only to show that you can temporarily change the meaning of "+". In a production setting, there would just be (+ 1 2 3) in the text, and a preprocessor would find all the sexps in the text, and replace them with the export format using code like this. At least, that is what I am imagining. It might be feasible to do this already with inline org-babel calls and an org-mode export filter, but I didn't try it here. So, here is the proof of concept code.

(cl-flet ((+ (lambda (&rest args)
                "$%s = %s$"
                (mapconcat #'number-to-string args " + ")
                (eval `(+ ,@args))))))
  (+ 1 2 3))

\(1 + 2 + 3 = 6\)

Here is an example that generates a fraction from a division.

(cl-flet ((/ (lambda (&rest args)
                "$\\frac{%s}{%s} = %s$"
                (car args)
                (mapconcat 'number-to-string (cdr args) " \\cdot ")
                (eval `(/ ,@args))))))
  (/ 1.0 2.0 3.0))

\(\frac{1.0}{2.0 \cdot 3.0} = 0.16666666666666666\)

As a proof of concept, this idea looks feasible, but this implementation has some limitations. Getting this to a complete workable approach would require a lot of work, basically creating transformation functions for many, many kinds of mathematical functions, and a lot of other kinds of logic. For example, (+ 1 2 (+ 3 4)) would not render correctly with the codes above. It isn't even clear what it should render to. I think you want 1 + 2 + (3 + 4) as the rendered output.

Anyway, it is an interesting idea, one that blurs the lines between code and mathematics. We are so used to the equation representation of mathematics, rather than the code representation that being able to go back and forth seems like a good idea, especially when one is derived from the other.

Copyright (C) 2015 by John Kitchin. See the License for information about copying.

org-mode source

Org-mode version = 8.2.10

Discuss on Twitter