Browse the docs · Apsi 1.10.0
From Python to Apsi (apsi convert)
apsi convert translates Python files — or whole folders — into Apsi, maps the libraries you use onto Apsi's own
built-ins, checks the result and tells you exactly which lines need a human look.
apsi convert script.py # writes script.apsi next to it, then checks it
apsi convert script.py --run # convert, check and run
apsi convert src/ -o apsi_src/ # a whole project, keeping the folder layout
apsi convert script.py --stdout # print the Apsi code
In VS Code, Cursor and the other VS Code-family editors: right-click a .py file (or a folder) →
Apsi: Convert Python File to Apsi — the result opens beside the Python file.
Typical output:
✓ demo.py → demo.apsi (2 notes)
line 48: generator squares(): values are collected into a list
line 92: try/except: Apsi stops with a clear error message instead of raising exceptions; …
What is translated
| Python | Apsi |
|---|---|
x = 1 (assigned once) / assigned again or += |
let x = 1 / var x = 1 — chosen automatically |
a name first assigned inside if/for/with/try and used after it |
declared before the block (var x = none), because Apsi blocks have their own scope |
| a parameter that is reassigned | var p = p at the start of the function (Apsi parameters are constants) |
def f(a, b=2, *, c=3) |
fn f(a, b = 2, c = 3) — one-line bodies become fn f(a) = expr |
lambda x: x * 2 |
fn(x) => x * 2 |
@functools.lru_cache / @cache |
@memo |
generators (yield) |
the values are collected into a list that the function returns |
class with __init__ |
struct with the fields found in __init__, methods, plus Name_init / Name_new (calls Name(...) become Name_new(...)) |
@dataclass |
a struct with typed fields and defaults (constructed directly) |
| inheritance from a class in the same file | fields and methods are merged; super().__init__(...) calls the base's _init |
@staticmethod |
a function Class_method |
if/elif/else, while, for, break, continue, pass, assert |
the same |
for i in range(n) / range(a, b) |
for i in 0..n / a..b |
nested unpacking for k, (a, b) in …, first, *rest = xs |
temporary variable + element access |
| list / dict / set comprehensions, generator expressions | comprehensions (set([...]) for sets) |
| f-strings (also with format specs) | f-strings; when an expression contains quotes, string concatenation with format() |
with open(p) as f: f.read() / f.write() / print(..., file=f) / json.load(f) / json.dump(x, f) / for line in f |
read_text, write_text, load_json, save_json, read_text(p).splitlines() |
try / except / finally |
the protected code and the finally code are kept; except blocks become comments (noted) |
raise ValueError("msg") |
error("ValueError: " + str("msg")) |
isinstance(x, int) / (int, float) / own classes |
type(x) == "Int" / … or … / type(x) == "ClassName" |
max(xs, key=f) / min(…) |
sorted(xs, key=f)[-1] / [0] |
a & b, a | b on booleans or boolean arrays |
where(a, b, false), where(a, true, b) (element-wise, correct for both) |
is None / is not None |
== none / != none |
if __name__ == "__main__": |
the body runs at the end of the file |
| docstrings and comments | comments, in the same places |
names that are Apsi keywords (var, let, fn, struct, test, step, …) |
renamed with a trailing _ |
Libraries
| Python | Apsi |
|---|---|
numpy: array, zeros, ones, full, eye, arange, linspace, sum, mean, std, var, max, min, argmax, cumsum, sqrt, exp, log, trig and hyperbolic functions, clip, where, dot, matmul, outer, cross, transpose, reshape, concatenate, stack, vstack, hstack, meshgrid, sort, roll, einsum, maximum, minimum, square, sign, median |
built-ins of the same meaning (concatenate → concat, arcsin → asin, …) |
np.random.seed/randn/rand/randint/normal/uniform/random/permutation/choice |
seed, randn, rand, randint, … (Apsi's random generator is a different stream: random numbers differ, statistics do not) |
np.linalg.inv/det/solve/eig/eigh/svd/norm, np.fft.*, np.trapz, np.interp |
use linalg, use sci |
dtype=np.float32 / torch.float16 … |
dtype=f32 / f16 … |
math: sqrt, exp, log (also with a base), trig, hypot, radians, degrees, factorial, isnan, isinf, fsum, pi, e, tau, inf |
built-ins |
random: random, seed, randint (inclusive), randrange, uniform, gauss, choice |
rand, seed, randint(a, b + 1), … |
json loads/dumps/load/dump, time time/perf_counter/sleep, os.path exists/join, sys argv/exit, statistics mean/median/pstdev |
json_parse, json_str, load_json, save_json, clock(), parallel.sleep, exists, args(), exit |
PyTorch tensors: torch.tensor/zeros/ones/randn/arange/linspace/matmul/…, dim=, keepdim= |
the numpy equivalents, axis=, keepdims= |
torch.nn.Linear/Conv2d/LSTM/GRU/Embedding/LayerNorm/BatchNorm/Dropout/MultiheadAttention/Flatten/Sequential and activations |
use layers: linear, conv2d_layer, lstm_layer, … sequential([...]), activation("relu") |
torch.nn.functional.relu/gelu/softmax/log_softmax/mse_loss/cross_entropy/dropout |
built-ins and use nn |
| any other library (pandas, scipy.special, requests, matplotlib, …) | loaded with pyimport("name"); the program then needs --allow-python (=all for libraries that reach the network or the operating system). The note tells you which. |
What needs a human look
The converter never silently drops behaviour; everything below is reported with its line number:
try/except(Apsi reports errors itself and stops),for … else,while … else*args/**kwargs(become a list/dict parameter),*/**in calls, the:=operator,match- bitwise operators on integers (
^,<<,>>,~), complex numbers,async/await random.shuffleand other in-place random operations,functools.reduce- special methods such as
__add__(kept as normal methods; operators do not call them),super().method() - base classes from other modules (for example
torch.nn.Module— rewrite the model withuse layers; it trains on PyTorch again withfit(…, backend="torch"), seeBACKENDS.md) - decorators that have no Apsi equivalent
After converting, run apsi check file.apsi (done automatically) — and consider adding units to the physics
parts: let g = 9.81 → let g = 9.81[m/s^2] turns every later formula into a checked one.
Found a mistake? Report it · Markdown source