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

Reference / Function

Typed locals

int x = 5; · Order o = …; · List<int> xs = …;

Locals can declare an explicit type instead of var; the declared type pins the binding. Literal initializers apply the C# constant conversion; non-literals widen by numeric rank but never across decimal↔double. A typed local must be initialized at its declaration.

stable1 example compiled by CIfunctiontypesauthoring

Summary#

Locals can declare an explicit type instead of varint x = 5;, Order o = …;, List<int> xs = …;. The declared type pins the binding, exactly C#: literal initializers apply the C# constant conversion, non-literal initializers must be implicitly assignable, and every typed local must be initialized at its declaration.

Signature#

<Type> <name> = <initializer>;
// Type: a scalar keyword, entity (incl. namespaced), Type?, Type[], List<T>/HashSet<T>/Dictionary<K,V>

Description#

  • A typed local must be initialized at its declarationint x; is refused (there is no definite-assignment analysis; initialize where you declare).
  • Literal initializers use the C# constant conversion: the literal is re-kinded when widening (int → long/decimal/double, decimal → double) — so double h = 2.5; compiles even though a bare 2.5 is decimal (Numeric types & literal suffixes). A non-representable constant refuses: int x = 2.5m;cannot implicitly convert 'decimal' to 'int'.
  • Non-literal initializers widen by numeric rank (int → long → decimal/double) but never across decimal↔double in either direction — C# has no implicit conversion between them (double x = someDecimal; is a pointed error).
  • null needs a nullable declared typeint? x = null;, not int x = null;.
  • The pinned type drives downstream resolution — an entity-typed local navigates members (Order o = Order.First(); o.Total).
  • Decompile normalizes to var with the re-kinded literal (decimal d = 5;var d = 5m;) — semantically identical; the same normalization const-inlining uses.

Examples#

entity Order { decimal Total; }

decimal Examples() {
  int x = 5;                         // pins int
  long big = 5;                      // constant conversion: the int constant becomes long
  decimal d = 5;                     // → 5m
  double h = 2.5;                    // works — the constant converts (a bare 2.5 is decimal)
  int? maybe = null;                 // nullable declared type accepts null
  Order? o = Order.FirstOrDefault(); // entity-typed local — `?`, because …OrDefault() may answer null
  if (o != null) { return o.Total + d; }
  return d + x + big + maybe ?? 0;
}

The ? on o is the example, not a typo. A …OrDefault() read answers null when nothing matches, so a non-nullable Order o would be holding a null the moment the table is empty — and every later read of it would be an unguarded one. The compiler refuses that declaration and names both honest choices: Order? o if absent is a case you handle, or First() if it is not, which fails loudly at the read instead of handing you a null that surfaces somewhere else. This page carried the non-nullable form until 2026-08-27, when the check that catches it landed.

See also#

Related

Numeric types & literal suffixes

The platform numeric types are int, long, decimal, and double. Literals follow C# exactly, suffixes (L, m, d) included:…

const

A value fixed at compile time and folded into the places it is used. Declare one at the TOP LEVEL to share it across…

var

Declares a local whose type is inferred from its initializer, exactly as in C#. The local is still statically typed —…