Hello y'all, So I'm working on a project with a moderate amount of macros and some tangled code paths. Which often means I have non-linear and hard-to-figure-out inter-dependencies between pieces of code. One of them bit me today: a macro that was defined after a procedure it was used in, resulted in an "Unbound variable" error when the procedure was called. The procedure was called long after the macro was finally defined, so it shouldn't have been a problem. Find the test file attached and use it as:
``` GUILE_LOAD_PATH=.:$GUILE_LOAD_PATH guile scheme@(guile-user)> (use-modules (test)) ;;; note: source file ./test.scm ;;; newer than compiled /.../test.scm.go ;;; note: auto-compilation is enabled, set GUILE_AUTO_COMPILE=0 ;;; or pass the --no-auto-compile argument to disable. ;;; compiling ./test.scm ;;; test.scm:7:5: warning: possibly unbound variable `a' ;;; test.scm:8:5: warning: possibly unbound variable `b' ;;; compiled /.../test.scm.go scheme@(guile-user)> (testing) ;; ice-9/boot-9.scm:1685:16: In procedure raise-exception: ;; Unbound variable: a ;; ... ```
(define-module (test) #:export-syntax (with-something) #:export (testing)) (define (testing) (with-something ((a 1) (b a)) 'hello)) (define-syntax-rule (with-something ((var init) ...) body ...) (let* ((var init) ...) (begin body ...) #t))
The expected behavior is that both "a" and "b" are defined and macro expanded during compilation, regardless of whether it was defined before or after use. I'm not sure if that's a valid bug, but here you go anyway. Best of love, -- Artyom Bologov https://aartaka.me