Open yorickhardy opened 1 year ago
After macro expansion, the following code segment is generated:
(call-with-values
(lambda () (screen->viewport x$1215 y$1219))
(lambda (x$1215$1225 x$1215$1226)
((lambda (x$1228 y$1229)
((lambda ()
((lambda (ray$1232)
((lambda (intersection$1235)
((lambda ()
(if (is-some?
intersection$1235)
(call-with-values
(lambda ()
(apply values
(unwrap
intersection$1235)))
(lambda (x$1228$1242
x$1228$1243)
((lambda (shape$1245
position$1246)
((lambda ()
(vec3->color
(shade-pixel
shape$1245
position$1246
(ray-origin
ray$1232))))))
x$1228$1242
x$1228$1242)))
(ray-color
(coordinate->ray
x$1228
y$1229))))))
(ray-intersect-scene ray$1232)))
(coordinate->ray x$1228 y$1229)))))
x$1215$1225
x$1215$1225))))
In the inner call-with-values, the last argument should be x$1228$1243, while the last argument for the outer call-with-values should be x$1215$1226
Still investigating: if I change one of the identifiers in the templates in the syntax-rules for let-values, then it seems to work.
--- scheme/base.sld.orig 2023-03-04 18:54:17.000000000 +0000
+++ scheme/base.sld
@@ -1950,9 +1950,9 @@
"mktmp"
b
e0
- (arg ... x)
+ (arg ... xyzzy)
bindings
- (tmp ... (a x))
+ (tmp ... (a xyzzy))
body))
((let-values
"mktmp"
The renaming of variables in the previous comment obviously does not work in general. The problem is that free variables "x" are introduced in the template, but they may already be bound in the scope surrounding the macro evaluation. Here is a small example:
(import (scheme base) (scheme write))
; x is free in a template in scheme/base.sld let-values
; expected output (1 2)
; actual output (1 1)
(let ( (x 3) )
(let-values ( ((x y) (values 1 2)) )
(display (list x y)) (newline) ) )
The easiest fix is perhaps to just set let-values == let*-values.
Apologies for the many replies!
This is probably issue #431 and not really about let-values.
No need for apologies @yorickhardy - thanks for raising this issue and working through it!
When I tried the ray tracer https://git.sr.ht/~jakob/lisp-raytracer-zoo/tree/master/item/r7rs-raytracer.scm with cyclone, I see the error
Patching r7rs-raytracer.scm with (i.e. replacing let-values) yields a working ray tracer:
The problem seems to be that
(let-values (((shape position) (...))) ...)
binds the same value to shape and position (both are bound to a shape). I tested this a bit more in the ray tracer code and the value bound to the first variable is bound also to all subsequent variables -- but I cannot reproduce it yet in a small example (small examples all seemed to work as expected). I also looked at the implementation of let-values and could not find any bugs, sorry!