for completeness i wanted to see what the spec says (r5rs). e.g. common lisp's defun is processed in the lexical environment, but defines the function in the global environment, so
CL-USER> (defun foo ()
(defun bar () :result-of-bar)
:result-of-foo)
FOO
CL-USER> (ignore-errors (bar))
NIL
#<UNDEFINED-FUNCTION @ #x1000e64422>
CL-USER> (foo)
:RESULT-OF-FOO
CL-USER> (bar)
:RESULT-OF-BAR
i know that's not the case in scheme, but they do it by differentiating "at the top level of a ⟨program⟩ and at the beginning of a ⟨body⟩"
5.2.2. Internal definitions
Definitions may occur at the beginning of a ⟨body⟩ (that is, the body
of a lambda, let, let*, letrec, let-syntax, or letrec-syntax
expression or that of a definition of an appropriate form). Such
definitions are known as internal definitions as opposed to the top
level definitions described above. The variable defined by an internal
definition is local to the ⟨body⟩. That is, ⟨variable⟩ is bound rather
than assigned, and the region of the binding is the entire ⟨body⟩. For
example,
(let ((x 5))
(define foo (lambda (y) (bar x y)))
(define bar (lambda (a b) (+ (* a b) a)))
(foo (+ x 3))) =⇒ 45
A ⟨body⟩ containing internal definitions can always be con- verted
into a completely equivalent letrec expression. For example, the let
expression in the above example is equiv- alent to
(let ((x 5))
(letrec ((foo (lambda (y) (bar x y)))
(bar (lambda (a b) (+ (* a b) a))))
(foo (+ x 3))))
Just as for the equivalent letrec expression, it must be possible to
evaluate each ⟨expression⟩ of every internal def- inition in a ⟨body⟩
without assigning or referring to the value of any ⟨variable⟩ being
defined.
Wherever an internal definition may occur (begin ⟨definition1⟩ . . . )
is equivalent to the sequence of defini- tions that form the body of
the begin.