Prola

Docs

Welcome to the Prola documentation

Part 1. Introduction

Prola is a process-oriented programming language designed for defining, orchestrating, and executing processes. It provides a clear, readable syntax that allows processes to be defined as ordered sequences of events, actions, and decisions.

Inspired by BPMN, SQL, and Python, Prola focuses on making process logic explicit and data-driven. Processes in Prola are built from a small set of core primitives—events, actions, and decisions—that are composed in a linear, readable flow. Data flows explicitly between actions, and process execution is deterministic and observable.

Prola is not a general-purpose programming language. It is a domain-specific language (DSL) for defining processes. Its primary goal is to make complex workflows easy to define, understand, and maintain. Prola also supports bi-directional editing between code and visual diagrams, allowing processes to be modeled and modified in either form.

Use cases for Prola include:

  • Approval workflows
  • Customer onboarding
  • Inventory synchronization
  • Logistics orchestration
  • Order processing
  • System integrations

Part 2. Core concepts

Prola is built on a small set of core concepts: events, actions, and gateways. These are composed in an ordered sequence to define the flow of a process. The flow between elements is implied by their order in the code. There are no hidden jumps, implicit state transitions, or parallel flows in this version of the language.

Processes are fully data-driven. Data flows explicitly from one action to the next. Process logic is deterministic—given the same inputs, a process will follow the same sequence of events, actions, and gateways. Process outputs are deterministic if all actions produce consistent results for the same inputs.

Events

Events define the start and end points of a process. A start event specifies the trigger that begins process execution, such as a new record in a database or an external system event. An end event marks the completion of the process.

Actions

Actions are the core units of work in a process. Each action takes input data, performs a defined operation, and produces output data. Actions can perform any type of computation, data transformation, or system interaction.

Gateways

Gateways define branching logic in a process. A gateway evaluates a condition based on process data and determines which branch of the process to execute. In this version of Prola, gateways are exclusive (only one branch is taken).

Flow

The flow of a process is determined by the order of elements in the process definition. Actions and gateways are executed in sequence from top to bottom. Branches within a gateway are mutually exclusive and continue the flow from that branch.

Dataflow

Data is passed explicitly between actions and gateways via input and output declarations. There is no implicit global state. This ensures that process logic is transparent and easy to reason about.

Visual editing

Prola is designed for bi-directional editing between code and visual diagrams. The core language is simple and structured to ensure that every Prola process can be represented visually without ambiguity, and that visual changes can be reflected in the code.

Part 3. Language syntax and semantics

Prola defines processes using a small, regular syntax built around three core constructs: events, actions, and gateways. The process definition is written as a linear sequence of these constructs. The execution flow is strictly determined by the order of the constructs in the code.

Processes are defined in plain text using Prola’s syntax. Every process definition can be represented visually, and every visual change can be reflected in code (bi-directional editing). There is no hidden or implicit flow logic.

Process definition

process "Process Name"

The process body consists of events, actions, and gateways defined in order. The flow of execution is top-to-bottom.

Events

Start event

start event "Event Name"
    trigger: on_insert(table="table_name")
    output: variable_name

trigger defines the event source. output declares the data object that enters the process.

End event

end event "Event Name"

Actions

action "Action Name"
    input: variable1, variable2
    output: result_variable
    run:
        result_variable = some_function(variable1, variable2)

If an action does not produce an output, the output section can be omitted:

action "Send email"
    input: order
    run:
        send_email(to=order.customer_email, template="order_confirmation")

Gateways

gateway "Gateway Name"
    condition:
        boolean_expression
    when true:
        action "Action Name"
            input: variables
            run:
                ...

    when false:
        action "Action Name"
            input: variables
            run:
                ...

Flow semantics

  • The flow of the process is determined by the order of events, actions, and gateways in the code.
  • Execution is strictly top-to-bottom.
  • Gateways cause exclusive branching—only one branch runs.
  • After a branch completes, flow continues below the gateway.
  • There are no implicit jumps or hidden transitions.
  • Parallel execution is not supported in this version.

Dataflow

Data is passed between actions and gateways explicitly through input and output declarations. Each process instance has its own data scope. There is no implicit global state or shared memory between process instances. All variables are process-scoped and flow forward.

This syntax forms the complete core of Prola in its current version. Processes defined this way are fully transparent, predictable, and suitable for visual representation and editing.

Part 4. Complete example

The following is a complete example of a Prola process. It demonstrates the use of events, actions, gateways, and explicit dataflow in a real-world process flow.

process "Order-to-shipment"

    start event "Order received"
        trigger: on_insert(table="orders")
        output: order

    action "Validate order"
        input: order
        output: validation_result
        run:
            validation_result = validate_order(order)

    action "Check inventory"
        input: order
        output: inventory_status
        run:
            inventory_status = check_inventory(order.item_id, order.quantity)

    gateway "Inventory available?"
        condition:
            inventory_status.available
        when true:
            action "Reserve inventory"
                input: order, inventory_status
                run:
                    reserve_inventory(order.item_id, order.quantity)

            action "Generate invoice"
                input: order
                run:
                    generate_invoice(order.id)

            action "Print shipping label"
                input: order
                run:
                    print_shipping_label(order.id, order.shipping_address)

        when false:
            action "Notify customer: Out of stock"
                input: order, inventory_status
                run:
                    send_email(to=order.customer_email, template="out_of_stock", data=order)

    end event "Shipment process completed"