Computation Model¶
Graphcal programs describe a directed acyclic graph (DAG) of computations. This page covers the core model: declaration kinds, the @ sigil, evaluation semantics, and naming conventions.
Declaration Kinds¶
Every top-level declaration belongs to one of four kinds:
| Kind | Keyword | Semantics | In DAG? |
|---|---|---|---|
| Parameter | param |
Named DAG input port, optionally with a default value | Yes |
| Node | node |
Computed value derived from other values | Yes |
| Constant | const node |
Compile-time immutable value | No |
| Assertion | assert |
Post-evaluation boolean check | No |
Parameters¶
param dry_mass: Mass = 1200.0 kg; // optional param (has default)
param fuel_mass: Mass; // required param (no default)
A param declares a named input port in the computation graph; it is not an
ordinary private declaration that becomes implicitly public. The declaration
kind itself supplies the external-input role, so params never take pub or
pub(bind):
- A param in the entry DAG can be supplied with
--setor--input. - A param in a callable DAG can be supplied by name in an
includebinding or inline DAG call. - Its effective value is also externally readable: callers may select it from
an
includeor project it from an inline call. The result is the supplied binding, or the default when no binding was supplied. - A param with a default (
= expr) keeps that value when the caller does not supply the port. - A param without a default is required. Leaving a required port unsatisfied is a compile error.
Use a private node for an internal computed value or a private const node
for an internal fixed value. If a sub-computation needs internal
parameterization, put it behind a private DAG or module boundary rather than
using an "internal param" naming convention.
Parameters (and nodes) can carry domain constraints that declare valid value ranges, checked at runtime:
See Type System — Domain Constraints for details.
Nodes¶
Nodes are computed values. Their expressions can reference parameters, other nodes, and constants. Graphcal evaluates nodes in topological order determined by the dependency graph.
Constants¶
Constants are evaluated at compile time before the DAG is built. They cannot reference parameters or nodes (the @ sigil is prohibited in const node expressions).
Assertions¶
Assertions are post-evaluation checks. They can reference parameters and nodes but are not part of the DAG -- no other declaration can reference an assert. Assertions are always evaluated last, after the entire graph. See Assertions and Attributes for full details.
The @ Sigil¶
The @ prefix is the central scoping mechanism:
| Reference | Meaning | Allowed in |
|---|---|---|
@name |
Parameter, node, or const node in the graph | node expressions, dag block bodies |
@dag(args).out |
Inline DAG invocation projecting one output | Same as above |
NAME |
Built-in constant (PI, E, TAU, etc.) |
Everywhere |
name |
Local variable (loop variable, match binding) | Expression bodies |
Where @ Is Allowed¶
| Context | @ Allowed? |
|---|---|
node expression |
Yes |
param default value |
No |
const node expression |
No |
dag block body (inside node expressions) |
Yes |
Evaluation Order¶
- Parse -- Source files are parsed into an AST
- Resolve -- Imports are loaded; references are resolved while lowering to the compiler's internal representation
- Dimension check -- All expressions are checked for dimensional consistency
- Const evaluation -- Constants are evaluated in dependency order
- DAG construction -- A dependency graph is built from
paramandnodedeclarations - Topological evaluation -- Nodes are evaluated in topological order
- Assertion checking -- Assert declarations are evaluated and reported
Cycle Detection¶
Circular dependencies between nodes are detected at compile time:
Call-Site Identity¶
When a dag is instantiated — whether via top-level include or via the
inline @dag(args).out expression form — each syntactic call site is a
fresh instantiation. Two textually distinct occurrences with identical
arguments denote two distinct sub-graphs in the underlying DAG, not a shared
sub-graph. Programs must not rely on sharing across call sites.
An eval engine is free to detect structurally identical sub-graphs and reuse their computation as an internal optimization, but this is not part of the language semantics.
Fault Isolation¶
If a node's evaluation fails (e.g., division by zero), only that node and its dependents are affected. Independent nodes still evaluate successfully.
Naming Conventions¶
Graphcal recommends the following naming conventions:
| Declaration | Recommended Convention | Example |
|---|---|---|
param |
lower_snake_case |
dry_mass |
node |
lower_snake_case |
total_dv |
const node |
lower_snake_case |
g0, margin_factor |
assert |
lower_snake_case |
fuel_positive |
dag |
lower_snake_case |
orbital_velocity |
type |
PascalCase |
TransferResult |
dim |
PascalCase |
Velocity |
index |
PascalCase |
Maneuver |
unit |
(various) | km, kN, MPa |
These conventions are not enforced by the compiler, but following them is strongly recommended for consistency and readability.
Comments¶
Graphcal supports line comments: