Am Di., 17. März 2020 um 08:46 Uhr schrieb Shiro Kawai <xxxxxx@gmail.com>:
On Mon, Mar 16, 2020 at 9:14 PM Marc Nieper-Wißkirchen <xxxxxx@nieper-wisskirchen.de> wrote:

Why?  It is just as good as procedure inlining.  In R6RS the compiler can know an imported bindings won't be altered at runtime; in R7RS we need to interact with some implementation-specific convention.  In either way, the compiler can keep information about the bound value; only the "constantness" of the binding is needed to look it up.

In general, the final binding of an identifier in an R[67]RS library is not known until a library is "invoked" (in the sense of "Implicit Phasing for R6RS Libraries by Dybvig/Ghuloum). The invocation happens when the main program is run, which is after the program has been compiled.  I'm not saying that the compiler cannot deduce the binding for the most common cases, but, in general, it can't.

Hmm... here's my understanding:
When the compiler compiles a library or a program, it needs to look at the imported libraries, otherwise it can't know
which is macro keywords.  Whether the compiler looks at the entire source, or looks at some information stored in the
precompiled file, is up to the implementation, but I don't see anything that prevents the compiler from knowing
the nature of the binding.  If the mutation of binding of exported identifiers is prohibited, I'd rather see that generally
it is possible for the compiler to know the bindings, and it is an implementation's choice to ignore it (in favor of
flexibility, ease of compile, etc.)   It is possible that the imported library is updated after the importing library is
compiled, but I don't think that's what you mean, since allowing it precludes expansion of macros during compilation.

Is there a definite reason that makes the implementation delay to know the final binding until
invocation time?

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.

A similar example is the following:

(define-library (baz)
  (import (scheme base) (scheme file) (foo))
  (export quux)
  (begin
    (define-syntax quux
      (lambda (stx)
        bar)))

After expanding this library, it is known that `quux' is bound to a macro transformer.  It's value will be determined when the library `(baz)' is visited, for which `(foo)' has be invoked, which again mustn't happen before the program is run.

CL is different in this regard, IIUC, since it must allow the binding to be altered at runtime by default.
 

In any case, in this regard there is no difference between CL-style keywords and property lists.
 

In R7RS, macro is the only portable way to declare such "constantness" (by which I mean the compiler knows
the binding of an identifier won't be altered).    An implementation may have other means (Gauche has a few).
define/kw macro may hide such differences.

One can read the last paragraph of section 5.2 of the R7RS-small in such a way that the exporting library mustn't alter the binding of an exported identifier after it has been imported by some other library or the top-level program.

Right.  I think I was confusing REPL semantics and the general case.