3 ms·
Here's a Javascript program: const x = 'lexically scoped'; const f = () => x; const g = () => { const x = 'dynamically scoped'; r
by kbp 8y ago
Here's a Javascript program:
const x = 'lexically scoped';
const f = () => x;
const g = () => {
const x = 'dynamically scoped';
return f();
};
console.log(g());
It prints which scoping Javascript uses. When `f` is executed, `x` isn't defined in that scope (the body of `f`), but `x` is used in that scope: does the language look in the scope that `f` itself was defined in (the top-level in this case, but you can have nested scopes), or does it look, at run-time, at the scope that `f` was called from (the body of `g`)? That's the difference. The local-to-`g` `x` that dynamic scoping would use when `f` is called is not a global; it's an entirely different variable from the other `x` (even in a dynamically scoped language, calling `g` won't change the outer `x`'s value).
Dynamic scoping can be useful: for example, in Common Lisp (which supports both lexical and dynamic variables), STANDARD-INPUT is a dynamically scoped variable, so you can temporarily redirect stdin like:
(with-open-file (*standard-input* (open "file.txt"))
(function-that-reads-from-stdin))
And not have to worry about setting STANDARD-INPUT back to its old value when you're done. Scala's implicits are also often used to produce the same effect as dynamic scope.
As an aside, you could argue that `this` is dynamically scoped in Javascript (outside of new lambdas).
- kbp 8y agoWasn't thinking when I wrote that Lisp example; obviously you don't use OPEN alongside WITH-OPEN-FILE, it just takes the filename.