Chicken egg that generates code from inline TeX
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.



This is early work in progress. It allows you to write inline TeX equations which get compiled to Scheme functions. Try out emacs and org-preview-latex if you're going to use this egg, it renders the TeX inside your buffer making is especially pleasant to read.

This module defines a reader macro #@"$...$". This is because character escaping is performed differently in TeX than in Scheme. Dollar signs are present to allow 'org-preview-latex' to find and render the inline LaTeX.

For example

  (tex #@"$\frac{1}{\sqrt{(2\pi)\sigma}}e^{-\frac{1}{2}\frac{x-\mu}{\sigma}}$")

which renders as

gaussian pdf

will compile to

  (lambda (x mu sigma)
     (r-/ (exp (r-neg (r-/ (r-/ (r-- x mu) sigma) 2)))
          (sqrt (r-* (r-* 2 pi) sigma))))

Unbound variables are turned into arguments and the argument order is the same as the occurence of the unbound variables in the TeX string. Functions starting with r- are generic functions that operate over various types, the idea being that you should be able to pass in input (numbers, lists, vectors, matrices) that is reasonable given the equation and get the right answer. This means that the generated code is slower than code written by hand because of all of the type checks.

To get code that's as good as we would write by hand schemetex has to do a bit of type inference, which you enable by using the tex* version of the macro:

  (tex* #@"$\frac{1}{\sqrt{(2\pi)\sigma}}e^{-\frac{1}{2}\frac{x-\mu}{\sigma}}$")

This will compile to

  (lambda (x mu sigma)
    (/ (exp (- (/ (/ (- x mu) sigma) 2)))
       (sqrt (* (* 2 pi) sigma))))

which is pretty much what you would write by hand. Sometimes type inference can't determine the type of a variable from the equation. For these cases you can specify the return type of the equation as well as the types of the variables. See the typed interface section at the bottom for details.

For longer equations you'll likely want to specify the arugment order:

  (tex #@"$f(x,y)=\sum_x\{x^2+y^3\}$")

The f is entirely ignored, but one day this syntax will allow for recursive and mutually recursive functions. For even more interesting equations you can use

  (tex-let ((x '(1 2 3))) #@"$\sum_x\{x^2+y^3\}$")


  (tex-let/value ((x '(1 2 3))) #@"$\sum_x\{x^2+y^3\}$")

which allow you to bind variables which ends up being much cleaner. The former produces a function while the latter produces a value.



(tex #@"$TeX$")
This is the basic interface. It compiles the TeX to Scheme at compile-time. For complex TeX equations with many parameters see tex-lex.

(tex-let ((x '(1 2 3))) #@"$\sum_x\{x^2+y^3\}$")
Binds x and produces a function with one argument y because y is unbound. If you want to produce a value instead of a function see tex-let/value.

(tex-let/value ((x '(1 2 3))) #@"$\sum_x\{x^2+y^3\}$")
Expands to code which produces a value instead of a function. Note that y here is unbound and will be captured from the enclosing scope.

(tex->lambda #@"$TeX$")
This will return the code produced for a particular TeX equation.


One day all macros from the untyped section will typed tex* versions.

The type system is intentionally pretty simple and intended to allow heterogenous collections. There are a only a small number of builtin types:

  n         number
  l         list
  v         vector
  m         matrix
  (-> a b)  function from type a to type b

For the moment you can't specify the types contained within matrices, lists, or vectors but these can generally be inferred from the context of the equation.

(tex* #@"$TeX$")
(tex* return-type #@"$TeX$")
(tex* return-type variable-type-alist #@"$TeX$")
(tex* return-type variable-type-alist #@"$TeX$" debugging?)
Like tex this produces a function. You can specify the type of any subset of variables. Pass #t to debugging? to see the inferred types. This is a bit difficult to read for now.

For example

  (tex* n ((f . (-> v (-> n n)))) #@"$f(x,2)$" #t)

will infer that x is a vector.


   Copyright 2012 Andrei Barbu. All rights reserved.
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   GNU Lesser General Public License for more details.
   You should have received a copy of the GNU Lesser General Public License
   along with this program.  If not, see