# The infix-math Reference Manual

Next: , Previous: , Up: (dir)   [Contents][Index]

# The infix-math Reference Manual

This is the infix-math Reference Manual, generated automatically by Declt version 4.0 beta 2 "William Riker" on Wed Jun 15 04:50:43 2022 GMT+0.

# Infix-Math

Infix-Math is a library that provides a special-purpose syntax for transcribing mathematical formulas into Lisp.

Bitter experience has taught me that the more the formula on screen resembles the formula on paper, the better. The more the formula on screen resembles the formula on paper, the easier it is to prevent bugs from transcription errors. The easier it is to prevent transcription errors, the easier it is to trace the source of any bugs that do occur – because sometimes the formula is wrong.

(Having to transcribe formulas from crooked, blurry scans of ancient pre-LaTeX typescripts is bad enough without having to parse operator precedence in your head.)

Even if you end up rewriting the formula for speed or numerical stability, having the specification in an executable form is invaluable for reference and testing.

## Examples

The macro `\$` is the entry point into Infix-Math.

``````(\$ 2 + 2)     => 4
(\$ 1 + 2 * 3) => 7
``````

Operator precedence parsing in Infix-Math is reliable – it uses Dijkstra’s shunting yard algorithm.

The parser automatically descends into function argument lists, which means that the total number of parentheses is never greater than it would be in a purely infix language.

``````(\$ (tan pi * (p - 1/2)))
≡ (tan (* pi (- p 1/2)))
≅ tan(pi*(p-0.5))
``````

Common subexpression elimination is automatic and aggressive. All forms are assumed to be pure. Math does not have side effects.

