Osy#the first language built for agents
Agents firstAgentic appsWorkflowsDurable Execution — built inSecurityTestingThe editorThe UI modelOne program

Reference / Types

Constant expressions

[Label("Awaiting " + "review")] // folded at compile time

Some places take a value that must be known at compile time — an attribute argument, a config setting, a workflow message. Adjacent string literals joined with `+` are folded before that check, so you can split a long sentence across lines. Anything that is not constant is still refused.

stable2 examples compiled by CItypesauthoring

Summary#

A few places in Osy# take a value that has to be known while the app is being compiled, not while it is running — an attribute argument, a setting in a config block, an enum member's display label, a workflow message. Those places require a constant.

A string literal is the obvious constant. So is a chain of string literals joined with +: the compiler folds "Awaiting " + "review" into "Awaiting review" before it checks that the value is constant, exactly as C# does. That means a long sentence can be split across lines for readability without the compiler objecting.

What is not constant is still refused, and for the real reason. A value that depends on a member, a parameter or a runtime call is not known at compile time, so it cannot go where a constant is required — no matter how it is spelled.

Signature#

[Label("Awaiting " + "review")]        // folded → "Awaiting review"
[Label("Signed " + "off " + "by legal")]   // any length of chain folds

[Pattern("^DOC-" + Code)]                // REFUSED — `Code` is not a constant
[Pattern($"^DOC-[0-9]+$")]               // REFUSED — an interpolated string is not a literal

Description#

Where a constant is required#

These are the places that read a value at compile time rather than evaluating it at run time:

  • Attribute arguments[Label], [Pattern], [ExternalName], and a constraint's optional message.
  • Enum member labels[Label] and [Icon] on a member.
  • Config settings — the values inside a config block, and the entries of a string list.
  • Workflow messages — a terminal's or a requirement's Message.
  • Agent and tool descriptions — a Description on a tool or agent, which the model reads.

In each case the value is baked into the application's metadata when it is compiled. There is no later moment at which a non-constant could be evaluated, which is why the requirement exists.

Folding#

Folding is left-nested, mirroring how + associates: "a" + "b" + "c" folds only because each step folds. A chain with one non-constant operand is not a constant at all, and returns nothing rather than a partial result — so "Hello " + name is refused rather than quietly becoming "Hello ".

Folding happens during the compile, not in the parsed source. Tooling that reads your code — hover, go-to-definition, selection — still sees the expression you wrote, with the + intact.

Interpolated strings are deliberately not constants#

$"…" is refused where a constant is required, even when it happens to contain no holes. The $ prefix declares an intent to interpolate, and a place that needs a compile-time value should say so plainly rather than accept a form whose purpose is to be computed. Write a plain literal, or a + chain of them.

Examples#

A long label split across two lines, and a three-part chain:

enum ReviewState {
  [Label("Awaiting " + "review")] Pending,
  [Label("Signed " + "off " + "by legal")] Approved,
}

An attribute whose pattern and whose failure message are both split:

entity Doc {
  [Pattern("^DOC-" + "[0-9]+$", "use " + "DOC-1234")] string Code;
  ReviewState State;
}

Neither of these is constant, and both are refused:

[Pattern("^DOC-" + Code)]     // depends on a member — not known at compile time
[Pattern($"^DOC-[0-9]+$")]    // an interpolated string is not a literal

See also#

Related

Optional and required members

A member is required or optional by how you spell its type. A bare value type with a natural zero reads that zero; a…

constraints

The per-member rules the database enforces — Required, Unique, MaxLength/MinLength, Min/Max, Pattern, and the…

enum

A fixed set of named values, used as a member type. Stored as a number by default, or as the member's own name with…