Counter your priors
No LLM was trained on Synsema, so a model writing Synsema falls back on habits from other
languages. These are the differences that bite. **Every claim here is verified against the
engine** (the ones below are a passing doctest):
-- Doc example: places where Synsema differs from what a fresh LLM assumes.
-- Every claim below is a passing assertion against the engine (doctested).
intent: "doc example: counter-your-priors gotchas"
require secret("API_KEY")
print("1 / 2 = " + text(1 / 2) + " (division is always float)")
test "division is ALWAYS float (1/2 is 0.5, not 0)"
assert_eq(1 / 2, 0.5)
assert_eq(type_of(1 / 2), "number")
test "there is no has(); use contains() for map keys"
let m be {"a": 1, "b": 2}
assert(contains(m, "a"))
assert(not contains(m, "z"))
test "concatenating text + secret redacts the WHOLE string (prefix absorbed)"
let k be secret("API_KEY", "sk-real-123")
assert_eq(type_of("Bearer " + k), "secret")
assert_eq(text("Bearer " + k), "secret(API_KEY)")
test "property access uses `of` (or dot)"
let cfg be {"host": "localhost", "port": 8080}
assert_eq(host of cfg, "localhost")
More gotchas (verified)
logis a statement, not a function. Writelog "message", notlog("message")—
the function form parses with check but crashes at runtime (Undefined variable: log).
random()/random_int()needrequire randomeven underrun— it is not
auto-granted (random is for tokens/nonces, so it's deny-by-default).
recall(...)is newest-first —[0]is the most recent entry — and truncates to 200
results (pass a 5th argument to raise the limit).
- LLM ops take a subject keyword:
reason about X,decide between [...] given X,
analyze X for "...", generate "..." given X. A bare reason "literal" only became
valid in a recent fix.
- A
:paramroute silently drops a.md/.jsonsuffix (it's content negotiation).
To detect the suffix, read path of request — the param itself is already stripped.
- Declared routes always beat
staticmounts. With wildcard routes like
GET /:lang/:version, a static "/assets" mount is never reached — serve assets with a
declared GET /assets/*path route instead.
- Division is always float:
1 / 2is0.5, andtype_of(1 / 2)is"number". printbuffers underrun— for a live REPL useflush()/read_line. Under
serve, print/log reach the terminal with a [serve] prefix.
- The lexer rejects a UTF-8 BOM, and a
use "..."import cannot escape its directory
(../x.syn is denied).
If a model keeps generating one of these wrong, copy this page into its context — it's exactly the prior that needs correcting.