Get started
Install
pip install er2That is everything. PARI comes inside the cypari2 wheel, so there is no system PARI/GP to install, and SymPy arrives with it. ER2 needs Python 3.12 or later.
For notebooks, ask for the extra:
pip install "er2[jupyter]"
er2 kernel installA first program
Put this in first.er2:
sym x
f = x^2 + 2*x + 1
print(factor(f)) # (x + 1)^2
print(1/3) # 1/3, exact
print(isprime(2^521 - 1)) # Trueand run it:
er2 first.er2To see what the preparser produced — which is ordinary Python — ask for it:
er2 --show-python first.er2There is also a REPL: run er2 with no arguments.
The three things to know
^ is power, not XOR. This is the one change that can silently alter pasted Python. Write ^^ when you want XOR. ER2 warns when a ^ shares a line with obvious bit manipulation.
Integer literals are exact. 1/3 is the rational one third, not 0.333…. When you want a plain Python int — in a hot loop, say — write 5r.
sym x declares a symbol. Or use the predefined _x, _y, _z, _n, _k, _p without declaring anything.
Those, plus 5r and the way f"{a^2=}" echoes ER2 rather than the generated Python, are the whole of the difference from Python. The specification says so normatively and exhaustively.
In Jupyter and Quarto
Two routes, both supported:
- The ER2 kernel.
er2 kernel install, then pick “ER2” in Jupyter. In Quarto, putjupyter: er2in the front matter. - The extension.
%load_ext er2as the first cell of an ordinarypython3kernel.
Quarto cells stay ```{python}, because that is what Quarto executes and what editor tooling understands. This very site is built that way: its home page runs ER2 as it renders.
Using the Python ecosystem
Plain import, and it is the real library — ER2 translates only .er2 sources:
import numpy as np
print(np.zeros(2^3).shape) # (8,)
print(np.array([2^3, 3^2]).dtype) # int64Integer subclasses int, so NumPy, pandas, SciPy and Matplotlib give it a real integer dtype. Rational is not a machine number: NumPy and pandas keep it in an object array — exactly, so 1/3 stays 1/3 — while SciPy’s ufuncs reject it. Ask for float(...) when you want speed rather than exactness.