Acore language

[ AxiomCore · Documentation ]

Objects, classes and functions

Build and amend objects, declare classes and type aliases, use this, outer and super, and write lambdas and pure functions in Acore.

This page covers how you shape data in Acore: objects, typed objects, classes, type aliases, scope references and functions. The general-module examples were evaluated with axiom eval from CLI 0.149.1; backend examples were checked with axiom check.

Objects

A name followed by a block, or a brace literal, creates an object. Bracketed keys are evaluated.

objects.acore
metadata {
  owner = "platform"
  ["x-contract-version"] = "1"
}
defaults {
  retries = 3
  region = "eu"
}
production = (defaults) {
  region = "us"
  label = "prod-" + super.region
}
service {
  base = 10
  nested { total = outer.base + 5 }
}
Output of axiom eval objects.acore -f json (condensed)
{
  "defaults": { "region": "eu", "retries": 3 },
  "metadata": { "owner": "platform", "x-contract-version": "1" },
  "production": { "label": "prod-eu", "region": "us", "retries": 3 },
  "service": { "base": 10, "nested": { "total": 15 } }
}
  • (defaults) { ... } and defaults { ... } both amend an existing object: the result keeps every property you do not override.
  • Name { ... } creates a typed object from a class, which supplies defaults. There is no new keyword and no constructor runs.
  • The parser does not expose for or when generators inside objects. Do not use those forms.

Scope: this, outer and super

ReferencePoints to
thisThe object being evaluated. A bare property name also resolves here.
outerThe enclosing object
superThe object being amended, or the parent class value

Properties are lazy and immutable. A property cycle such as a = b and b = a aborts evaluation: CLI 0.149.1 stops with a stack overflow instead of a diagnostic. An import cycle reports Cycle: <module>.

Classes

classes.acore
hidden open class BaseService {
  enabled: Boolean = true
  timeoutSeconds: Int(this > 0) = 30
}

hidden class BillingService extends BaseService {
  endpoint: String
}

billing = BillingService {
  endpoint = "https://billing.example.com"
}
Output of axiom eval classes.acore -f json
{
  "billing": {
    "enabled": true,
    "endpoint": "https://billing.example.com",
    "timeoutSeconds": 30
  }
}
  • A class describes a value shape. It may omit its body, take type parameters (class Box<T>) and extend one parent type.
  • axiom eval renders a class declaration like any other property, with its defaults. Mark classes hidden or local to keep them out of output.
  • A class property with no default, such as endpoint: String, must be set by each typed object. If the class itself is rendered, its null value fails the type check.
  • A typed object does not re-check overridden properties against the class's type or constraint in 0.149.1; see Types.

Type aliases

Acore excerpt
typealias Environment = "development" | "staging" | "production"
typealias StringMap = Mapping<String, String>

Several contract positions are structurally typed, so the schema validation of each profile remains authoritative. A property typed with a literal-union alias is not checked against the literals in 0.149.1.

Functions

Lambdas are the callable form in general modules.

Acore excerpt
upper = (value: String) -> value.toUpperCase()
labels = ["one", "two"].map(upper)
DeclarationBehavior in 0.149.1
(params) -> expressionA closure. Call it with name(args) or pass it to a collection method.
function name(params): Type { ... }Parsed as a signature. It is not bound as a callable name (Undefined: name).
external function name(params): TypeA member a trusted host must implement. Without a host binding the name is undefined.

external does not let package code run. The standard library declares its native members this way:

Acore excerpt
external function parse(source: String): Any

class Parser {
  external function render(value: Any): String
}

Annotations

Acore excerpt
@deprecated { replacement = "currentName" }
oldName: String = "legacy"

An annotation is data for tooling. It has no effect unless the active compiler profile recognizes it.

Inheritance and composition

These forms are deliberately different.

SyntaxPurpose
class Child extends ParentClass inheritance
base { ... } or (base) { ... }Amend an object value
entity customer(model: Models.Customer)Promote a model to a domain entity (backend)
extend Models.Name { ... }Older form that promotes an extracted model. extend accepts only Models.Name.
amends "./base.acore"Compose source before a build
import "./shared.acore"Load trusted source as a module

A top-level extends "..." is rejected because it made source composition and value inheritance ambiguous. See Imports, amends and variants.

Backend pure functions and managed locals

backend/main.acore
project(id: "pure-example", version: "1.0.0")
pure fn normalizeTitle(value: String): String = value.trim()
pure fn label(count: Int32): String = count > 1 ? "many" : "one"
  • A pure fn declares explicit parameter and result types and a single bounded expression body.
  • It may call other pure functions and bounded string and list methods. The call graph must be acyclic: recursion fails with recursive or excessive-depth pure functions are forbidden.
  • It cannot capture state, host services, the clock or randomness.
  • In a managed block, let creates an immutable lexical local. Locals cannot be shadowed, and a local declared in a branch or handler cannot escape it.

See Managed logic and concurrency for statements and effects.