Browse the documentation

Preview documentation for AEL Beta 0.0.1 — launching soon

Functions and visibility

Sharing in AEL, the Agent Engineering Language, will follow three clear rules: helpers will stay private to their component, shared functions will be visible by folder, and reusable functions will be imported explicitly. The check will enforce each rule before anything runs.

Status

Planned for AEL Beta 0.0.1. AEL is not available yet.

Package names on this page are preview naming and may change before launch.

Declaring a function

Preview syntax — may change before launch
fn with_tax(amount: u64, percent: u64) -> u64 {
    return amount + amount * percent / 100;
}
  • Every parameter and the result will have explicit types. A function that returns nothing will declare -> ().
  • Parameters will not be reassignable unless declared mut: fn next(mut n: u64) -> u64.
  • A function will be able to call functions declared further down the same file.
  • Every call will name its function directly. Functions will not be values: there will be no closures, and you will not be able to store a function or pass it as an argument.
  • Two functions with the same name in one file will be refused; AEL will have no overloading.

The primary of a component will use its role word instead of fn, as in reuse twice(value: i64) -> i64. main will be able to leave out its result when it returns nothing.

Recursive calls will be checked against the target's stack limits: on the smallest boards, a recursion whose depth cannot be bounded will fail to build.

Three kinds of function

KindDeclaredCallable from
Helper functionfn in any component's fileThat component and its extension files only
Global functionglobal <name>(…) in <name>.global.aelEvery file in the same folder and every folder below it, with no import
Reusable functionreuse <name>(…) in <name>.reuse.aelA file in the same folder or a folder below it that imports the file in its header

"Global" will describe where a function is visible, never shared state: AEL will have no global variables.

An example

Preview syntax — may change before launch
shop/
  round_cents.global.ael     # global round_cents(…)
  pricing/
    discount.reuse.ael       # reuse discount(…)
    quote.node.ael
  shipping/
    rates.node.ael
Preview syntax — may change before launch
# pricing/discount.reuse.ael
reuse discount(amount: u64, percent: u64) -> u64 {
    return amount - share(amount, percent);
}

fn share(amount: u64, percent: u64) -> u64 {
    return amount * percent / 100;
}
Preview syntax — may change before launch
# pricing/quote.node.ael
import "./discount.reuse.ael";

node quote(amount: u64) -> u64 {
    return round_cents(discount(amount, 10));
}
  • quote will call round_cents without an import, because round_cents.global.ael is in an ancestor folder.
  • quote will call discount because its header imports discount.reuse.ael.
  • quote will not be able to call share: it is a helper, private to discount.
  • shipping/rates.node.ael will be able to call round_cents, but never discount, not even with an import, because pricing/ is a sibling folder.
  • A file directly in shop/ will not be able to call discount either: a folder will never reach into the folders below it.

Imports

  • An import will sit in the file's header, before the first declaration: import "../welcome.reuse.ael";.
  • The path will be relative to the importing file and name the whole file name. It will have to lead to the file's own folder or a folder above it, inside the project.
  • An import will make one reusable function available, and nothing else: not the file's helpers, and not what that file imports in turn.
  • A reusable function that is not imported will be invisible, even in the same folder.

When names collide

  1. Names in the function itself, and the component's own helpers, will come first.
  2. Then AEL will look in the caller's folder, then in each folder above it up to the project root. The nearest folder that has an eligible global or imported reusable function of that name will win.
  3. Two eligible functions of one name in the same folder will be refused as ambiguous.
  4. If the nearest function has the wrong types, the call will fail. AEL will never fall back to a function further away that happens to fit.

A shared function's body will always use the names visible where it is written. Calling it from another folder will never change which functions its body calls.

Components and packages

These rules will be for shared functions. Components will be connected differently:

  • An agent will name its nodes and edges in its configuration, such as nodes: [summarizer = summarize]. Those references will be typed and may cross folders, but they will never expose a component's helpers. See Agents, nodes and edges.
  • A package's exports will be named in the header with refer, such as refer server/http select get;. See Using packages.