Reputation: 156
I've been playing around in Chicken Scheme for a short while but I noticed something unusual. Let's say I have the following simple source file:
(define (f x)
(g x))
It's obvious (to a human bean) that this can't work. When I start up csi
and manually enter this function definition I get the following message:
Note: the following toplevel variables are referenced but unbound:
g (in f)
That's good to know! Finding typos in larger programs is good before you run them. Now, let's start up csi
again and try to load
the file:
(load "test.scm")
Output:
; loading test.scm ...
Note: the following toplevel variables are referenced but unbound:
g (in f)
Also good. Now, let's try starting up csi
with that file!
$ csi test.scm
CHICKEN
(c) 2008-2015, The CHICKEN Team
(c) 2000-2007, Felix L. Winkelmann
Version 4.10.0 (rev b259631)
linux-unix-gnu-x86-64 [ 64bit manyargs dload ptables ]
compiled 2015-08-04 on yves.more-magic.net (Linux)
; loading test.scm ...
#;1>
Uh... where did the error message go? Why is it not there? Okay, maybe it will complain when I actually try to compile it...
$ csc test.scm
$
Nope. Even when I add the line (f 2)
to the end of the file (to avoid the f
-function being optimized away) I still don't get any sort of error message or warning.
Why? How can the interpreter (or at least the manual load
part of it) immediately notice this problem but the compiler can't? Funnily enough, there is a -no-warnings
argument for the compiler. As expected, it does nothing since there are no warnings.
What am I missing? How can I fix it? Can it be fixed or will I have to manually load
every single involved file manually in csi
before actually compiling any programs with some confidence?
Upvotes: 1
Views: 376
Reputation: 2292
The reason that this doesn't give an error message is that CHICKEN supports separate compilation. This works just like in for example C: you can compile files separately and then later link them together to form an executable. Also, it's possible to (re)define a variable in code ran through eval
, which means the compiler can't make too many assumptions about this (by default).
If you'd like to get an error, I'd suggest you modules. These are supposed to be completely "closed worlds", so if an identifier is unreferenced, it will produce an error:
$ cat foo.scm
(module foo (f)
(import chicken scheme)
(define (f x)
(g x))
)
$ csc foo.scm
Warning: reference to possibly unbound identifier `g' in:
Warning: main#f
Error: module unresolved: main
Error: shell command terminated with non-zero exit status 256: csc foo.scm
You can also use csc -M
to implicitly wrap the entire code in a (nameless) module, for convenience.
Upvotes: 2