#lang racket ;; Def'n [Scott, Sect.3.3]: Scope: ;; The textual region of a program in which a binding is active. ;; ;; ; Syntax of `let`: ; -> ( let { } ) ; ; -> [ ] ; -> ϵ | (let {[n 3]} (+ 3 (let {[k (* 7 n)]} (* k 2)) n)) ; In `let`, the scope of the introduced-bindings is the let's body. (let {[n 3]} (+ 3 (let {[k 7]} (* k (let {[j 99]} (/ j 3)) 2)) n)) #| You can also have shadowing: [1] (let {[n 3]} [2] (let {[n 5]} [3] (* n 2))) returns 10; the binding-occurence on line [2] is what is used on line [3]; I'll write "[2] -> [3]" (non-standard terminology). [1] (let {[n 3]} [2] (+ (let {[n 5]} [3] (* n 2))) [4] n) evaluates to 13 -- [2]->[3], and [1]->[4]. So the scope of the `n` on [2] is line [3] (but not [2]). So the scope of the `n` one line[1] is lines[2]-[4] ... except we say that the inner `n` "shadows" the outer one, for line[3]. ; Lisp/Scheme/Racket have "let*" which corresponds to nested-lets: ; ; #| Compare to java -- a very common pitfall for beginners: class Stuff { int[] nums; Stuff() { int[] nums = new int[365]; for (int i=0; i