JavaScript Interop
Calcit keeps JS interop syntax intentionally small. This page covers the existing core patterns:
- global access
- property access
- method call
- array/object construction
- constructor call with
new
Access global values
Use js/... to read JavaScript globals and nested members:
do js/window.innerWidth
Access properties
Use .-name for property access:
let
obj $ js-object (:name |Alice)
.-name obj
This compiles to direct JS member access. For non-identifier keys, Calcit uses bracket access automatically.
Optional access is also supported with .?-name, which maps to optional chaining style access.
Call methods
Use .!name for native JS method calls (object first, then args):
.!setItem js/localStorage |key |value
Optional method call is supported with .?!name.
Note:
.mand.!mare different..mis Calcit method dispatch (traits/impls), while.!mis native JavaScript method invocation.
Construct arrays
Use js-array for JavaScript arrays:
let
a $ js-array 1 2
.!push a 3 4
, a
Construct objects
Use js-object with key/value pairs:
js-object
:a 1
:b 2
js-object is a macro that validates input shape, so each entry must be a pair.
Equivalent single-line form:
js-object (:a 1) (:b 2)
Create instances with new
Use new with a constructor symbol:
new js/Date
With arguments:
new js/Array 3
Async interop patterns
Calcit provides async interop syntax for JS codegen.
Mark async functions
Use hint-fn async in function body when using js-await:
js-await should stay inside async-marked function bodies.
let
fetch-data $ fn () nil
fn ()
hint-fn async
js-await $ fetch-data
Await promises
Use js-await for Promise-like values:
fn ()
hint-fn async
let
p $ new js/Promise $ fn (resolve _reject)
js/setTimeout
fn () (resolve |done)
, 100
result $ js-await p
, result
Build Promise helpers
A common pattern is wrapping callback APIs with new js/Promise:
defn timeout (ms)
new js/Promise $ fn (resolve _reject)
js/setTimeout resolve ms
Then consume it inside async function:
let
timeout $ fn (ms) $ new js/Promise $ fn (resolve _reject)
js/setTimeout resolve ms
fn ()
hint-fn async
js-await $ timeout 200
Async iteration
Use js-for-await with js-await for async iterables:
let
gen $ fn () nil
fn ()
hint-fn async
js-await $ js-for-await (gen)
fn (item)
new js/Promise $ fn (resolve _reject)
js/setTimeout $ fn ()
resolve item