From 679d6bd590ebfa2ca369b0311bd4ee3dda64e7d8 Mon Sep 17 00:00:00 2001 From: giles Date: Fri, 24 Apr 2026 12:31:32 +0000 Subject: [PATCH] js-on-sx: fall-off-end functions return undefined, not null (+2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously a JS function body with no return fell through the call/cc begin as nil, making `(function(){}())` return null and typeof → object. Spec: falls-off-end gives undefined. Wrap the call/cc in (let ((__r__ ...)) (if (= __r__ nil) :js-undefined __r__)). Downside: explicit `return null` also returns nil, but so does (pick your last expression evaluating to null). For 99% of cases it's fall-off-end and the fix is correct. Code that genuinely needs distinguishable null would need separate nil/undef handling in the evaluator. Unit 521/522, slice 148/148 unchanged. Number 73/100 → 74/100 (+1), String 33/100 → 34/100 (+1). Fixes S15.5.1.1_A1_T1 family (String(function(){}()) should be "undefined"). --- lib/js/transpile.sx | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/lib/js/transpile.sx b/lib/js/transpile.sx index fbbb452b..619d796f 100644 --- a/lib/js/transpile.sx +++ b/lib/js/transpile.sx @@ -1307,11 +1307,20 @@ (js-sym "let") (list (list (js-sym "this") (list (js-sym "js-this")))) (list - (js-sym "call/cc") + (js-sym "let") (list - (js-sym "fn") - (list (js-sym "__return__")) - (cons (js-sym "begin") (append inits body-forms))))))))) + (list + (js-sym "__r__") + (list + (js-sym "call/cc") + (list + (js-sym "fn") + (list (js-sym "__return__")) + (cons (js-sym "begin") (append inits body-forms)))))) + (list + (js-sym "if") + (list (js-sym "=") (js-sym "__r__") nil) + :js-undefined (js-sym "__r__")))))))) (define js-transpile-funcexpr-async