<p>In <a href="https://en.wikipedia.org/wiki/Scope_(computer_science)#Dynamic_scope" rel="noreferrer">dynamic scoping</a>, if a function accesses a variable in a higher scope, it does so relative to the location it's called rather than the location it's defined. For example:</p>
<pre><code>function a() {
    var b = 1;

    return () -&gt; b;
}

{
    var b = 2;
    var c = a();

    return c();
}
</code></pre>
<p>In a typical lexically scoped language, <code>c</code> would be a closure, returning <code>1</code>. However, in a dynamically scoped language, it instead returns <code>2</code>, the value of <code>b</code> in the scope where <code>c</code> is called.</p>
<p>What are the pros and cons of dynamic scoping?</p>

<functions><scoping>
What are the pros and cons of dynamic scoping?
CC BY-SA 4.0
2023-06-01T17:31:25.497Z
Also `this` in javascript is dynamically scoped.
Aman Grewal
CC BY-SA 4.0
2023-07-03T12:54:41.837Z
Tcl has `upvar`.
user23013
CC BY-SA 4.0
2023-07-08T01:06:32.810Z
@user23013 This better not be the setup to an updog joke :p
rydwolf
CC BY-SA 4.0
2023-05-17T07:17:00.523Z
Do you know any concrete languages that use dynamic scoping?
mousetail 'he-him'
CC BY-SA 4.0
2023-05-17T08:53:21.687Z
Sure thing @mousetail ! :D [Dynamic Variables](https://lisp-lang.org/learn/variables) in Common Lisp, "parameter objects" in [Scheme](https://srfi.schemers.org/srfi-39/srfi-39.html) and [Racket](https://docs.racket-lang.org/reference/parameters.html), also Clojure I vaguely remember had something similar too. :)
Alex Chichigin
<p>Dynamic scoping is fun and weird! That's about it for the pros. Well, also it's relatively easy to implement in an interpreter, because you don't have to do lexical resolution of names; names are resolved by walking the call stack instead of the source tree, and you already have a call stack. In practice this means your stack frames just each have a dictionary of names instead of a more complicated parent-pointer-tree of dictionaries of names. My first language, <a href="https://kaya3.github.io/fffff/" rel="noreferrer">fffff</a>, had dynamic scopes partly for this reason.</p>
<p>The cons are that dynamic scoping is weird and nobody is used to writing programs with it. There are almost no mainstream programming languages which use dynamic scoping; even <a href="https://en.wikipedia.org/wiki/Scope_(computer_science)#Dynamic_scope" rel="noreferrer">Wikipedia</a> only lists Logo, Emacs Lisp, LaTeX and some shell languages, and none of these are general-purpose programming languages.</p>
<p>Dynamic scoping makes it pretty difficult to reason about programs, particularly if you have higher-order functions. Consider the following example:</p>
<pre class="lang-py prettyprint-override"><code>def call_me_maybe(f):
    p = random()
    if p &lt; 0.5:
        f()

x = 23
call_me_maybe(() =&gt; print(x));
</code></pre>
<p>This program has a 50% probability of printing the number 23. But if we refactor the <code>call_me_maybe</code> function to change the name of the local variable <code>p</code> to <code>x</code>, then suddenly the program instead has a 50% probability of printing a floating-point number between 0 and 0.5. This is because the local variable in the <code>call_me_maybe</code> stack frame shadows the one from the root stack frame.</p>
<p>So the behaviour of a piece of code like this can't be determined without knowing even the names of the local variables of all the functions that might be called! This is a pretty severe violation of <a href="https://en.wikipedia.org/wiki/Encapsulation_(computer_programming)" rel="noreferrer">encapsulation</a>, the principle that one piece of code shouldn't depend on the irrelevant internal details of another piece of code.</p>
<hr />
<p>So this is pretty much why sensible languages don't use dynamic scoping. That said, there is some benefit in having something <em>resembling</em> dynamic scope for individual variables on an opt-in basis, in a language which is otherwise lexically scoped. <a href="https://docs.scala-lang.org/tour/implicit-parameters.html" rel="noreferrer">Scala</a>, for example, has this for function parameters, as does my language <a href="https://kaya3.github.io/papyri/" rel="noreferrer">Papyri</a>:</p>
<pre><code>@fn greet($greeting: implicit str) $name: str -&gt; {
    $greeting, $name!
}

@fn say_hi $name: str -&gt; {
    @implicit(greeting=`Hi`)
    @greet $name
}

@say_hi `Andrew`
# result: Hi, Andrew!
</code></pre>
<p>An implicit parameter will be passed automatically when the function is called, with the argument value taken from a (lexically-scoped) variable of the same name, as long as that variable is also labelled as implicit. So this is still lexical scoping because the name <code>$greeting</code> in the first function refers to a different variable than the same name in the second function, but it behaves similar to dynamic scoping because the value is passed automatically along the call stack.</p>

CC BY-SA 4.0
2023-05-17T02:45:56.050Z
2023-05-19T05:50:09.193Z
2023-05-19T05:50:09.193Z
kaya3
<p>The use of dynamic scoping makes code less self-contained; with lexical scoping all uses of a variable are logically kept together whereas with dynamic scoping it's hard to tell what uses what, making it more difficult to refactor code (such as by renaming a variable).</p>

CC BY-SA 4.0
2023-05-17T02:28:35.397Z
2023-05-17T02:28:35.397Z
pppery
<h1>Dependency Injection</h1>
<p>Things like logging become incredibly easy with dynamic scoping, since if a <code>log</code> function is in scope for your <code>main</code> function, anything your <code>main</code> function calls will automatically have access to <code>log</code>. This has some pros and cons itself.</p>
<p><strong>Pros:</strong></p>
<ul>
<li>No need to pass tons of arguments to functions, or create unnecessary closures, in order to do dependency injection</li>
<li>Saves typing</li>
</ul>
<p><strong>Cons:</strong></p>
<ul>
<li>There's no easy way to know what dependencies a function expects it will have
<ul>
<li>Error messages resulting from this could be difficult to read, since it would be unclear whether it's a bug in the library, or a failure on your part to define a variable in an enclosing scope</li>
</ul>
</li>
</ul>

CC BY-SA 4.0
2023-05-17T02:20:35.143Z
2023-05-17T02:20:35.143Z
rydwolf
<p>Universal dynamic scope has a lot of well-travelled drawbacks, but in limited circumstances, especially when it's opt-in, it can be a powerful tool for flexibly extending the language for specific purposes.</p>
<p>Dynamic scoping can enable the easy creation of embedded domain-specific languages when the language has suitable syntax and semantics otherwise: define names, constructs, and functions of the language within a scope, and allow a piece of code provided from outside as a function pointer or lambda to run in the context of that scope. In fact, it can enable exactly the kind of thing this site is about!</p>
<p>For example, while not generally dynamically scoped, Ruby allows evaluating a block of code <em>within the scope of a given object</em> using the <code>instance_eval</code> method. This is used for very widely-used DSLs, like the configuration in every Rails project and RubyGem, Chef, and Rake. When evaluated, the block of code will see the methods of that object, and any unqualified names will be looked up there first:</p>
<pre class="lang-ruby prettyprint-override"><code>class DSL
    def hello
        puts &quot;Hello&quot;
    end
    def world
        puts &quot;world&quot;
    end
end
DSL.new.instance_eval { hello; world }
</code></pre>
<p>This is an opt-in dynamic scoping behaviour, and it's extremely widely used. Ruby provides dynamic overriding of most object features, so these DSLs can be quite powerful and somewhat different in semantics from the host language.</p>
<p>I wouldn't want to use a language that was all dynamic scoping, all the time, but the ability to run <em>this bit of code</em> in <em>this outer scope</em> is really useful, and points in the design space in between Ruby and full dynamic scoping seem like they would be useful in some circumstances too.</p>

CC BY-SA 4.0
2023-05-19T00:07:01.850Z
2023-05-19T00:07:01.850Z
Michael Homer
<p>Let's say we're mapping over an array in an interpreted language, calling a function on each element. With lexical scoping, we'd have to define the function inside the loop, incurring an overhead each time around the loop. A dynamic language could define the function outside the loop and still have it access parameters set up inside the loop.</p>

CC BY-SA 4.0
2023-05-17T04:37:02.537Z
2023-05-17T04:37:02.537Z
Adám
<p>Several good answers already, but I would put it even more strongly. Dynamic scoping makes it impossible to tell what a program means at compile time.</p>
<p>I don't want to discourage anyone from dynamic scoping if that's what your dynamic language needs, but it makes things <em>much</em> harder for compilation, including JIT compilation.</p>

CC BY-SA 4.0
2023-05-17T02:54:58.917Z
2023-05-17T02:54:58.917Z
Pseudonym
<h1>Memory Usage</h1>
<p>With dynamic scoping, variables would still be available out of <em>'scope,'</em> so they would be kept in memory for longer, potentially leading to memory issues depending on what is stored in them. With lexical scoping, variables are more effectively deleted once their are no longer needed.</p>

CC BY-SA 4.0
2023-05-19T02:50:12.503Z
2023-05-19T02:50:12.503Z
CPlus
# What are the pros and cons of dynamic scoping?
Posted by: username_0 on 2023-05-17
In dynamic scoping, if a function accesses a variable in a higher scope, it does so relative to the location it's called rather than the location it's defined. For example:
function a() {
    var b = 1;

    return () -> b;
}

{
    var b = 2;
    var c = a();

    return c();
}

In a typical lexically scoped language, c would be a closure, returning 1. However, in a dynamically scoped language, it instead returns 2, the value of b in the scope where c is called.
What are the pros and cons of dynamic scoping?
**Tags:** functions scoping
> **Comments:**
> **username_3**: Do you know any concrete languages that use dynamic scoping?  
> **username_4**: Sure thing @mousetail ! :D [Dynamic Variables](https://lisp-lang.org/learn/variables) in Common Lisp, "parameter objects" in [Scheme](https://srfi.schemers.org/srfi-39/srfi-39.html) and [Racket](https://docs.racket-lang.org/reference/parameters.html), also Clojure I vaguely remember had something similar too. :)  
> **username_1**: Also `this` in javascript is dynamically scoped.  
> **username_2**: Tcl has `upvar`.  
> **username_0**: @user23013 This better not be the setup to an updog joke :p  
---
## 7 answers
### Answer by username_5 on 2023-05-17. Score: 12
Dynamic scoping is fun and weird! That's about it for the pros. Well, also it's relatively easy to implement in an interpreter, because you don't have to do lexical resolution of names; names are resolved by walking the call stack instead of the source tree, and you already have a call stack. In practice this means your stack frames just each have a dictionary of names instead of a more complicated parent-pointer-tree of dictionaries of names. My first language, fffff, had dynamic scopes partly for this reason.
The cons are that dynamic scoping is weird and nobody is used to writing programs with it. There are almost no mainstream programming languages which use dynamic scoping; even Wikipedia only lists Logo, Emacs Lisp, LaTeX and some shell languages, and none of these are general-purpose programming languages.
Dynamic scoping makes it pretty difficult to reason about programs, particularly if you have higher-order functions. Consider the following example:
def call_me_maybe(f):
    p = random()
    if p < 0.5:
        f()

x = 23
call_me_maybe(() => print(x));

This program has a 50% probability of printing the number 23. But if we refactor the call_me_maybe function to change the name of the local variable p to x, then suddenly the program instead has a 50% probability of printing a floating-point number between 0 and 0.5. This is because the local variable in the call_me_maybe stack frame shadows the one from the root stack frame.
So the behaviour of a piece of code like this can't be determined without knowing even the names of the local variables of all the functions that might be called! This is a pretty severe violation of encapsulation, the principle that one piece of code shouldn't depend on the irrelevant internal details of another piece of code.

So this is pretty much why sensible languages don't use dynamic scoping. That said, there is some benefit in having something resembling dynamic scope for individual variables on an opt-in basis, in a language which is otherwise lexically scoped. Scala, for example, has this for function parameters, as does my language Papyri:
@fn greet($greeting: implicit str) $name: str -> {
    $greeting, $name!
}

@fn say_hi $name: str -> {
    @implicit(greeting=`Hi`)
    @greet $name
}

@say_hi `Andrew`
# result: Hi, Andrew!

An implicit parameter will be passed automatically when the function is called, with the argument value taken from a (lexically-scoped) variable of the same name, as long as that variable is also labelled as implicit. So this is still lexical scoping because the name $greeting in the first function refers to a different variable than the same name in the second function, but it behaves similar to dynamic scoping because the value is passed automatically along the call stack.
---
### Answer by username_0 on 2023-05-17. Score: 8
# Dependency Injection

Things like logging become incredibly easy with dynamic scoping, since if a `log` function is in scope for your `main` function, anything your `main` function calls will automatically have access to `log`. This has some pros and cons itself.

**Pros:**

* No need to pass tons of arguments to functions, or create unnecessary closures, in order to do dependency injection
* Saves typing

**Cons:**

* There's no easy way to know what dependencies a function expects it will have
  + Error messages resulting from this could be difficult to read, since it would be unclear whether it's a bug in the library, or a failure on your part to define a variable in an enclosing scope
---
### Answer by username_6 on 2023-05-17. Score: 5
The use of dynamic scoping makes code less self-contained; with lexical scoping all uses of a variable are logically kept together whereas with dynamic scoping it's hard to tell what uses what, making it more difficult to refactor code (such as by renaming a variable).
---
### Answer by username_7 on 2023-05-19. Score: 3
Universal dynamic scope has a lot of well-travelled drawbacks, but in limited circumstances, especially when it's opt-in, it can be a powerful tool for flexibly extending the language for specific purposes.
Dynamic scoping can enable the easy creation of embedded domain-specific languages when the language has suitable syntax and semantics otherwise: define names, constructs, and functions of the language within a scope, and allow a piece of code provided from outside as a function pointer or lambda to run in the context of that scope. In fact, it can enable exactly the kind of thing this site is about!
For example, while not generally dynamically scoped, Ruby allows evaluating a block of code within the scope of a given object using the instance_eval method. This is used for very widely-used DSLs, like the configuration in every Rails project and RubyGem, Chef, and Rake. When evaluated, the block of code will see the methods of that object, and any unqualified names will be looked up there first:
class DSL
    def hello
        puts "Hello"
    end
    def world
        puts "world"
    end
end
DSL.new.instance_eval { hello; world }

This is an opt-in dynamic scoping behaviour, and it's extremely widely used. Ruby provides dynamic overriding of most object features, so these DSLs can be quite powerful and somewhat different in semantics from the host language.
I wouldn't want to use a language that was all dynamic scoping, all the time, but the ability to run this bit of code in this outer scope is really useful, and points in the design space in between Ruby and full dynamic scoping seem like they would be useful in some circumstances too.
---
### Answer by username_8 on 2023-05-17. Score: 2
Let's say we're mapping over an array in an interpreted language, calling a function on each element. With lexical scoping, we'd have to define the function inside the loop, incurring an overhead each time around the loop. A dynamic language could define the function outside the loop and still have it access parameters set up inside the loop.
---
### Answer by username_9 on 2023-05-17. Score: 1
Several good answers already, but I would put it even more strongly. Dynamic scoping makes it impossible to tell what a program means at compile time.

I don't want to discourage anyone from dynamic scoping if that's what your dynamic language needs, but it makes things *much* harder for compilation, including JIT compilation.
---
### Answer by username_10 on 2023-05-19. Score: 1
# Memory Usage

With dynamic scoping, variables would still be available out of *'scope,'* so they would be kept in memory for longer, potentially leading to memory issues depending on what is stored in them. With lexical scoping, variables are more effectively deleted once their are no longer needed.
---
