Skip to content

ALP Specification — Expressions (ALPEL) ​

Version: 80.0.0 Status: Stable


1. Expression Language Overview ​

mermaid
flowchart TD
    ALPEL[ALP Expression Language] --> Interpolation[String Interpolation]
    ALPEL --> Conditionals[Conditional Directives]
    ALPEL --> Assertions[Runtime Assertions]
    Interpolation --> Syntax1[\${ expression }]
    Conditionals --> Syntax2[!if: expression]
    Assertions --> Syntax3[!assert: expression]
    ALPEL --> Literals[Literals]
    Literals --> String[\"string\"]
    Literals --> Number[42]
    Literals --> Bool[true/false]
    ALPEL --> Operators[Operators]
    Operators --> Comparison[==, !=, >, <]
    Operators --> Logical[&&, ||, !]

2. Overview ​

Starting with v0.3.0, ALP includes the ALP Expression Language (ALPEL). ALPEL is a secure, sandboxed, and lightweight expression language used for conditional logic and string interpolation.

ALPEL allows workflows, tasks, and engines to dynamically adapt based on the project's current state, without relying on external scripts.


2. Where Expressions Are Used ​

Expressions can be used in three primary contexts:

2.1 Interpolation (${ }) ​

Embedded within string values.

alp
  description: "Deploying feature ${ task.feature.name } to ${ project.environment }"

2.2 Directives (!if, !assert) ​

Used to conditionally include blocks or enforce rules.

alp
@task
  id: task-deploy
  !if: "project.state == 'production'"
  !assert: "agent.role == 'devops'"

2.3 Engine Conditions ​

Used by engines (like the Workflow engine) to branch logic.

alp
    - name: "Run security scan"
      task: -> task-sec-scan
      condition: "task.feature.priority == 'critical'"

3. Syntax & Operators ​

ALPEL syntax is inspired by JavaScript and Python, designed to be intuitive for developers.

3.1 Primitives ​

  • Strings: 'hello', "world"
  • Numbers: 42, 3.14
  • Booleans: true, false
  • Null: null

3.2 Operators ​

  • Comparison: ==, !=, <, >, <=, >=
  • Logical: && (AND), || (OR), ! (NOT)
  • Math: +, -, *, /
  • Collection: in, contains

3.3 Property Access ​

Use dot notation or bracket notation to access properties of ALP objects.

alp
  task.priority
  feature.metadata['custom_key']

3.8 Collection Iteration (v1.4.0+) ​

ALPEL supports basic operations over lists to power @macro expansions:

FunctionSyntaxDescriptionExample
maplist.map(var => expr)Transforms each item['a', 'b'].map(x => x + '1') → ['a1', 'b1']
filterlist.filter(var => expr)Keeps matching items[1, 2, 3].filter(x => x > 1) → [2, 3]
containslist.contains(val)True if value exists['a', 'b'].contains('c') → false

Example:

alp
// Used in a macro to generate tasks for every feature tagged "core"
iterate_over: "project.features.filter(f => f.tags.contains('core')).map(f => f.id)"

4. Evaluation Context Variables ​

During evaluation, ALPEL provides access to the following built-in context variables:

VariableDescription
projectThe global @project object and its properties.
taskThe current @task object (if the expression is evaluated within a task context).
featureThe current @feature object.
agentThe @agent currently executing the engine or assigned to the task.
envEnvironment variables exposed to the ALP parser (e.g., env.CI).
stateThe current @state object.

5. Built-in Functions ​

ALPEL provides a small standard library of safe functions for common operations.

5.1 String Functions ​

  • length(str): Returns string length.
  • toUpper(str): Converts to uppercase.
  • toLower(str): Converts to lowercase.
  • startsWith(str, prefix): Boolean check.

5.2 List Functions ​

  • size(list): Number of items in a list.
  • isEmpty(list): True if list is empty.
  • hasStatus(tasks, status): E.g., hasStatus(feature.tasks, '[x]')

6. Execution Sandbox ​

ALPEL MUST be evaluated in a strict sandbox.

  1. No Mutation: Expressions cannot change the value of any variable. They are strictly read-only.
  2. No Side Effects: Expressions cannot make network requests, read the filesystem, or execute shell commands.
  3. Deterministic: Given the same context state, an expression must always return the same result.
  4. Timeout: Parsers MUST enforce an execution time limit (e.g., 100ms) per expression to prevent infinite loops (though ALPEL intentionally lacks looping constructs).

7. Examples ​

Conditional Workflow Step:

alp
@workflow
  steps:
    - name: "Optional QA"
      task: -> task-qa
      condition: "feature.priority == 'critical' && !isEmpty(feature.tasks)"

Assertion in a Task:

alp
@task
  id: task-deploy
  !assert: "project.state == 'testing'"
  // Task will fail to parse if the project is not in 'testing' state

Complex String Interpolation:

alp
@artifact
  id: art-build
  path: "dist/build-${ toLower(project.name) }-v${ project.version }.tar.gz"