Skip to main content
Version: 1.0.0

Function

A Touba function computes a pure value. It keeps business logic inside the language when no host handler is required.

A function can use native expressions: arithmetic, booleans, comparisons, text concatenation, explicit text(expr) rendering, and field access.

It produces no external effect:

  • no network;
  • no file read;
  • no direct secret access;
  • no show or ask;
  • no human validation;
  • no mutation or reassignment.

Shape​

source.tb
function Name
takes input as InputType
gives OutputType
do
give expression

With an immutable local value:

source.tb
function Name
takes input as InputType
gives OutputType
do
bind local_name as OutputType = expression
give local_name

define names a non-sensitive module constant. bind names an immutable local value inside a block.

Each invocation has its own scope: parameters, bind values and into results do not overwrite identically named values in the caller. Only the returned result crosses back into the caller; other local values stay inside the call. This isolation also applies to imported functions and is preserved on failure. A function cannot capture its caller's local variables.

Simple Case​

function_simple.tb
module examples.function_simple

function BuildGreeting
takes name as Text
gives Text
do
give "Bonjour " ++ name

Here, Touba needs neither a manifest nor a handler. The computation stays in AIR and can be executed by the runtime.

Advanced Case​

function_advanced.tb
module examples.function_advanced

define RiskLimit as Float = 0.7
define FileLimit as Int = 20

type ReviewSignal
risk is Float
file_count is Int
has_secret_change is Boolean

function ShouldEscalate
takes signal as ReviewSignal
gives Boolean
do
bind risky as Boolean = signal.risk >= RiskLimit
bind large_change as Boolean = signal.file_count > FileLimit
give risky or large_change or signal.has_secret_change

function BuildReviewLabel
takes signal as ReviewSignal
gives Text
do
ShouldEscalate
with signal as signal
into escalate

if escalate
give "human review required"
else
give "automatic path accepted"

This case shows two points:

  • a function can call another function with with / into;
  • the compiler verifies that an if condition receives a Boolean.

Control flow and business values​

if / else if / else, for and while compose inside functions, skills and strategies. Bindings remain immutable and block-scoped; loops do not add mutable assignment. A give immediately returns from the current path, including from inside a loop.

ticket_priority.tb
module examples.ticket_priority

enum Priority
normal
watch
urgent

function FirstContact
takes contacts as List of Optional of Text
gives Optional of Text
do
for contact in contacts
if present contact as address
if address != ""
give some(address)
give none(Text)

function ClassifyTicket
takes overdue_days as Int
gives Priority
do
if overdue_days >= 7
give Priority.urgent
else if overdue_days >= 3
give Priority.watch
else
give Priority.normal

Priority is a closed nominal type, not free text. Optional of Text distinguishes absence from empty text; if present exposes the value only inside its branch. At the JSON boundary, the enum is "urgent", "watch" or "normal", and the optional is {"present":false} or {"present":true,"value":"a@example.test"}. See the syntax reference for loops, imported types and record construction. Write parallel in a skill or strategy, not a pure function.

What a Function Carries​

In ordinary host code, a simple business calculation can end up inside a handler, a JavaScript helper, or an auxiliary script.

With function, that calculation remains in the Touba contract. This makes the boundary between pure computation and tool-mediated effects explicit.

Runtime Contract​

  • No mutable variables.
  • No implicit conversion to Text.
  • No text rendering of structured types, lists, secrets, or memories.
  • No rich standard library in the first public slice.
  • No inline host code.

Purity is checked at compilation and AIR admission. Every function must reference its own graph, and its calls must resolve to declared functions. A forged function graph containing tools, agents, interaction, or human approval is rejected before execution. Importing a pure function grants no additional authority.

Dedicated walkthroughs​