Getting started

Installation

LibPARI is installable from the Julia General registry:

using Pkg
Pkg.add("LibPARI")

The native PARI library is supplied by PARI_jll, a registered binary build of PARI 2.17.3 for Linux, macOS, and Windows. Pkg.add resolves and installs it automatically — no system PARI is required.

LibPARI requires Julia 1.10 (the long-term-support release) or later.

Loading the package

using LibPARI

Loading the module initializes the embedded PARI library exactly once for the process and registers a clean shutdown at process exit. You can observe the lifecycle:

LibPARI.is_initialized()   # true
LibPARI.library_state()    # LibraryState.INITIALIZED
LibPARI.stack_size()       # PARI main-stack size, in bytes

The PARI main-stack size defaults to 8 MiB. To change it, set the LIBPARI_STACK_SIZE environment variable (a byte count) before the package is loaded.

A first tour

using LibPARI brings in exactly four names: pari, Gen, gp_eval and PariError. Everything else stays qualified.

pari converts a Julia value into a PARI one — a Gen — and the usual Julia operators work on it:

julia> using LibPARI
julia> a = pari(42)42
julia> a * a + 11765
julia> pari(2)^1001267650600228229401496703205376

pari accepts integers of any magnitude, rationals, floats — including BigFloat, exactly — and complex numbers. Mixed arithmetic takes a Julia operand on either side:

julia> pari(3 // 4) + 17/4
julia> pari(2)^200 == big(2)^200true
julia> pari(big"1.234567890123456789012345678901")1.2345678901234567890123456789010000000

Convert back to a Julia value:

julia> BigInt(pari(2)^64)18446744073709551616
julia> Int(pari(255))255

The three levels of access

1. Idiomatic Julia. A small hand-written surface: the operators above, the conversions, and a short list of Base functions where PARI's operation is Julia's.

julia> gcd(pari(12), 18)6
julia> factorial(pari(20))2432902008176640000
julia> LibPARI.isprime(1009)true
julia> LibPARI.factors(60)3-element Vector{Pair{Gen, Gen}}: Gen(2) => Gen(2) Gen(3) => Gen(1) Gen(5) => Gen(1)

This is the layer that changes most slowly, and the one the documentation leads with. LibPARI is in 0.x: it can still change, and the changelog records every such change.

2. The generated bindings. Nearly 1200 PARI functions under LibPARI.PARI, one per eligible entry in PARI's own function database, each carrying PARI's help text as its docstring:

julia> LibPARI.PARI.nextprime(pari(1000))1009
julia> LibPARI.PARI.eulerphi(pari(100))40

Their names and calling conventions follow pari.desc, so they track PARI rather than Julia taste.

3. GP expressions. gp_eval reaches anything the other two do not — in particular the functions taking a GP closure, which are not generated:

julia> gp_eval("sum(k = 1, 100, k^2)")338350

It is an escape hatch, not the recommended way to use LibPARI.

Handling errors

A failing PARI call raises a catchable PariError carrying PARI's own message and an error category:

julia> try
           gp_eval("1/0")
       catch e
           e isa PariError
       endtrue

Next steps

The API reference documents the hand-written public surface in full and explains how the generated LibPARI.PARI bindings are organized.