slang

Limitations

What slang does not do, stated plainly.

Markdown version · llms.txt · api.json

Known limitations

  • Block scoping: a let inside if/else/while/for is not visible afterwards. Loop bindings (for i in ...) are scoped to the loop. Redeclaring a name in the same scope is an error; inner blocks may shadow. guard let still binds for the rest of its enclosing block.
  • Strings are immutable; concatenation allocates. The collector reclaims unreachable strings automatically.
  • Package globals require constant-literal initializers.
  • Implicit returns only apply to the last statement of a function body; if and {} blocks are statements, not expressions yet.
  • No closures. Functions are values (fn(int) -> int), but they capture nothing — a function value always names a top-level function, never an environment. break/continue work inside loops.
  • Package-level lists are not supported yet (scalars and bytes are).
  • Map keys are limited to integers, str, and bool.
  • No data-race protection: spawn gives you real concurrency and per-task failure isolation, not an ownership/borrow checker. Mutating a shared struct/list/map from more than one task is on you, same as Go or Java — mutex is available for it, but nothing makes you reach for one.
  • select has no timeout arm and no way to disable an arm. A closed channel's recv arm is ready forever (see Concurrency above), and there is no nil channel to switch it off with; for a deadline, feed a channel from a spawned timer task.
  • mutex has no scope guard: without closures or defer, an early return between mutex_lock and mutex_unlock leaks the lock. Mutexes are also not recursive (locking one twice from the same task is a checked error, not a hang).
  • TLS: no session resumption tuning. Handshake and send/recv park; getaddrinfo in tls_dial parks the task while a dedicated thread resolves. mTLS (tls_ctx_require_client / tls_ctx_use_cert) and SNI extra certs (tls_ctx_add_sni) are supported.
  • JSON: no dynamic/unknown-shape decoding (every decode target is a concrete slang type known at compile time — see the json section above), and JSON object keys map to struct field names verbatim (no camelCase/snake_case conversion). bytes fields are base64 strings (RFC 4648).
  • proc: only SIGTERM/SIGINT are handled (there's no general signal-registration API); a signal that arrives in the narrow window before main() installs the handler gets the OS's default disposition (immediate termination) rather than graceful handling. proc.wait_idle() parks until proc.active_tasks() is zero.