Skip to main content
Lion’s expression model is the foundation of the language: every program is a valid JSON value. There is no separate syntax to learn, no parser to invoke, and no serialization step. Numbers, booleans, null, strings, arrays, and objects are all Lion expressions, each evaluated according to its own rules. This homoiconic design means programs can be stored in databases, sent over HTTP, and generated by other systems — because they are already data.
Numbers, booleans, and null are self-evaluating — they return themselves unchanged. Strings are treated as environment references: if the string matches a key in the current environment the bound value is returned; if no binding exists the string returns as-is.
42
Evaluates to 42.
true
Evaluates to true.
null
Evaluates to null.
"x"
With { "x": 10 } in the environment, evaluates to 10. With no binding, evaluates to "x".
"number/add"
Resolves to the stdlib addition function because stdlib contains a "number/add" key.

Expression schema

Internally, Lion validates every value against the LionExpressionSchema before evaluation begins. The schema is a union of three branches:
export const LionExpressionSchema = Schema.Union(
  JsonPrimitiveSchema,        // number | boolean | null | string
  LionArrayExpressionSchema,  // readonly LionExpression[]
  LionRecordExpressionSchema  // { [key: string]: LionExpression }
);
Anything that does not conform — such as a JavaScript Date, undefined, or a class instance — is rejected at the boundary before evaluation starts.