``````(macroexpand '(\$ 2 ^ 2x * 2 ^ 2x)
=> ‘(let ((#:subexp11325 (^ 2 (* 2 x))))
(* #:subexp11325 #:subexp11325))
``````

Infix-Math knows about the following arithmetic and bitwise operators, in descending order of precedence.

• unary -, sqrt
• expt, log
• *, /, rem, mod, floor, ffloor, ceiling, fceiling, truncate, ftruncate, round, fround, scale-float, gcd, lcm, atan
• +, -
• ash
• logand, logandc1, logandc2, lognand
• logxor, logeqv
• logior, logorc1, logorc2, lognor
• min, max
• over

Operations at the same level of precedence are always evaluated left-to-right.

``````(+ 0.1d0 (+ 0.2d0 0.3d0)) => 0.6d0
(+ (+ 0.1d0 0.2d0) 0.3d0) => 0.6000000000000001D0
(\$ 0.1d0 + 0.2d0 + 0.3d0) => 0.6000000000000001D0
``````

Parentheses can be used for grouping.

``````(\$ 0.1d0 + (0.2d0 + 0.3d0)) => 0.6d0
``````

Variables can be written with literal numbers as coefficients.

``````(\$ 2x)  => 10
(\$ -2x) => 10
``````

Literal coefficients have very high priority.

``````(\$ 2 ^ 2 * x) ≡ (* (expt 2 2) x)     => 20
(\$ 2 ^ 2x)    ≡ (expt 2 (* 2 x))     => 1024
``````

A literal coefficient of 1 can be omitted.

``````(\$ -x) ≡ (\$ -1x) ≡ (* -1 x)
``````

Literal coefficients are parsed as decimals, rather than floats.

``````(\$ 1.5x) ≡ (* 3/2 x)
``````

You can also use fractions as literal coefficients.

``````(\$ 1/3x) ≡ (* 1/3 x)
``````

Among other things, literal coefficients are very convenient for units of measurement.

(The idea for literal coefficients comes from Julia.)

## Symbols

Infix-Math exports only five symbols: `\$`, `^`, `over`, and two macros for declaring operators: `declare-unary-operator` and `declare-binary-operator`.

The symbol `^` is just a shorthand for `expt`.

``````(\$ 1 + 2 * 3 ^ 4) => 163
``````

(`^` is from Dylan.)

The symbol `over` represents the same operation as `/`, but at a much lower priority. Using `over` lets you avoid introducing parentheses for grouping when transcribing fractions.

``````(setf x 5)
(\$ x * 2 / x * 3)     ≡ (* (/ (* x 2) x) 3) => 6
(\$ (x * 2) / (x * 3)) ≡ (/ (* x 2) (* x 3)) => 2/3
(\$ x * 2 over x * 3)  ≡ (/ (* x 2) (* x 3)) => 2/3
``````

You can also spell `over` with a series of dashes or underscores.

``````(\$ x * 2
-----
x * 3)
=> 2/3
``````

If you want more math symbols, the package `infix-math/symbols` provides a few more.

## Calculator

You can use Infix-Math to turn your REPL into a calculator.

First, load the `infix-math/calc` system:

``````(asdf:load-system "infix-math/calc")
``````

Then, at the REPL, start the calculator:

``````(infix-math/calc:calc)
``````

This will put you at a calculator prompt. You can type in mathematical expressions directly:

``````\$> 2 + 2
4
``````

A single form entered at the REPL is interpreted as ordinary CL.

``````\$> *package*
:infix-math/calc-user
``````

You can assign to variables using the `<-` operator.

``````\$> x <- 2 + 2
4
\$> x
4
``````

Certain one-letter variables are provided for you to assign to, such as `x`, `y`, and `z`. You can see the full list by evaluating `:v` at the calculator prompt.

To quit, use `:q`. The value of the last expression evaluated will be returned.

``````\$> 2 + 2
4
\$> :q
4
CL-USER> *
4
``````

## Extending

Infix-Math is easily to extend. In fact, you may not even need to extend it.

Any symbol that consists entirely of operator characters is interpreted as an infix operator, with the highest non-unary priority. Operator characters are anything but dashes, underscores, whitespace or alphanumeric characters.

``````(defun <*> (x y)
"Matrix multiplication, maybe."
...)

(macroexpand '(\$ x * y <*> z)) => (* x (<*> y z))
``````

(This approach is taken from Haskell.)

You can use any function as an infix operator by surrounding its name with dots.

``````(defun choose (n k)
"Binomial coefficient, maybe."
...)

(macroexpand '(\$ n .choose. k)) => '(choose n k)
``````

Again, the operator has the highest non-unary priority.

(This approach is taken from Haskell and Fortran.)

If you need more flexibility, declare the operators using `declare-binary-operator` or `declare-unary-operator`.

To declare a unary operator:

``````(declare-unary-operator √)
``````

To copy the precedence of another operator:

``````(declare-binary-operator <*> :from *)
``````

To declare an operator right-associative:

``````(declare-binary-operator ?
:from *
:right-associative t)
``````

## 2 Systems

The main system appears first, followed by any subsystem dependency.

Next: , Previous: , Up: Systems   [Contents][Index]

### 2.1 infix-math

An extensible infix syntax for math in Common Lisp.

Author

Paul M. Rodriguez <pmr@ruricolist.com>

MIT

Defsystem Dependency

asdf-package-system (system).

Dependency

infix-math/infix-math (system).

Source

Next: , Previous: , Up: Systems   [Contents][Index]

### 2.2 infix-math/infix-math

Author

Paul M. Rodriguez <pmr@ruricolist.com>

MIT

Dependencies
Source

### 2.3 infix-math/symbols

Author

Paul M. Rodriguez <pmr@ruricolist.com>

MIT

Source

Previous: , Up: Systems   [Contents][Index]

### 2.4 infix-math/data

Author

Paul M. Rodriguez <pmr@ruricolist.com>

MIT

Dependencies
Source

## 3 Files

Files are sorted by type and then listed depth-first from the systems components trees.

Previous: , Up: Files   [Contents][Index]

### 3.1 Lisp

#### 3.1.1 infix-math/infix-math.asd

Source
Parent Component

infix-math (system).

ASDF Systems

#### 3.1.2 infix-math/infix-math/file-type.lisp

Source
Parent Component

infix-math/infix-math (system).

Packages
Public Interface

\$ (macro).

Internals

#### 3.1.3 infix-math/symbols/file-type.lisp

Source
Parent Component

infix-math/symbols (system).

Packages
Public Interface
• % (compiler macro).
• % (function).
• & (compiler macro).
• & (function).
• << (compiler macro).
• << (function).
• >> (compiler macro).
• >> (function).
• ^ (compiler macro).
• ^ (function).
• over (compiler macro).
• over (function).
• × (compiler macro).
• × (function).
• ÷ (compiler macro).
• ÷ (function).
• π (symbol macro).
• (compiler macro).
• (function).
Internals

#### 3.1.4 infix-math/data/file-type.lisp

Source
Parent Component

infix-math/data (system).

Packages
Public Interface
Internals

## 4 Packages

Packages are listed by definition order.

Next: , Previous: , Up: Packages   [Contents][Index]

Source
Nickname

infix-math

Use List
Public Interface

\$ (macro).

Internals

### 4.2 infix-math/symbols

Source
Use List

common-lisp.

Used By List
Public Interface
• % (compiler macro).
• % (function).
• & (compiler macro).
• & (function).
• << (compiler macro).
• << (function).
• >> (compiler macro).
• >> (function).
• ^ (compiler macro).
• ^ (function).
• over (compiler macro).
• over (function).
• × (compiler macro).
• × (function).
• ÷ (compiler macro).
• ÷ (function).
• π (symbol macro).
• (compiler macro).
• (function).
Internals

Previous: , Up: Packages   [Contents][Index]

Source
Use List
Used By List
Public Interface
Internals

## 5 Definitions

Definitions are sorted by export status, category, package, and then by lexicographic order.

Next: , Previous: , Up: Definitions   [Contents][Index]

### 5.1 Public Interface

Next: , Previous: , Up: Public Interface   [Contents][Index]

Symbol Macro: π
Package
Source

#### 5.1.2 Macros

Macro: \$ (&rest formula)

Compile a mathematical formula in infix notation.

Package
Source
Macro: declare-binary-operator (new &body &key)
Package
Source
Macro: declare-unary-operator (name)
Package
Source
Macro: unary (op arg)

Pretend unary operators are binary operators.

Package
Source

#### 5.1.3 Compiler macros

Compiler Macro: % (a b)
Package
Source
Compiler Macro: & (a b)
Package
Source
Compiler Macro: << (a b)
Package
Source
Compiler Macro: >> (a b)
Package
Source
Compiler Macro: ^ (a b)
Package
Source
Compiler Macro: over (a b)
Package
Source
Compiler Macro: × (a b)
Package
Source
Compiler Macro: ÷ (a b)
Package
Source
Compiler Macro: (a)
Package
Source

Next: , Previous: , Up: Public Interface   [Contents][Index]

#### 5.1.4 Ordinary functions

Function: % (a b)
Package
Source
Function: & (a b)
Package
Source
Function: << (a b)
Package
Source
Function: >> (a b)
Package
Source
Function: ^ (a b)
Package
Source
Function: operator? (operator)
Package
Source
Function: over (a b)
Package
Source
Function: precedence (operator)
Package
Source
Function: (setf precedence) (operator)
Package
Source
Function: right-associative? (operator)
Package
Source
Function: (setf right-associative?) (operator)
Package
Source
Function: trim-dotted-operator (operator)
Package
Source
Function: unary? (operator)
Package
Source
Function: (setf unary?) (operator)
Package
Source
Function: × (a b)
Package
Source
Function: ÷ (a b)
Package
Source
Function: (a)
Package
Source

#### 5.1.5 Types

Type: precedence ()
Package
Source

### 5.2 Internals

Next: , Previous: , Up: Internals   [Contents][Index]

#### 5.2.1 Special variables

Special Variable: *order-of-operations*

Basic C-style operator precedence, with some differences.

The use of MIN, MAX, GCD and LCM as infix operators is after Dijkstra (see EWD 1300). Perl 6 is also supposed to use them this way, and I have adopted its precedence levels.

Package
Source
Special Variable: *precedence*

Table of operator precedence.

Package
Source
Special Variable: *right-associative*
Package
Source
Special Variable: *unary*
Package
Source

Next: , Previous: , Up: Internals   [Contents][Index]

Symbol Macro: e
Package
Source
Symbol Macro: i
Package
Source

#### 5.2.3 Macros

Macro: binary-operator (new old)
Package
Source
Macro: binary-operators (&body body)
Package
Source
Macro: nodef (place operator)
Package
Source
Macro: unary-operator (new old)
Package
Source
Macro: unary-operators (&body body)
Package
Source

Next: , Previous: , Up: Internals   [Contents][Index]

#### 5.2.4 Ordinary functions

Function: ash- (i c)
Package
Source
Function: dotted-operator? (sym)
Package
Source
Function: eliminate-common-subexpressions (form &optional env)
Package
Source
Function: expand-expression (exprs)
Package
Source
Function: expand-fancy-symbols (form)

Expand -x into (- x) and 2x into (* 2 x).

Literal coefficients have the same precedence as unary operators.

Literal coefficients are assumed to be in base 10.

Package
Source
Function: looks-like-operator? (sym)

Does SYM start and end with an operator char?

Package
Source
Function: make-node (tree operator)
Package
Source
Function: operator-char? (c)
Package
Source
Function: parse-coefficient (str)
Package
Source
Function: parse-expression (expression)
Package
Source
Function: precedence< (op1 op2)
Package
Source
Function: precedence= (op1 op2)
Package
Source
Function: save-operator (&key name from right-associative)
Package
Source
Function: save-unary-operator (name)
Package
Source
Function: shunting-yard (expression)
Package
Source
Function: valid? (expression)
Package
Source

#### 5.2.5 Types

Type: operator ()
Package
Source