 <p>This isn't an answer but it is too long for a comment: sorry.</p> <p>There are three possibilities for creating variable bindings that seem to be common:</p> <ol> <li>variables are explicitly bound at the start of a scope;</li> <li>there is a construct which creates a binding which can occur anywhere in a scope, but it's not just assignment;</li> <li>variables get implicitly bound in a surrounding scope on their first assignment.</li> </ol> <p>An example of (3) is Python. Languages which do this end up needing explicit scope-resolution operators (<code>global</code> and now <code>nonlocal</code> in Python) to deal with the stupid, lazy, pun they have done and are not worth discussing further: you need binding constructs which are distinct from assignment or you end up living in pain for ever.</p> <p>Common Lisp is an example of (1), and C used to be: they are both (C was) examples of languages where all the bindings needed to be created at the start of a scope construct.</p> <p>Within (1) there are languages which have some kind of block construct (<code>{</code> ... <code>}</code> in C) which can be used for grouping <em>and</em> for scope, and ones which have a grouping construct and one or more separate scoping constructs: CL is in the latter family.</p> <p>So in (old) C you would say</p> <pre><code>{ int i = 3; ... } </code></pre> <p>While in CL you say</p> <pre><code>(let ((i 3)) ...) </code></pre> <p>-- the scope construct here is <code>let</code> (and there are others of course).</p> <p>Of course, CL, being a Lisp, can perfectly happily invent a construct which looks like C's blocks:</p> <pre><code>(defmacro scope (&amp;body vars/body) (loop for (var? . body?) on vars/body while (and (listp var?) (&lt;= 2 (length var?) 3) (eql (first var?) 'var) (symbolp (second var?))) collect (case (length var?) (2 (second var?)) (3 (rest var?))) into bindings finally (return `(let* ,bindings ,var? ,@body?)))) </code></pre> <p>And now</p> <pre><code>(scope (var a) (var b 2) ...) </code></pre> <p>is a construct in the language.</p> <p>So really these two variants on (1) are more similar than they are different: it's just a matter of how you cut up the underlying constructs you want in the language: C conflated scope blocks and grouping, CL doesn't.</p> <p>(2) is different however. Here you are allowed to intermingle binding constructs and other things within a scope construct. C is now like this, and so is JavaScript. CL is <em>not</em> like this natively (obviously, being a Lisp, it could <em>become</em> like this with some macrology, although that macrology would be a lot hairier than what I wrote above).</p> <p>In such a language you really need a separate binding-creation construct, because it can't be part of the scoping construct. Languages like C already treat the binding-creation construct as separate, so for them it's just a matter of relaxing the rule which says bindings must all be created at the start of a scope construct.</p> <p>Languages like this have a significant question to answer though: what <em>is</em> the scope of a binding? Does something like</p> <pre><code>{ ... int x = 3; ... } </code></pre> <p>Really mean</p> <pre><code>{ ... { int x = 3; ... } } </code></pre> <p>or does it mean</p> <pre><code>{ int x; ... x = 3; ... } </code></pre> <p>The latter case is easier, but means that there's an awkward region where references to <code>x</code> are legal but its value may not be well-defined. C takes the former interpretation I think.</p> <p>This is mostly fine for languages like C where the grouping construct is the same as the scoping construct. But it's not fine for languages like JavaScript where the grouping construct is not the scoping construct and, worse, where there is no scoping construct other than functions (or used not to be). And in fact languages like that can't really fix the problem, since there's no useful scoping construct. Well, of course, they fix it by growing a scoping construct.</p> <p>Note that although CL is a (1) language there are Lisp-family languages which are (2) languages: in particular <a href="http://racket-lang.org/" rel="nofollow noreferrer">Racket</a> is. In Racket (but not, I think, in Scheme) you can say</p> <pre><code>(define (foo) (define bar 1) ;; is baz bound here? (display bar) (define baz 3) (list bar baz)) </code></pre> <p>And the answer is that yes, <code>baz</code> is bound there, but it's bound to an undefined object and you'll get an error (at run time, not compile time) if you try to use it. So this is a run-time error:</p> <p>(define (foo) (define bar 1) (display baz) (define baz 3) (list bar baz))</p> <p>while this</p> <pre><code>(define (foo) (define bar 1) (display baz) (let () (define baz 3) (list bar baz))) </code></pre> <p>is a compile time error. (I am actually slightly confused about which constructs in Racket create scopes.)</p>