Welcome to the CHICKEN Scheme pasting service

Patch added by sjamaan 6 hours ago

From 3bc8e7b77ff62fb25b5b43782f60e65478e238ef Mon Sep 17 00:00:00 2001
From: Peter Bex <peter@more-magic.net>
Date: Tue, 3 Nov 2026 09:54:54 +0100
Subject: [PATCH] Allow procedures introduced by internal define or letrec to
 be called directly

If a variable is "undefined", it means it is currently undefined and
will receive a value.  We only use this to mark variables introduced
by letrec and internal defines, and they will receive a value by
assignment only once.  This invisible, internal assignment prevented
the compiler from performing almost any optimization.

This also meant that a procedure that was introduced by an internal
define or "letrec" would not be optimizable in the same way as when
that procedure would be introduced by a regular "let".  Both
approaches are considered idiomatic, and it is very unintuitive for
the typical Scheme programmer that code would perform differently
depending on how the variable was introduced.

Now we treat an assignment of a variable with an 'undefined value as
the same as a regular let.  This allows the compiler to have access to
its value and allow it to make certain optimizations it otherwise
wouldn't be able to.

Note that if a variable is 'undefined and then gets assigned to "by
hand", it will still be marked as 'unknown.
---
 NEWS     | 6 ++++++
 core.scm | 4 ++--
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/NEWS b/NEWS
index 0e5f4b2d..5421b5bf 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,9 @@
+6.2.0
+
+- Compiler
+  - Allow direct calls of procedures introduced by internal defines and letrec
+    (reported by Kristian Lein-Mathisen)
+
 6.1.0
 
 - Core libraries
diff --git a/core.scm b/core.scm
index 4d9d7e62..fc7ee6b9 100644
--- a/core.scm
+++ b/core.scm
@@ -2243,12 +2243,12 @@
 	    ((or (memq var env)
 		 (variable-mark var '##compiler#constant)
 		 (not (variable-visible? var block-compilation)))
-	     (let ((props (db-get-all db var 'unknown 'value))
+	     (let ((props (db-get-all db var 'unknown 'value 'undefined))
 		   (home (db-get db var 'home)) )
 	       (unless (assq 'unknown props)
 		 (if (assq 'value props)
 		     (db-put! db var 'unknown #t)
-		     (if (or (not home) (eq? here home))
+		     (if (or (not home) (eq? here home) (assq 'undefined props))
 			 (db-put! db var 'value val)
 			 (db-put! db var 'unknown #t) ) ) ) ) )
 	    ((and (or local-definitions
-- 
2.51.2

Your annotation:

Enter a new annotation:

Your nick:
The title of your paste:
Your paste (mandatory) :
Which one-argument R5RS procedure returns 3 when given `'(1 2 3 4)' as input?