Exercise 1: Redeclaring a Variable in the Same Scope — Possible Solution ==================================================================== THE RELEVANT CODE (unchanged from the chapter) ------------------------------ def define(self, name, value): self.values[name] = value def visit_var_stmt(self, stmt): value = stmt.initializer.accept(self) if stmt.initializer is not None else None self.env.define(stmt.name, value) RESULT ------------------------------ var x = 1; var x = 2; print x; -> 2 WHY THIS WORKS AS AN ANSWER ------------------------------ define() is a plain dict assignment -- `self.values[name] = value` -- with no "does this key already exist" check anywhere. The second `var x = 2;` simply overwrites the first entry in the SAME dict. Nothing raises, nothing warns; the second declaration silently wins. This is genuinely a different case from the chapter's own shadowing example, even though both involve a name being "redeclared." Shadowing (the chapter's `{ var x = "inner"; }` example) creates a NEW dict -- a fresh block Environment with its own `values` -- so the outer `x` still exists, untouched, one level up the `enclosing` chain, and reappears the moment the block ends. This exercise's redeclaration happens inside the SAME Environment object, so there is only ever one dict entry for `x`, and the second `var` statement genuinely overwrites, rather than hides, the first. Whether same-scope redeclaration should be a compile-time error is a real, debated language design choice -- Rust explicitly allows it (and even encourages it, calling it "shadowing" too, confusingly, in a same-scope form), while many statically-typed languages treat it as a duplicate-declaration error. This chapter's own Environment doesn't take a position on that question one way or the other -- define() simply doesn't check, which means the language currently behaves like Rust's permissive version by default, not by deliberate design choice. Adding a check would mean tracking, at parse or interpret time, whether a name has already been declared in the CURRENT block's own declaration list before allowing a second `var` for it.