Expressions
This page covers Chute's expression syntax, everything you can write on the right side of an =, pass as an argument, or use in a pipeline.
Arithmetic
Standard arithmetic operators work on Number values:
| Operator | Meaning |
|---|---|
+ | Addition |
- | Subtraction |
* | Multiplication |
/ | Division |
% | Modulo (remainder) |
const sum = a + b;
const product = width * height;
const remainder = 10 % 3;Unary negation:
const negative = -x;Arithmetic on non-number types is a compile error.
String interpolation
Embed expressions inside a string with ${}:
const name = "World";
const greeting = "Hello, ${name}!";
const math = "2 + 2 = ${2 + 2}";Interpolated strings are always typed as Text.
Raw strings
Use #"..."# for strings without escape processing:
const pattern = #"no \n escapes here"#;Literals
List literals
const numbers = [1, 2, 3];
const names = ["Alice", "Bob"];
const empty = [];Dictionary literals
const person = {"name": "Alice", "age": 30};
const empty = {:};The empty dictionary uses {:} to distinguish it from an empty block.
Boolean literals
const yes = true;
const no = false;Nil literal
const nothing: Number? = nil;See Types for optional types and nil coalescing.
Member access
Access fields on records and dictionaries with dot notation:
const name = person.name;
const x = point.x;Properties on opaque types
Some types like Date, URL, and Contact are opaque — they come from Shortcuts and don't have fields you defined. You can access their properties with dot notation:
import Scripting
let d = Scripting.date();
let y = d.year;
let m = d.month;Available properties depend on the type. For example, Date has year, month, day, hour, minute, second, and weekday. URL has scheme, host, path, query, and fragment. Accessing an unknown property is a compile error.
Optional chaining works the same way:
let od = d as Date;
let y = od?.year; // Number?Type coercion
Use as to coerce a value from one type to another:
let n = someText as Number;Coercion returns an optional because it can fail at runtime. someText as Number has type Number?, not Number.
The compiler validates that the conversion is plausible. text as Number is allowed, but boolean as Date is a compile error. Use ?? to provide a fallback:
let n = someText as Number ?? 0;Coercion works in pipelines with _ as Type:
let n = getText() |> _ as Number;Property access also works in pipeline stages:
let year = Scripting.date() |> _.year;Optional chaining
Use ?. to safely access a member of an optional value. If the value is nil, the result is nil instead of an error:
const name = maybePerson?.name; // Text? — nil if maybePerson is nilOptional chaining is only valid on optional types. Using ?. on a non-optional is a compile error.
Subscript access
Access list elements or dictionary values by index or key:
const first = items[0];
const value = dict["key"];Ternary expression
A compact conditional expression:
const label = x > 0 ? "positive" : "non-positive";The condition uses the same syntax as if conditions (see Control flow). Both branches must produce the same type.
Conditions
Conditions are a separate category from value expressions. They appear in if statements, else if, and ternary expressions, but not as standalone values.
Comparison operators
| Operator | Meaning |
|---|---|
== | Equal to |
!= | Not equal to |
> | Greater than |
>= | Greater than or equal |
< | Less than |
<= | Less than or equal |
String operators
| Operator | Meaning |
|---|---|
contains | Text contains substring |
!contains | Text doesn't contain substring |
hasPrefix | Text starts with |
hasSuffix | Text ends with |
if (name contains "Alice") { ... }
if (url hasPrefix "https") { ... }Logical operators
| Operator | Meaning |
|---|---|
&& | Both conditions must be true |
|| | Either condition can be true |
! | Negates a condition |
if (x > 0 && x < 100) { ... }
if (a || b) { ... }
if (!done) { ... }Type tests
Use is to test a value's type at runtime:
if (value is Number) { ... }Range tests
Use in with ... to test if a value falls within a range:
if (x in 1...10) { ... }Grouping
Use parentheses to control evaluation order:
if ((x > 0 && x < 10) || x == 100) { ... }Dot-name shorthand
When the expected type is an enum, you can use .caseName instead of EnumName.caseName:
const dir: Direction = .north;See Enums and records for details.
#index
Inside a repeat loop, #index evaluates to the current iteration index (starting from 1). It's typed as Number.
repeat 3 {
showAlert("Iteration ${#index}");
}#index is only valid inside repeat blocks and for loop bodies.
Comments
// This is a line comment
/* This is a
block comment */Comments are ignored by the compiler and don't appear in the compiled output.
Related
- Variables and bindings: using expressions in declarations
- Control flow: conditions in
ifandfor - Pipelines: chaining expressions with
|> - Types: optional chaining, nil coalescing