munificent / craftinginterpreters

Repository for the book "Crafting Interpreters"
http://www.craftinginterpreters.com/
Other
8.5k stars 1.01k forks source link

Issues with closures in JLox #1029

Closed Yummy-Pizza closed 2 years ago

Yummy-Pizza commented 2 years ago

The following code:

{
   fun a() {
      b();
   }
   fun b() {
      print "Hello world!";
   }
   a();
}

throws an error saying that "b" is undefined. When the Resolver class resolves body of "a" "b" is not yet defined. So "b" is not put in the "locals" map. This code works with global functions because the "lookupVariable" function defaults to looking in the "globals" map. How can this issue be overcome? Languages like JavaScript would handle this perfectly fine.

munificent commented 2 years ago

This is by design and is how Lox is intended to behave. Lox doesn't support mutually recursive local functions.

JavaScript handles this using "hoisting", which causes its own problems. You can work around this, like:

{
   var b;
   fun a() {
      b();
   }
   fun b_() {
      print "Hello world!";
   }
   b = b_;
   a();
}