chansey97
2020-10-24 21:09:55

I have a question about identifier binding:

In REPL, I typed: test.rkt> (define (test env) 1) test.rkt> (test (λ (var) ⊥)) 1 It is OK.

But in the test.rkt file: #lang racket (define (test env) 1) (test (λ (var) ⊥)) It complained ⊥: unbound identifier in module

Although the in the body of the lambda is unbound identifier, but I doesn’t use it at all. Why it complained?


sorawee
2020-10-24 21:28:39

Actually, the REPL’s behavior is considered bad, but we need to support it for mutually recursive function.


sorawee
2020-10-24 21:29:09

E.g.,

test.rkt> (define (a) (b)) test.rkt> (define (b) (a))


sorawee
2020-10-24 21:30:11

If the REPL reports unbound identifier right away, (define (a) (b)) would result in an error.


soegaard2
2020-10-24 21:39:26

Think about this way: In a module (file) the compiler checks for a wider range of errors than it can in the repl. In a module all identifier needs to be bound, hence the error that ⊥ is undefined. In the repl there are are fewer checks - in particular identifiers in the body of a lambda expression are allowed to be unbound. As Sorawee says, this allows the definition of mutually recursive functions in the repl.


soegaard2
2020-10-24 21:40:10

That is, the question is not why you get an error in the module (file), but why you don’t get an error in the repl!


chansey97
2020-10-24 21:50:38

OK, It make sense. Thanks. @sorawee @soegaard2


kellysmith12.21
2020-10-24 22:41:44

Is it generally better to use a box instead of set!?


notjack
2020-10-25 00:02:07

I prefer doing so


notjack
2020-10-25 00:02:50

I don’t think there’s any consensus about it in the Racket community though


notjack
2020-10-25 00:03:16

I think it’s good to make mutation a distinct concept from binding