Skip to content

Operators & built-ins

OperatorArityOperandsResultNotes
+ - * /binaryIntIntarithmetic; no %
-unaryIntIntnegation
== !=binarysame typeBoolnon-associative
< <= > >=binaryIntBoolcomparison
&& ||binaryBoolBoollogical
!unaryBoolBoollogical not
impliesbinaryBoolBoollogical implication (P implies Q!P || Q, directional); lowest precedence; in invariant predicates (invariants)
isbinarysum value + patternBoolvariant test, may bind (guide)
?postfixResultunwraps Okpropagates Err; only in a Result-returning fn
<-bindEffect[T]Tsequences an effect in a let
~>prefixEffect[()]statementasynchronous (fire-and-forget) send; the reply is discarded, so it is restricted to Effect[()] (guide)

There is no string concatenation operator: + requires Int operands.

Lowest to highest:

  1. assert (in expression position)
  2. implies (lowest-precedence operator; predicate language)
  3. ||
  4. &&
  5. == != is (non-associative — no chaining)
  6. < <= > >=
  7. + -
  8. * /
  9. unary - !
  10. postfix: ?, .field, .method(…), calls

So assert x == 1 parses as assert (x == 1), and a + b * c as a + (b * c).

Duration (a span) and Instant (an absolute point in time) compose through a fixed operator surface; every other numeric mix between them — or with Int — is a bynk.types.no_numeric_coercion error.

ExpressionResultNotes
Duration ± DurationDurationsubtraction is unclamped (may go negative)
Duration * Int / Int * DurationDurationscalar scaling
Duration vs Duration (< <= > >=)Boolcomparison
Instant ± DurationInstantadvance / retreat
Instant - InstantDurationthe span between
Instant vs Instant (< <= > >=)Boolchronological ordering

Instant is orderable (so sortBy/min/max key on it) but not numeric (sum/average reject it). Timestamp math goes through InstantClock.now() + 5.minutes is Instant + Duration. The earlier Int + Duration -> Int clock-math coercion was withdrawn at v0.90; mixing Instant with Int now errors. Convert explicitly with d.toMillis() / Duration.millis(n) and t.toEpochMillis() / Instant.fromEpochMillis(n). See types.

FormMeaning
if c { … } else { … }conditional expression; branches share a type
match e { … }exhaustive pattern match (types)
let x = e / let x: T = ebinding; let x <- e binds an effect
T.of(…) / T.unsafe(…)refined/opaque construction (refined types)
name := ewrite a store Cell field; committed at handler end (agents)

Int, Float, String, Bool, Duration, Instant, the unit (), and the generics Result[T, E], Option[T], Effect[T], HttpResult[T], Stream[T], Query[T]. See the type system reference.