# What is the use of ScopedValues beyond web authorization?

**URL:** <https://discourse.julialang.org/t/what-is-the-use-of-scopedvalues-beyond-web-authorization/116162>\
**Category:** General Usage\
**Tags:** scopedvalues\
**Created:** [June 24, 2024, 9:05pm UTC](https://discourse.julialang.org/t/what-is-the-use-of-scopedvalues-beyond-web-authorization/116162 "2024-06-24T21:05:22Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![sadish-d](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sadish-d/32/48058_2.png) [@sadish-d](https://discourse.julialang.org/u/sadish-d)\
**Post date:** [June 24, 2024, 9:05pm UTC](https://discourse.julialang.org/t/what-is-the-use-of-scopedvalues-beyond-web-authorization/116162/1 "2024-06-24T21:05:23Z")

</div>

ScopedValues are coming to Julia v1.11 (I think?). After reading a few examples, I think of them as resettable `Ref`s. Apparently they behave like constants even though you can temporarily change their values. They are useful in passing data from one function to another without passing it “through” the functions (example below). And it seems like this is a neat way to do authorizations in web-based systems.

What are some of its uses beyond web-based systems?

```julia
using ScopedValues

const authorized = ScopedValue(false)

"""
    the friend communicates to (the guard via) the messanger
    the friend does not tell the messanger whether it is authorized
"""
function friend()
    with(authorized => true) do
        messanger()
    end

    return nothing
end
"""
    the foe communicates to (the guard via) the messanger
    the foe does not tell the messanger whether it is authorized
"""
function foe()
    with(authorized => false) do
        messanger()
    end

    return nothing
end
"""
    the messanger talks to the guard on behalf of the seeker (friend or foe)
    the messanger does not know whether the friend or foe invokes it
"""
function messanger()
    guard()

    return nothing
end
"""
    the guard lets the messanger know whether the seeker may pass
"""
function guard()
    granted =
        if authorized[]
            println("passage granted")
            true
        else
            println("passage denied")
            false
        end
    
    return granted
end

# friend()
# foe()

```

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [June 24, 2024, 10:04pm UTC](https://discourse.julialang.org/t/what-is-the-use-of-scopedvalues-beyond-web-authorization/116162/2 "2024-06-24T22:04:53Z")

</div>

I’m using them in Supposition.jl to pass a context object that’s not exposed to the user-facing API into the code handling that API call. It’s pretty useful for that, because it lets me design the user API without having to leak internals 🙂

---

<div class="post-metadata">

**Author:** ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)\
**Post date:** [June 24, 2024, 10:40pm UTC](https://discourse.julialang.org/t/what-is-the-use-of-scopedvalues-beyond-web-authorization/116162/3 "2024-06-24T22:40:34Z")

</div>

I’m using them in [AllocArrays.jl](https://github.com/ericphanson/AllocArrays.jl) to hold a bump allocator to allocate memory from. ScopeValues are very useful for this, since I have no way to pass extra arguments into `similar(::Type{<:AllocArray{T}},...)` calls made from library code I don’t control, but in my method for `similar` I can access a scoped value that holds the allocator to use to allocate the memory. This is nicer than a global since one can use different allocators in parallel (on different tasks) for different things, potentially from multiple downstream libraries that don’t know about each other but both use AllocArrays.jl.

Though this was a bit of a solution in search of a problem, since I had the idea to write AllocArrays after thinking about possible uses for ScopedValues 🙂.

---

<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:** [June 24, 2024, 10:40pm UTC](https://discourse.julialang.org/t/what-is-the-use-of-scopedvalues-beyond-web-authorization/116162/4 "2024-06-24T22:40:41Z")

</div>

Scoped values (aka dynamic variables) are useful any time you want to setup a context with dynamic extent. They are not (yet) widely used in Julia, but in [Conditions.jl](https://github.com/bertschi/Conditions.jl) I used them to setup error handler (which are dynamically bound) and also some idioms such as `redirect_stdout` have similar effect (even though they predate scoped values and just temporarily overwrite the global binding instead).  
For further inspiration you could look at Lisp where dynamic variables are more wide-spread, e.g., in [Common Lisp](https://gigamonkeys.com/book/variables) or especially [Emacs Lisp](https://www.gnu.org/software/emacs/emacs-paper.html#SEC17).

---

<div class="post-metadata">

**Author:** ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)\
**Post date:** [June 24, 2024, 10:44pm UTC](https://discourse.julialang.org/t/what-is-the-use-of-scopedvalues-beyond-web-authorization/116162/5 "2024-06-24T22:44:58Z")

</div>

> [@bertschi](#):
>
> They are not (yet) widely used in Julia

Probably one should mention that the logging system relies on them heavily, and the logging system (`@info`, `@warn`, etc) is used pretty often! Prior to scoped values, the logging state got a special field in the task object to enable dynamic scope for loggers specifically; [the scoped values PR](https://github.com/JuliaLang/julia/pull/50958) changed it into a generic system that anyone can use, and reimplemented logging as just a regular scoped value instead of a special thing that couldn’t be done outside of Base.

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [June 24, 2024, 11:58pm UTC](https://discourse.julialang.org/t/what-is-the-use-of-scopedvalues-beyond-web-authorization/116162/6 "2024-06-24T23:58:24Z")

</div>

So is ScopedValues basically program-global variables that one can access from anywhere? (with a bonus of being thread-safe)

---

<div class="post-metadata">

**Author:** ![vchuravy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vchuravy/32/8_2.png) [@vchuravy](https://discourse.julialang.org/u/vchuravy)\
**Post date:** [June 25, 2024, 1:47am UTC](https://discourse.julialang.org/t/what-is-the-use-of-scopedvalues-beyond-web-authorization/116162/7 "2024-06-25T01:47:28Z")

</div>

I had also prototype variants of Test/TimerOutputs that use a ScopedValue to propagate the current context to the next layer.

---

<div class="post-metadata">

**Author:** ![tecosaur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tecosaur/32/23206_2.png) [@tecosaur](https://discourse.julialang.org/u/tecosaur)\
**Post date:** [June 25, 2024, 3:50am UTC](https://discourse.julialang.org/t/what-is-the-use-of-scopedvalues-beyond-web-authorization/116162/8 "2024-06-25T03:50:42Z")

</div>

StyledStrings.jl uses ScopedValues to allow for the use of a seperate set of styles within a certain scope (`withfaces`). This could be done by editing then reversing the edits to a global variable, but that’s not thread-safe.

> **[Example Usage · Styled Strings](https://julialang.github.io/StyledStrings.jl/dev/examples/#Application-customisation-of-faces)**
>
> Documentation for Styled Strings.

---

<div class="post-metadata">

**Author:** ![sadish-d](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sadish-d/32/48058_2.png) [@sadish-d](https://discourse.julialang.org/u/sadish-d)\
**Post date:** [June 26, 2024, 3:25am UTC](https://discourse.julialang.org/t/what-is-the-use-of-scopedvalues-beyond-web-authorization/116162/9 "2024-06-26T03:25:53Z")

</div>

Looks like there’s a whole JuliaCon talk (by @vchuravy ?) set aside for this topic: [ScopedValues -- What are they good for :: Juliacon 2024 :: pretalx](https://pretalx.com/juliacon2024/talk/FR8MVT/)

---

<div class="post-metadata">

**Author:** ![vchuravy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vchuravy/32/8_2.png) [@vchuravy](https://discourse.julialang.org/u/vchuravy)\
**Post date:** [June 26, 2024, 5:22pm UTC](https://discourse.julialang.org/t/what-is-the-use-of-scopedvalues-beyond-web-authorization/116162/10 "2024-06-26T17:22:59Z")

</div>

Indeed… So if you have an interesting/cool use-case please let me know.

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [June 26, 2024, 6:25pm UTC](https://discourse.julialang.org/t/what-is-the-use-of-scopedvalues-beyond-web-authorization/116162/11 "2024-06-26T18:25:07Z")

</div>

I’ve been thinking Makie could use this for themes, or for backend activation maybe, at least if we ever want to be able to render from multiple threads. But that’s in general hard to do with the global state in OpenGL I think.

---

<div class="post-metadata">

**Author:** ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)\
**Post date:** [June 26, 2024, 7:08pm UTC](https://discourse.julialang.org/t/what-is-the-use-of-scopedvalues-beyond-web-authorization/116162/12 "2024-06-26T19:08:04Z")

</div>

I think themes are a good use-case. I think anytime there’s the pattern

```julia
library_function() do
   # user does stuff
end

```

where `library_function` sets up some global state, then calls the user function to do stuff, then resets the state, would benefit from that global state being ScopedValues instead of raw global state. I think Mocking.jl does stuff like this too.

---

<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:** [June 26, 2024, 8:05pm UTC](https://discourse.julialang.org/t/what-is-the-use-of-scopedvalues-beyond-web-authorization/116162/13 "2024-06-26T20:05:34Z")

</div>

Thanks, makes a lot of sense.  
Just saw that `@testset` – which also introduces a dynamic scope for tests – uses `task_local_storage` … could probably also be moved to scoped values?

---

<div class="post-metadata">

**Author:** ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)\
**Post date:** [June 26, 2024, 9:00pm UTC](https://discourse.julialang.org/t/what-is-the-use-of-scopedvalues-beyond-web-authorization/116162/14 "2024-06-26T21:00:50Z")

</div>

Yeah, Valentin mentioned above he experimented with that; I think his PR was [Implement Test/Testset using ScopedValue by vchuravy · Pull Request #51012 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/pull/51012)

---

<div class="post-metadata">

**Author:** ![1113](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/1113/32/205603_2.png) [@1113](https://discourse.julialang.org/u/1113)\
**Post date:** [December 16, 2024, 2:40am UTC](https://discourse.julialang.org/t/what-is-the-use-of-scopedvalues-beyond-web-authorization/116162/15 "2024-12-16T02:40:42Z")

</div>

Injecting into `Base.show`.  
It’s almost impossible to change the show behavior of a inner object. You could pass value to `show` method of your custom object, but you cannot decide how an outer show function call the `show` method of your custom object. If it simply calls one argument `show` method, there’s nothing you can change.  
For exmaple, how can you change the show behavior of your custom object as a tree node in tree display mode offered by `AbstractTrees.jl`?
