When the library is expanded, the type of the binding of each (exported) identifier is known, i.e. whether it is a variable or a keyword. This is what has to be recorded in a precompiled library file. The value of the binding, however, is in general not known at expansion time but only after the library is visited or invoked (in the sense of the Dybvig/Ghuloum paper). Here is an example:
(define-library (foo)
(import (scheme base) (scheme file) (scheme read))
(export bar)
(begin
(define bar (call-with-input-file "value.scm" read)))
After expanding this library, it is known that `bar' is bound to a variable. It's value is not known until the library is invoked, which mustn't happen before the program is run. Note that the value of `bar' is never altered, but initialized only once per program run.
Ah, I see. By "in general" I meant most code out there, where the expression that yields the value is also visible and
fixed at the compile time of the imported library, hence visible from the expansion time of the importing library.
(Especially, we're talking about optimizing the procedure.)
Yes, it is not always possible as your example shows (and I see you meant that by "in general"), but I'd rather think in vast
majority of cases it is known. And optimizations are for majority of cases rather than for rare cases.