DEVELOPER PREVIEWDOCUMENTATION FOR THE CURRENT COMPILER

Programming
in Abla

Enough to write a program, understand what makes Abla different, and find the deeper contracts when you need them.

01

GETTING STARTED

Build the compiler, then build a program.

Abla is pre-release software. Today, the supported way to start is from the compiler repository with its pinned Nix and LLVM environment.

terminal
git clone https://github.com/AndreBaltazar8/ablac.git
cd ablac
nix-shell
make

build/ablac run examples/hello.ab

The normal interface is one executable: ablac build emits a native program, ablac run uses the JIT, ablac repl evaluates expressions, and ablac serve watches a long-running program.

02

LANGUAGE BASICS

Expression-oriented and deliberately familiar.

Kotlin influenced the surface syntax. Semicolons are accepted but never required, the last expression in a block is its value, and function return types can be inferred.

basics.abABLA
val immutable = 1
var mutable: int = 2

fun add(left: int, right: int): int {
    left + right
}

fun main: int = add(20, 22)
Core types

bool, signed and unsigned integers, f32, f64, char, string, array<T>, nullable T?, classes, interfaces, and affine resource classes.

03

COMPILE-TIME EXECUTION

# evaluates an expression while building.

Compile-time execution is not a separate template language. It shares Abla's checked instruction model, values, diagnostics, and resource limits. A compile fun can exist only at compile time; an ordinary function can be called in either phase when its effects are allowed.

staging.abRETURNS 40
fun square(value: int): int = value * value

compile fun compileAdd(left: int, right: int): int =
    left + right

fun main: int {
    val generated = #square(6)
    generated + #compileAdd(2, 2)
}

Filesystem, environment, process, network, clock, random, and native access are explicit capabilities. This keeps program generation inspectable and bounded.

04

LIBRARY-PROVIDED SYNTAX

Syntax can come from a package and remain checked.

Compile-time subparsers let a library recognize a source form, produce syntax, and send it back through the ordinary parser, resolver, type checker, ownership checker, and IR verifier.

json.abSAME FORM, TWO PHASES
import "abla/json"

fun main: int {
    val frozen = #$json {"number": 20}
    val runtime = $json {"number": 22}
    frozen.getInt("number") + runtime.getInt("number")
}

The same mechanism powers typed HTML in Abla MVC and declarative Android trees in Abla Mobile.

05

RESOURCE SAFETY

Affine resources have visible ownership.

A resource class is owned exactly once. Ordinary parameters borrow, own receives ownership, move transfers it, and an optional drop method runs once across normal exits and control-flow edges.

socket.abOWNERSHIP CHECKED
resource class Socket(val descriptor: int) {
    fun drop(): void {
        platformClose(descriptor)
        return
    }
}

fun inspect(socket: Socket): int = socket.descriptor
fun close(own socket: Socket): int = platformClose(socket.descriptor)

inspect(socket)
close(move(socket))

The verifier also tracks moved fields and array elements, closure captures, reassignment, early returns, and nested cleanup.

06

PACKAGES

Imports are typed compile-time source providers.

github(...) returns an ImportSource; it is a library provider, not hardcoded parser syntax. Package updates resolve immutable revisions into abla.lock. Ordinary and offline builds do not move them.

app.abLOCKED IMPORTS
import github("AndreBaltazar8/abla-web")
import github("AndreBaltazar8/abla-postgres")

fun main: int {
    val app = webApp()
    app.use(webSecurityHeaders())
    // compose the service here
    0
}
ablac package update --project .
ablac build --project . --offline
Browse Abla packages
07

TOOLCHAIN

One compiler, several ways to execute.

ablac build app.ab -o build/appNative executable
ablac build app.ab -o build/app --fastFaster edit/build cycle
ablac run app.abJIT execution
ablac replExpression REPL
ablac serve app.abReload-safe supervisor

The built-in raw x86-64 Linux target emits a static executable with its own startup, allocator, and syscall boundary—without a C runtime, libc, ELF interpreter, or dynamic dependency.