Philip McGrath schreef op zo 27-03-2022 om 10:12 [-0400]: > In the context of Racket or R6RS modules, where the semantics are > essentially those of `letrec*`, I'm used to distinguishing "unbound" > variables from "undefined" variables, two types of errors, though > informally "defined" is often used more loosely: Guile also distinguished them, though possibly in a different way, and terminology is inconsistent. > >   1. Every variable reference must refer to a lexically visible > binding, or it is an "unbound" variable error. Inherently, this > can *always* be detected statically at compile time. This is different in Guile. If a variable reference 'foo' is not a lexical variable, then Guile assumes it is a global variable -- it doesn't check if the name of the global variable reference actually belongs to an imported module, this only happens at runtime. Apparently Guile is a bit lazier than Racket. > >   2. A variable may not be accessed until it has been initialized.( > More precisely, we could discuss a variable's "location", which > I see is part of Guile's model.) This is the essence of the > `letrec`/`letrec*` restriction: while the "fixing letrec" > papers[4][5] show that useful static analysis can be done, this > is fundamentally a dynamic property. Violating the restriction > is an "undefined" variable error at runtime. I don't know how Guile handles letrec/letrec*. However, Guile has undefined(uninitialised? unbound? Guile has inconsistent terminology here) variables: (define foo) ; no value foo ; I thought this would raise an "Unbound variable: ..." error but apparently not? A bug? Looks like it returns *unspecified* instead ... (variable-ref (make-undefined-variable)) ; -> Unbound variable: ... (define f (make-variable #f)) (variable-unset! f) (variable-ref f) ; --> Unbound variable: #> (variable-ref (make-variable #f)) ; this variable has no name, so in a sense, it is not ‘bound’, yet it has a value Greetings, Maxime.