Composability: Functions & Imports
Composability: Functions & Imports
Trilogy models are building blocks. Two language features do most of the work: functions package reusable logic within and across queries, and imports share whole models across files and projects.
Functions
Function statements define reusable custom functions that can be called throughout your Trilogy scripts:
def double(x) -> x * 2;
Functions support type hints and default parameter values:
def calculate_tax(amount: float, rate: float) -> amount * rate;
def apply_discount(price, discount = 0.1) -> price * (1 - discount);
Call them with the @ prefix:
def format_currency(amount) -> concat('$', cast(round(amount, 2) as string));
select
order.id,
@format_currency(order.total) -> formatted_total
;
Define a metric or a formatting rule once, and every query — human- or AI-authored — uses the same definition.
Imports
Import statements bring concepts and definitions from other Trilogy files into the current scope:
import customer;
import models.order;
import ..parent_module;
Use as to give the import a local alias; all concepts from the imported module are namespaced under it:
import customer as c;
import models.order as ord;
After aliasing, reference concepts like c.id or ord.total.
The standard library ships with Trilogy and provides common types and utilities:
import std.money;
import std.display;
Putting Them Together
A typical project defines shared models — concepts, datasources, types, and functions — in dedicated files, then composes them in queries:
import customer as customer;
import order as order;
import std.money;
select
customer.id,
customer.name,
sum(order.total) -> customer_total
;
The query file never repeats join logic or metric definitions; those live in the model, defined once and reused everywhere.