# Naming of ScopedValues

**URL:** <https://discourse.julialang.org/t/naming-of-scopedvalues/110747>\
**Category:** Internals & Design\
**Created:** [February 25, 2024, 5:39pm UTC](https://discourse.julialang.org/t/naming-of-scopedvalues/110747 "2024-02-25T17:39:24Z")\
**Posts on this page:** 7\
**Page:** 2

<div class="post-metadata">

**Author:** ![uniment](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uniment/32/24532_2.png) [@uniment](https://discourse.julialang.org/u/uniment)\
**Post date:** [March 3, 2024, 8:06pm UTC](https://discourse.julialang.org/t/naming-of-scopedvalues/110747/21 "2024-03-03T20:06:55Z")

</div>

> [@Mason](#):
>
> your example also doesn’t work for the most important part of this: thread safety

Howso?

> [@](#):
>
> That’s a different feature. That’s a dynamic binding, whereas `ScopedValue` is a container.

It’d feel like a binding but be a container under the hood—like how boxed captures feel like a binding but are actually containers under the hood.

> [@Mason](#):
>
> Feel free to open a PR

Don’t be silly, I’m not about try compiler edits for an idea I spent five minutes spitballing before I have an idea of its feasibility…

> [@mnemnion](#):
>
> It’s a nice-to-have but I wouldn’t say it’s worth baking in any deeper.

In that case, `with` and `@with` should be left in the `ScopedValues` namespace. I had assumed there was a good reason they were being brought into the global namespace, but maybe not.

---

<div class="post-metadata">

**Author:** ![mnemnion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mnemnion/32/206596_2.png) [@mnemnion](https://discourse.julialang.org/u/mnemnion)\
**Post date:** [March 3, 2024, 8:48pm UTC](https://discourse.julialang.org/t/naming-of-scopedvalues/110747/22 "2024-03-03T20:48:12Z")

</div>

> [@uniment](#):
>
> In that case, `with` and `@with` should be left in the `ScopedValues` namespace. I had assumed there was a good reason they were being brought into the global namespace, but maybe not.

From where it’s placed in [the manual](https://docs.julialang.org/en/v1.12-dev/base/scopedvalues/), `ScopedValues` are going into the Base namespace, so that’s where `with` and `@with` are going also.

Whether it will be ok to add `with` was discussed as well. It did strike me as pretty basic word to reserve for the default namespace, [this frequency list](https://frequencylist.com) has “with” as the 33rd most common word in English. Source code isn’t English though, and a survey of package code showed that it wasn’t likely to be disruptive. I’m pretty sure I’ve never named a function or variable `with`, despite that initial reaction.

---

<div class="post-metadata">

**Author:** ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)\
**Post date:** [March 3, 2024, 9:28pm UTC](https://discourse.julialang.org/t/naming-of-scopedvalues/110747/23 "2024-03-03T21:28:55Z")

</div>

There is an open PR to un-export `with` and `@with`:

> <https://github.com/JuliaLang/julia/pull/53004>
>
> fixes #52535

---

<div class="post-metadata">

**Author:** ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)\
**Post date:** [March 6, 2024, 3:07am UTC](https://discourse.julialang.org/t/naming-of-scopedvalues/110747/24 "2024-03-06T03:07:37Z")

</div>

I just read through the entire Scoped Values PR, and I dispute this claim:

> [@ToucheSir](#):
>
> The original PR linked above ([Scoped values by vchuravy · Pull Request #50958 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/pull/50958)), has an extensive analysis and bikeshedding of the naming.

There is some discussion of the name, but it is nowhere close to “an extensive analysis and bikeshedding”. Most of the commentary on the name comes from the author of the PR. There is very little discussion of other alternatives. There was reportedly a discussion on Slack,

> [@ToucheSir](#):
>
> FWIW, there were even longer debates on Slack around naming.

but those discussions are inaccessible to those of us who don’t use Slack (and they’ve probably been lost to the slack-hole by now anyways).

It is odd that there is no discussion in the PR about using the word `Context` instead of `Scope` (except for a one sentence note about a triage call: “Triage: We remained split on `Contextual` vs `ScopedValue`.”). This is particularly odd considering that the precursor PR to the Scoped Values PR, [PR #35833](https://github.com/JuliaLang/julia/pull/35833) mentions the use of the term “context” in four other language:

- Python: `contextvars`
- .NET: `ExecutionContext`
- Kotlin: `CoroutineContext`
- Go: `context`

Julia uses lexical scope, so I think we are begging for confusion by referring to this feature as dynamical scope. True dynamical scope would look like this:

```julia
a = 1
f() = a

function g()
    a = 2
    f()
end

g() # returns 2

```

But that’s not what the Scoped Values PR provides, so I don’t think the feature should be referred to as dynamic scope. I think it’s better to describe this feature with the word “context”. So, this feature in action could look something like this:

```julia
a = ContextValue(1)
f() = a[]

newcontext(a => 2) do
    f() + 1
end

```

Of course the precise names of `ContextValue` and `newcontext` are debatable, but I think they should involve the word “context” rather than the word “scope”.

---

<div class="post-metadata">

**Author:** ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)\
**Post date:** [March 7, 2024, 6:18pm UTC](https://discourse.julialang.org/t/naming-of-scopedvalues/110747/25 "2024-03-07T18:18:39Z")

</div>

I opened a Github issue. It’s about more than just the name. I think it is misleading and confusing to describe the `ScopedValue` feature as a “dynamic scope” feature. I think it is more accurate and understandable to describe the feature as a “context” feature. This feature is described as a “context” feature in at least four other major programming languages.

> <https://github.com/JuliaLang/julia/issues/53644>
>
> \## Introduction
> 
> The new \`ScopedValue\` feature is really nice, but I think the… name and the description of the feature in terms of dynamic scope is likely to lead to confusion.
> 
> There was a \[claim on Discourse\](https://discourse.julialang.org/t/naming-of-scopedvalues/110747/2?u=cameronbieganek) that the PR had "an extensive analysis and bikeshedding of the naming". However, I have read through the entire PR and I disagree with that statement. There is some discussion of the name, but it is not a very complete discussion. In particular, it is surprising that there was no discussion regarding using the terminology "context" instead of "dynamic scope". In PR #35833, @tkf pointed out that the "context" terminology is used in at least four major programming languages:
> 
> \- Python: \[\`contextvars\`\](https://docs.python.org/3/library/contextvars.html)
> \- .NET: \[\`ExecutionContext\`\](https://learn.microsoft.com/en-us/dotnet/api/system.threading.executioncontext?view=netcore-3.1)
> \- Kotlin: \[\`CoroutineContext\`\](https://kotlinlang.org/docs/coroutine-context-and-dispatchers.html)
> \- Go: \[\`Context\`\](https://go.dev/blog/context)
> 
> Julia is a lexically scoped language, and the Scoped Values PR does not change that. Below are a couple examples that I think emphasize that what \`ScopedValue\` provides is \*not\* dynamic scoping.
> 
> (Disclaimer: I have only tested these using ScopedValues.jl. I need to install \`juliaup\` so I can get nightly.)
> 
> \## Example 1
> 
> \`\`\`julia
> julia\> using ScopedValues
> 
> julia\> f() = a\[\];
> 
> julia\> function g()
> a = ScopedValue(1)
> f()
> end;
> 
> julia\> g()
> ERROR: UndefVarError: \`a\` not defined
> Stacktrace:
> \[1\] f()
> @ Main ./REPL\[2\]:1
> \[2\] g()
> @ Main ./REPL\[3\]:3
> \[3\] top-level scope
> @ REPL\[4\]:1
> \`\`\`
> 
> \## Example 2
> 
> \`\`\`julia
> julia\> module A
> f() = a\[\]
> export f
> end
> Main.A
> 
> julia\> module B
> using ScopedValues
> using ..A
> a = ScopedValue(1)
> g() = f()
> export g
> end
> Main.B
> 
> julia\> using .B
> 
> julia\> g()
> ERROR: UndefVarError: \`a\` not defined
> Stacktrace:
> \[1\] f()
> @ Main.A ./REPL\[1\]:2
> \[2\] g()
> @ Main.B ./REPL\[2\]:5
> \[3\] top-level scope
> @ REPL\[4\]:1
> \`\`\`
> 
> \## Discussion
> 
> Both of these examples would work if \`ScopedValue\` provided true dynamic scoping. So essentially we are telling the user that Julia uses a subtle combination of lexical scoping and dynamic scoping. I think that's more confusing than it needs to be. We should describe this feature as a "context" feature rather than a "dynamic scoping" feature. This is about more than just the name, it is about our semantic understanding of what the feature provides.
> 
> So, after a renaming, this feature could look like this:
> 
> \`\`\`julia
> f() = a\[\]
> a = ContextValue(1)
> 
> newcontext(a =\> 2) do
> f()
> end # returns 2
> \`\`\`
> 
> Of course the precise naming is up for debate. Possible names for the context entering function:
> 
> \- \`with\`
> \- \`withcontext\`
> \- \`context\`
> \- \`incontext\`
> \- \`updatecontext\`
> \- \`newcontext\`
> 
> I think \`updatecontext\` and \`newcontext\` are probably the most accurate names to describe what they do.

---

<div class="post-metadata">

**Author:** ![mnemnion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mnemnion/32/206596_2.png) [@mnemnion](https://discourse.julialang.org/u/mnemnion)\
**Post date:** [March 7, 2024, 7:08pm UTC](https://discourse.julialang.org/t/naming-of-scopedvalues/110747/26 "2024-03-07T19:08:01Z")

</div>

> [@CameronBieganek](#):
>
> I think it is misleading and confusing to describe the `ScopedValue` feature as a “dynamic scope” feature. I think it is more accurate and understandable to describe the feature as a “context” feature. This feature is described as a “context” feature in at least four other major programming languages.

Just because I started this thread, I’ll chime in and say that I find `ContextValue` clear and unobjectionable. `ContextRef` is maybe worth considering, to signal that access is `refstyle[]`, but if I ran into `ContextValue` in the documentation right now I would consider it unremarkable.

---

<div class="post-metadata">

**Author:** ![bertschi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bertschi/32/33462_2.png) [@bertschi](https://discourse.julialang.org/u/bertschi)\
**Post date:** [March 7, 2024, 7:29pm UTC](https://discourse.julialang.org/t/naming-of-scopedvalues/110747/27 "2024-03-07T19:29:41Z")

</div>

> [@CameronBieganek](#):
>
> Julia uses lexical scope, so I think we are begging for confusion by referring to this feature as dynamical scope. True dynamical scope would look like this:
> 
> ```julia
> a = 1
> f() = a
> 
> function g()
> a = 2
> f()
> end
> 
> g() # returns 2
> 
> ```
> 
> But that’s not what the Scoped Values PR provides, so I don’t think the feature should be referred to as dynamic scope. I think it’s better to describe this feature with the word “context”. So, this feature in action could look something like this:
> 
> ```julia
> a = ContextValue(1)
> f() = a[]
> 
> newcontext(a => 2) do
> f() + 1
> end
> 
> ```
> 
> Of course the precise names of `ContextValue` and `newcontext` are debatable, but I think they should involve the word “context” rather than the word “scope”.

Your first example looks like setting a global variable to me. Guess, one should be more precise in distinguishing between binding and assigning, i.e., in Common Lisp, `let` establishes a new binding – for lexical as well as dynamic variables – whereas `setf` is used for assignment. In that interpretation `a = 2` simple sets the value (assuming it is already bound) whereas `newcontext` establishes a new binding. Unfortunately, the scoping rules of Julia with `=` sometimes establishing a new binding while assigning to an existing one in other cases can confuse here – especially in the context of contextual values.

I agree that `scope` is not the right term here and already in Common Lisp `dynamic scope` was considered a [misnomer](http://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node43.html) meaning _indefinite scope_ and _dynamic extent_ instead.

[Previous page](https://discourse.julialang.org/t/naming-of-scopedvalues/110747.md?page=1)
