jolt/.dirge/memory/PITFALLS.md
2026-06-02 08:43:27 -04:00

1.3 KiB

Janet structs silently omit entries with nil values: (struct ;[:x nil :y 1]){:y 1}. The :x key is completely dropped from the struct, not just set to nil. Use @{} (mutable table) when map needs nil-valued entries. This caused the &env implicit binding to fail — (put new-bindings "&env" {'ns nil}) created a struct that became empty {}, so (:ns &env) failed with unknown method. Fix: use @{} table for bindings that may contain nil values, or use a non-nil sentinel. § Janet (put table key nil) silently drops the key — it's a no-op, not a way to store nil. This is SEPARATE from struct-nil-drop: even mutable @{} tables drop nil values on put. The bind-put helper in evaluator.janet stores nil as :jolt/nil sentinel; resolve-sym unwraps it back to nil. All binding put calls in fn*, let*, loop*, macro bodies, and deftype reify MUST use bind-put, not raw put. § Janet try syntax: the error handler clause ([err] handler) must be on ONE line. Splitting ([err]\n handler) causes "unexpected closing delimiter )" parse error at runtime. This is a Janet parser limitation, not a Jolt issue. Fix: always write (try body ([err] handler-body)) on one line, or use (do ...) for multi-line handlers: (try body ([err] (do ...))).