Scheme Scoping (define and enable)

So, I know that in Scheme define for dynamic overview and for static coverage, but the following confuses me:

If i have

(let ((x 0))
  (define f (lambda () x))
  (display (f))
  (let ((x 1))
    (display (f))
    )
  )

It will display 00. So far so good. However, if I add an additional definition for x, for example:

(let ((x 0))
  (define f (lambda () x))
  (display (f))
  (define x 4)
  (let ((x 1))
    (display (f))
    )
  )

Undefined4 is displayed. Why is this? Why does the definition of x after evaluating f affect the return value (f)? And why is this return value "undefined"?

It's also worth mentioning that linking f to letrec instead of define will also work:

(let ((x 0))
  (letrec ((f (lambda () x)))
  (display (f))
  (define x 4)
  (let ((x 1))
    (display (f))
    )
  )
)

Returns 00.

Note. I used DrRacket with the language set to "Pretty Big"

+5
source share
3 answers

, , , (define x 42) x , . , , undefined (define x 42).

(let ()
  ;; up here, `x` is defined but has an undefined value
  ;; ...
  (define x 42)
  ;; down here `x` has the value 42
  ;; ...
  )

:

(let ([x 'undefined])
  ;; ... up here, `x` is 'undefined
  (set! x 42)
  ;; ... down here, `x` is 42
  )
+5

- ( R5RS, R6RS R7RS). <body> ( let ) :

<body> -> <definition>* <sequence>
<sequence> -> <command>* <expression>
<command> -> <expression>

, , define ( <definition>) display (a <expression>). , , / "let".

"" R6RS:

> (let ((x 0))
  (letrec ((f (lambda () x)))
  (display (f))
  (define x 4)
  (let ((x 1))
    (display (f))
    )
  )
)
Unhandled exception
 Condition components:
   1. &who: define
   2. &message: "a definition was found where an expression was expected"
   3. &syntax:
       form: (define x 4)
       subform: #f
   4. &trace: #<syntax (define x 4)>
> 
+1

1: f , , 00, .

Case 2: I'm not very sure about this, but the inner one (define x 4)hides the outermost binding x = 0 and is in scope, even though it is a text message after calling function f. Then a certain trick evaluation order makes the first challenge a case before the new binding x is fully initialized, so it is "uninitialized". The second call in internal let occurs after everything is initialized, therefore 4.

Case 3: Now that we explicitly put letrec and define in separate areas, f explicitly refers to an external let. The definition does nothing here.

0
source

All Articles