Skip to content

Commit

Permalink
Unexport with, at_with, and ScopedValue from Base (#53004)
Browse files Browse the repository at this point in the history
fixes #52535

---------

Co-authored-by: Kristoffer Carlsson <kcarlsson89@gmail.com>
  • Loading branch information
vchuravy and KristofferC committed Mar 6, 2024
1 parent 90d84d4 commit 6335386
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 17 deletions.
5 changes: 0 additions & 5 deletions base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -653,11 +653,6 @@ export
sprint,
summary,

# ScopedValue
with,
@with,
ScopedValue,

# logging
@debug,
@info,
Expand Down
1 change: 1 addition & 0 deletions base/logging.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
module CoreLogging

import Base: isless, +, -, convert, show
import Base: ScopedValue, with, @with

export
AbstractLogger,
Expand Down
8 changes: 4 additions & 4 deletions base/mpfr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,9 @@ end
tie_breaker_is_to_even(::MPFRRoundingMode) = true

const ROUNDING_MODE = Ref{MPFRRoundingMode}(MPFRRoundNearest)
const CURRENT_ROUNDING_MODE = ScopedValue{MPFRRoundingMode}()
const CURRENT_ROUNDING_MODE = Base.ScopedValue{MPFRRoundingMode}()
const DEFAULT_PRECISION = Ref{Clong}(256)
const CURRENT_PRECISION = ScopedValue{Clong}()
const CURRENT_PRECISION = Base.ScopedValue{Clong}()
# Basic type and initialization definitions

# Warning: the constants are MPFR implementation details from
Expand Down Expand Up @@ -162,7 +162,7 @@ significand_limb_count(x::BigFloat) = div(sizeof(x._d), sizeof(Limb), RoundToZer
rounding_raw(::Type{BigFloat}) = something(Base.ScopedValues.get(CURRENT_ROUNDING_MODE), ROUNDING_MODE[])
setrounding_raw(::Type{BigFloat}, r::MPFRRoundingMode) = ROUNDING_MODE[]=r
function setrounding_raw(f::Function, ::Type{BigFloat}, r::MPFRRoundingMode)
@with(CURRENT_ROUNDING_MODE => r, f())
Base.@with(CURRENT_ROUNDING_MODE => r, f())
end


Expand Down Expand Up @@ -1109,7 +1109,7 @@ Note: `nextfloat()`, `prevfloat()` do not use the precision mentioned by
The `base` keyword requires at least Julia 1.8.
"""
function setprecision(f::Function, ::Type{BigFloat}, prec::Integer; base::Integer=2)
@with(CURRENT_PRECISION => _convert_precision_from_base(prec, base), f())
Base.@with(CURRENT_PRECISION => _convert_precision_from_base(prec, base), f())
end

setprecision(f::Function, prec::Integer; base::Integer=2) = setprecision(f, BigFloat, prec; base)
Expand Down
2 changes: 2 additions & 0 deletions base/scopedvalues.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ Dynamic scopes are propagated across tasks.
# Examples
```jldoctest
julia> using Base.ScopedValues;
julia> const sval = ScopedValue(1);
julia> sval[]
Expand Down
25 changes: 22 additions & 3 deletions doc/src/base/scopedvalues.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ concurrently.
Scoped values were introduced in Julia 1.11. In Julia 1.8+ a compatible
implementation is available from the package ScopedValues.jl.

In its simplest form you can create a [`ScopedValue`](@ref) with a
default value and then use [`with`](@ref Base.with) or [`@with`](@ref) to
In its simplest form you can create a [`Base.ScopedValue`](@ref) with a
default value and then use [`Base.with`](@ref with) or [`Base.@with`](@ref) to
enter a new dynamic scope.

The new scope will inherit all values from the parent scope
Expand Down Expand Up @@ -54,6 +54,8 @@ f() # 1
Now using a `ScopedValue` we can use **dynamic** scoping.

```julia
using Base.ScopedValues

x = ScopedValue(1)
f() = @show x[]
with(x=>5) do
Expand All @@ -70,6 +72,8 @@ and you can set the value of multiple `ScopedValue`s with one call to `with`.


```julia
using Base.ScopedValues

const scoped_val = ScopedValue(1)
const scoped_val2 = ScopedValue(0)

Expand All @@ -94,6 +98,8 @@ Since `with` requires a closure or a function and creates another call-frame,
it can sometimes be beneficial to use the macro form.

```julia
using Base.ScopedValues

const STATE = ScopedValue{State}()
with_state(f, state::State) = @with(STATE => state, f())
```
Expand All @@ -106,7 +112,9 @@ The parent task and the two child tasks observe independent values of the
same scoped value at the same time.

```julia
using Base.ScopedValues
import Base.Threads: @spawn

const scoped_val = ScopedValue(1)
@sync begin
with(scoped_val => 2)
Expand All @@ -128,7 +136,9 @@ values. You might want to explicitly [unshare mutable state](@ref unshare_mutabl
when entering a new dynamic scope.

```julia
using Base.ScopedValues
import Base.Threads: @spawn

const sval_dict = ScopedValue(Dict())

# Example of using a mutable value wrongly
Expand Down Expand Up @@ -161,6 +171,8 @@ are not well suited for this kind of propagation; our only alternative would hav
been to thread a value through the entire call-chain.

```julia
using Base.ScopedValues

const LEVEL = ScopedValue(:GUEST)

function serve(request, response)
Expand Down Expand Up @@ -189,7 +201,9 @@ end
### [Unshare mutable state](@id unshare_mutable_state)

```julia
using Base.ScopedValues
import Base.Threads: @spawn

const sval_dict = ScopedValue(Dict())

# If you want to add new values to the dict, instead of replacing
Expand All @@ -210,6 +224,7 @@ be in (lexical) scope. This means most often you likely want to use scoped value
as constant globals.

```julia
using Base.ScopedValues
const sval = ScopedValue(1)
```

Expand All @@ -218,7 +233,9 @@ Indeed one can think of scoped values as hidden function arguments.
This does not preclude their use as non-globals.

```julia
using Base.ScopedValues
import Base.Threads: @spawn

function main()
role = ScopedValue(:client)

Expand All @@ -241,6 +258,8 @@ If you find yourself creating many `ScopedValue`'s for one given module,
it may be better to use a dedicated struct to hold them.

```julia
using Base.ScopedValues

Base.@kwdef struct Configuration
color::Bool = false
verbose::Bool = false
Expand All @@ -260,7 +279,7 @@ end
Base.ScopedValues.ScopedValue
Base.ScopedValues.with
Base.ScopedValues.@with
Base.isassigned(::ScopedValue)
Base.isassigned(::Base.ScopedValues.ScopedValue)
Base.ScopedValues.get
```

Expand Down
10 changes: 5 additions & 5 deletions test/scopedvalues.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license
import Base: ScopedValues
using Base.ScopedValues

@testset "errors" begin
@test ScopedValue{Float64}(1)[] == 1.0
Expand Down Expand Up @@ -67,13 +67,13 @@ import Base.Threads: @spawn
end

@testset "show" begin
@test sprint(show, ScopedValue{Int}()) == "ScopedValue{$Int}(undefined)"
@test sprint(show, sval) == "ScopedValue{$Int}(1)"
@test sprint(show, ScopedValue{Int}()) == "Base.ScopedValues.ScopedValue{$Int}(undefined)"
@test sprint(show, sval) == "Base.ScopedValues.ScopedValue{$Int}(1)"
@test sprint(show, Core.current_scope()) == "nothing"
with(sval => 2.0) do
@test sprint(show, sval) == "ScopedValue{$Int}(2)"
@test sprint(show, sval) == "Base.ScopedValues.ScopedValue{$Int}(2)"
objid = sprint(show, Base.objectid(sval))
@test sprint(show, Core.current_scope()) == "Base.ScopedValues.Scope(ScopedValue{$Int}@$objid => 2)"
@test sprint(show, Core.current_scope()) == "Base.ScopedValues.Scope(Base.ScopedValues.ScopedValue{$Int}@$objid => 2)"
end
end

Expand Down

0 comments on commit 6335386

Please sign in to comment.