Skip to content

Commit 8aa54ac

Browse files
JeffBezansonViralBShah
authored andcommitted
make coalesce handle only missing; add something (#27258)
* make `coalesce` handle only `missing`; add `something` to handle `nothing`/`Some` fixes #26927 * Move something docs with those for nothing and Some
1 parent f161ffa commit 8aa54ac

31 files changed

+223
-185
lines changed

base/client.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ color_normal = text_colors[:normal]
1515
function repl_color(key, default)
1616
env_str = get(ENV, key, "")
1717
c = tryparse(Int, env_str)
18-
c_conv = coalesce(c, Symbol(env_str))
18+
c_conv = something(c, Symbol(env_str))
1919
haskey(text_colors, c_conv) ? c_conv : default
2020
end
2121

base/compiler/ssair/show.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ function compute_ir_line_annotations(code::IRCode)
234234
first_mismatch = nothing
235235
end
236236
end
237-
last_depth = coalesce(first_mismatch, x+1)-1
237+
last_depth = something(first_mismatch, x+1)-1
238238
if min(depth, last_depth) > last_printed_depth
239239
printing_depth = min(depth, last_printed_depth + 1)
240240
last_printed_depth = printing_depth

base/deprecated.jl

Lines changed: 45 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -730,10 +730,10 @@ end
730730
@deprecate charwidth textwidth
731731

732732
@deprecate find(x::Number) findall(!iszero, x)
733-
@deprecate findnext(A, v, i::Integer) coalesce(findnext(isequal(v), A, i), 0)
734-
@deprecate findfirst(A, v) coalesce(findfirst(isequal(v), A), 0)
735-
@deprecate findprev(A, v, i::Integer) coalesce(findprev(isequal(v), A, i), 0)
736-
@deprecate findlast(A, v) coalesce(findlast(isequal(v), A), 0)
733+
@deprecate findnext(A, v, i::Integer) something(findnext(isequal(v), A, i), 0)
734+
@deprecate findfirst(A, v) something(findfirst(isequal(v), A), 0)
735+
@deprecate findprev(A, v, i::Integer) something(findprev(isequal(v), A, i), 0)
736+
@deprecate findlast(A, v) something(findlast(isequal(v), A), 0)
737737
# to fix ambiguities introduced by deprecations
738738
findnext(pred::Function, A, i::Integer) = invoke(findnext, Tuple{Function, Any, Any}, pred, A, i)
739739
findprev(pred::Function, A, i::Integer) = invoke(findprev, Tuple{Function, Any, Any}, pred, A, i)
@@ -1239,47 +1239,47 @@ end
12391239
@deprecate_binding HasOrder Ordered
12401240
@deprecate_binding ArithmeticOverflows ArithmeticWraps
12411241

1242-
@deprecate search(str::Union{String,SubString}, re::Regex, idx::Integer) coalesce(findnext(re, str, idx), 0:-1)
1243-
@deprecate search(s::AbstractString, r::Regex, idx::Integer) coalesce(findnext(r, s, idx), 0:-1)
1244-
@deprecate search(s::AbstractString, r::Regex) coalesce(findfirst(r, s), 0:-1)
1245-
@deprecate search(s::AbstractString, c::Char, i::Integer) coalesce(findnext(isequal(c), s, i), 0)
1246-
@deprecate search(s::AbstractString, c::Char) coalesce(findfirst(isequal(c), s), 0)
1247-
@deprecate search(a::ByteArray, b::Union{Int8,UInt8}, i::Integer) coalesce(findnext(isequal(b), a, i), 0)
1248-
@deprecate search(a::ByteArray, b::Union{Int8,UInt8}) coalesce(findfirst(isequal(b), a), 0)
1249-
@deprecate search(a::String, b::Union{Int8,UInt8}, i::Integer) coalesce(findnext(isequal(b), unsafe_wrap(Vector{UInt8}, a), i), 0)
1250-
@deprecate search(a::String, b::Union{Int8,UInt8}) coalesce(findfirst(isequal(b), unsafe_wrap(Vector{UInt8}, a)), 0)
1251-
@deprecate search(a::ByteArray, b::Char, i::Integer) coalesce(findnext(isequal(UInt8(b)), a, i), 0)
1252-
@deprecate search(a::ByteArray, b::Char) coalesce(findfirst(isequal(UInt8(b)), a), 0)
1253-
1254-
@deprecate search(s::AbstractString, c::Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}, i::Integer) coalesce(findnext(in(c), s, i), 0)
1255-
@deprecate search(s::AbstractString, c::Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}) coalesce(findfirst(in(c), s), 0)
1256-
@deprecate search(s::AbstractString, t::AbstractString, i::Integer) coalesce(findnext(t, s, i), 0:-1)
1257-
@deprecate search(s::AbstractString, t::AbstractString) coalesce(findfirst(t, s), 0:-1)
1258-
1259-
@deprecate rsearch(s::AbstractString, c::Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}, i::Integer) coalesce(findprev(in(c), s, i), 0)
1260-
@deprecate rsearch(s::AbstractString, c::Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}) coalesce(findlast(in(c), s), 0)
1261-
@deprecate rsearch(s::AbstractString, t::AbstractString, i::Integer) coalesce(findprev(t, s, i), 0:-1)
1262-
@deprecate rsearch(s::AbstractString, t::AbstractString) coalesce(findlast(t, s), 0:-1)
1263-
1264-
@deprecate rsearch(str::Union{String,SubString}, re::Regex, idx::Integer) coalesce(findprev(re, str, idx), 0:-1)
1265-
@deprecate rsearch(str::Union{String,SubString}, re::Regex) coalesce(findlast(re, str), 0:-1)
1266-
@deprecate rsearch(s::AbstractString, r::Regex, idx::Integer) coalesce(findprev(r, s, idx), 0:-1)
1267-
@deprecate rsearch(s::AbstractString, r::Regex) coalesce(findlast(r, s), 0:-1)
1268-
@deprecate rsearch(s::AbstractString, c::Char, i::Integer) coalesce(findprev(isequal(c), s, i), 0)
1269-
@deprecate rsearch(s::AbstractString, c::Char) coalesce(findlast(isequal(c), s), 0)
1270-
@deprecate rsearch(a::Union{String,ByteArray}, b::Union{Int8,UInt8}, i::Integer = lastindex(a)) coalesce(findprev(isequal(b), a, i), 0)
1271-
@deprecate rsearch(a::String, b::Union{Int8,UInt8}, i::Integer = lastindex(a)) coalesce(findprev(isequal(Char(b)), a, i), 0)
1272-
@deprecate rsearch(a::ByteArray, b::Char, i::Integer = lastindex(a)) coalesce(findprev(isequal(UInt8(b)), a, i), 0)
1273-
1274-
@deprecate searchindex(s::AbstractString, t::AbstractString) first(coalesce(findfirst(t, s), 0:-1))
1275-
@deprecate searchindex(s::AbstractString, t::AbstractString, i::Integer) first(coalesce(findnext(t, s, i), 0:-1))
1276-
@deprecate rsearchindex(s::AbstractString, t::AbstractString) first(coalesce(findlast(t, s), 0:-1))
1277-
@deprecate rsearchindex(s::AbstractString, t::AbstractString, i::Integer) first(coalesce(findprev(t, s, i), 0:-1))
1278-
1279-
@deprecate searchindex(s::AbstractString, c::Char) coalesce(findfirst(isequal(c), s), 0)
1280-
@deprecate searchindex(s::AbstractString, c::Char, i::Integer) coalesce(findnext(isequal(c), s, i), 0)
1281-
@deprecate rsearchindex(s::AbstractString, c::Char) coalesce(findlast(isequal(c), s), 0)
1282-
@deprecate rsearchindex(s::AbstractString, c::Char, i::Integer) coalesce(findprev(isequal(c), s, i), 0)
1242+
@deprecate search(str::Union{String,SubString}, re::Regex, idx::Integer) something(findnext(re, str, idx), 0:-1)
1243+
@deprecate search(s::AbstractString, r::Regex, idx::Integer) something(findnext(r, s, idx), 0:-1)
1244+
@deprecate search(s::AbstractString, r::Regex) something(findfirst(r, s), 0:-1)
1245+
@deprecate search(s::AbstractString, c::Char, i::Integer) something(findnext(isequal(c), s, i), 0)
1246+
@deprecate search(s::AbstractString, c::Char) something(findfirst(isequal(c), s), 0)
1247+
@deprecate search(a::ByteArray, b::Union{Int8,UInt8}, i::Integer) something(findnext(isequal(b), a, i), 0)
1248+
@deprecate search(a::ByteArray, b::Union{Int8,UInt8}) something(findfirst(isequal(b), a), 0)
1249+
@deprecate search(a::String, b::Union{Int8,UInt8}, i::Integer) something(findnext(isequal(b), unsafe_wrap(Vector{UInt8}, a), i), 0)
1250+
@deprecate search(a::String, b::Union{Int8,UInt8}) something(findfirst(isequal(b), unsafe_wrap(Vector{UInt8}, a)), 0)
1251+
@deprecate search(a::ByteArray, b::Char, i::Integer) something(findnext(isequal(UInt8(b)), a, i), 0)
1252+
@deprecate search(a::ByteArray, b::Char) something(findfirst(isequal(UInt8(b)), a), 0)
1253+
1254+
@deprecate search(s::AbstractString, c::Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}, i::Integer) something(findnext(in(c), s, i), 0)
1255+
@deprecate search(s::AbstractString, c::Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}) something(findfirst(in(c), s), 0)
1256+
@deprecate search(s::AbstractString, t::AbstractString, i::Integer) something(findnext(t, s, i), 0:-1)
1257+
@deprecate search(s::AbstractString, t::AbstractString) something(findfirst(t, s), 0:-1)
1258+
1259+
@deprecate rsearch(s::AbstractString, c::Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}, i::Integer) something(findprev(in(c), s, i), 0)
1260+
@deprecate rsearch(s::AbstractString, c::Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}) something(findlast(in(c), s), 0)
1261+
@deprecate rsearch(s::AbstractString, t::AbstractString, i::Integer) something(findprev(t, s, i), 0:-1)
1262+
@deprecate rsearch(s::AbstractString, t::AbstractString) something(findlast(t, s), 0:-1)
1263+
1264+
@deprecate rsearch(str::Union{String,SubString}, re::Regex, idx::Integer) something(findprev(re, str, idx), 0:-1)
1265+
@deprecate rsearch(str::Union{String,SubString}, re::Regex) something(findlast(re, str), 0:-1)
1266+
@deprecate rsearch(s::AbstractString, r::Regex, idx::Integer) something(findprev(r, s, idx), 0:-1)
1267+
@deprecate rsearch(s::AbstractString, r::Regex) something(findlast(r, s), 0:-1)
1268+
@deprecate rsearch(s::AbstractString, c::Char, i::Integer) something(findprev(isequal(c), s, i), 0)
1269+
@deprecate rsearch(s::AbstractString, c::Char) something(findlast(isequal(c), s), 0)
1270+
@deprecate rsearch(a::Union{String,ByteArray}, b::Union{Int8,UInt8}, i::Integer = lastindex(a)) something(findprev(isequal(b), a, i), 0)
1271+
@deprecate rsearch(a::String, b::Union{Int8,UInt8}, i::Integer = lastindex(a)) something(findprev(isequal(Char(b)), a, i), 0)
1272+
@deprecate rsearch(a::ByteArray, b::Char, i::Integer = lastindex(a)) something(findprev(isequal(UInt8(b)), a, i), 0)
1273+
1274+
@deprecate searchindex(s::AbstractString, t::AbstractString) first(something(findfirst(t, s), 0:-1))
1275+
@deprecate searchindex(s::AbstractString, t::AbstractString, i::Integer) first(something(findnext(t, s, i), 0:-1))
1276+
@deprecate rsearchindex(s::AbstractString, t::AbstractString) first(something(findlast(t, s), 0:-1))
1277+
@deprecate rsearchindex(s::AbstractString, t::AbstractString, i::Integer) first(something(findprev(t, s, i), 0:-1))
1278+
1279+
@deprecate searchindex(s::AbstractString, c::Char) something(findfirst(isequal(c), s), 0)
1280+
@deprecate searchindex(s::AbstractString, c::Char, i::Integer) something(findnext(isequal(c), s, i), 0)
1281+
@deprecate rsearchindex(s::AbstractString, c::Char) something(findlast(isequal(c), s), 0)
1282+
@deprecate rsearchindex(s::AbstractString, c::Char, i::Integer) something(findprev(isequal(c), s, i), 0)
12831283

12841284
@deprecate ismatch(r::Regex, s::AbstractString) occursin(r, s)
12851285

base/exports.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,7 @@ export
695695
ismissing,
696696
missing,
697697
skipmissing,
698+
something,
698699

699700
# time
700701
sleep,

base/file.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,7 @@ function _win_tempname(temppath::AbstractString, uunique::UInt32)
421421
tempp = cwstring(temppath)
422422
tname = Vector{UInt16}(undef, 32767)
423423
uunique = ccall(:GetTempFileNameW,stdcall,UInt32,(Ptr{UInt16},Ptr{UInt16},UInt32,Ptr{UInt16}), tempp,temp_prefix,uunique,tname)
424-
lentname = coalesce(findfirst(iszero,tname), 0)-1
424+
lentname = something(findfirst(iszero,tname), 0)-1
425425
if uunique == 0 || lentname <= 0
426426
error("GetTempFileName failed: $(Libc.FormatMessage())")
427427
end

base/missing.jl

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ showerror(io::IO, ex::MissingException) =
1919
print(io, "MissingException: ", ex.msg)
2020

2121

22-
2322
nonmissingtype(::Type{Union{T, Missing}}) where {T} = T
2423
nonmissingtype(::Type{Missing}) = Union{}
2524
nonmissingtype(::Type{T}) where {T} = T
@@ -189,3 +188,30 @@ function Base.iterate(itr::SkipMissing, state...)
189188
end
190189
item, state
191190
end
191+
192+
"""
193+
coalesce(x, y...)
194+
195+
Return the first value in the arguments which is not equal to [`missing`](@ref),
196+
if any. Otherwise return `missing`.
197+
198+
# Examples
199+
200+
```jldoctest
201+
julia> coalesce(missing, 1)
202+
1
203+
204+
julia> coalesce(1, missing)
205+
1
206+
207+
julia> coalesce(nothing, 1) # returns `nothing`
208+
209+
julia> coalesce(missing, missing)
210+
missing
211+
```
212+
"""
213+
function coalesce end
214+
215+
coalesce() = missing
216+
coalesce(x::Missing, y...) = coalesce(y...)
217+
coalesce(x::Any, y...) = x

base/parse.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -278,16 +278,16 @@ function tryparse_internal(::Type{Complex{T}}, s::Union{String,SubString{String}
278278
end
279279

280280
# find index of ± separating real/imaginary parts (if any)
281-
i₊ = coalesce(findnext(in(('+','-')), s, i), 0)
281+
i₊ = something(findnext(in(('+','-')), s, i), 0)
282282
if i₊ == i # leading ± sign
283-
i₊ = coalesce(findnext(in(('+','-')), s, i₊+1), 0)
283+
i₊ = something(findnext(in(('+','-')), s, i₊+1), 0)
284284
end
285285
if i₊ != 0 && s[i₊-1] in ('e','E') # exponent sign
286-
i₊ = coalesce(findnext(in(('+','-')), s, i₊+1), 0)
286+
i₊ = something(findnext(in(('+','-')), s, i₊+1), 0)
287287
end
288288

289289
# find trailing im/i/j
290-
iᵢ = coalesce(findprev(in(('m','i','j')), s, e), 0)
290+
iᵢ = something(findprev(in(('m','i','j')), s, e), 0)
291291
if iᵢ > 0 && s[iᵢ] == 'm' # im
292292
iᵢ -= 1
293293
if s[iᵢ] != 'i'

base/path.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -381,8 +381,8 @@ function relpath(path::String, startpath::String = ".")
381381
break
382382
end
383383
end
384-
pathpart = join(path_arr[i+1:coalesce(findlast(x -> !isempty(x), path_arr), 0)], path_separator)
385-
prefix_num = coalesce(findlast(x -> !isempty(x), start_arr), 0) - i - 1
384+
pathpart = join(path_arr[i+1:something(findlast(x -> !isempty(x), path_arr), 0)], path_separator)
385+
prefix_num = something(findlast(x -> !isempty(x), start_arr), 0) - i - 1
386386
if prefix_num >= 0
387387
prefix = pardir * path_separator
388388
relpath_ = isempty(pathpart) ?

base/shell.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ function shell_parse(str::AbstractString, interpolate::Bool=true;
4646
end
4747
function consume_upto(j)
4848
update_arg(s[i:prevind(s, j)])
49-
i = coalesce(peek(st), (lastindex(s)+1,'\0'))[1]
49+
i = something(peek(st), (lastindex(s)+1,'\0'))[1]
5050
end
5151
function append_arg()
5252
if isempty(arg); arg = Any["",]; end

base/some.jl

Lines changed: 24 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
A wrapper type used in `Union{Some{T}, Nothing}` to distinguish between the absence
77
of a value ([`nothing`](@ref)) and the presence of a `nothing` value (i.e. `Some(nothing)`).
88
9-
Use [`coalesce`](@ref) to access the value wrapped by a `Some` object.
9+
Use [`something`](@ref) to access the value wrapped by a `Some` object.
1010
"""
1111
struct Some{T}
1212
value::T
@@ -33,47 +33,39 @@ function show(io::IO, x::Some)
3333
end
3434

3535
"""
36-
coalesce(x, y...)
36+
notnothing(x)
3737
38-
Return the first value in the arguments which is not equal to
39-
either [`nothing`](@ref) or [`missing`](@ref), or the last argument.
40-
Unwrap arguments of type [`Some`](@ref).
38+
Throw an error if `x === nothing`, and return `x` if not.
39+
"""
40+
notnothing(x::Any) = x
41+
notnothing(::Nothing) = throw(ArgumentError("nothing passed to notnothing"))
42+
43+
"""
44+
something(x, y...)
45+
46+
Return the first value in the arguments which is not equal to [`nothing`](@ref),
47+
if any. Otherwise throw an error.
48+
Arguments of type [`Some`](@ref) are unwrapped.
4149
4250
# Examples
4351
4452
```jldoctest
45-
julia> coalesce(nothing, 1)
53+
julia> something(nothing, 1)
4654
1
4755
48-
julia> coalesce(missing, 1)
56+
julia> something(Some(1), nothing)
4957
1
5058
51-
julia> coalesce(1, nothing)
52-
1
59+
julia> something(missing, nothing)
60+
missing
5361
54-
julia> coalesce(nothing, nothing) # returns nothing, but not printed in the REPL
55-
56-
julia> coalesce(Some(1))
57-
1
58-
59-
julia> coalesce(nothing, Some(1))
60-
1
62+
julia> something(nothing, nothing)
63+
ERROR: ArgumentError: No value arguments present
6164
```
6265
"""
63-
function coalesce end
64-
65-
coalesce(x::Any) = x
66-
coalesce(x::Some) = x.value
67-
coalesce(x::Nothing) = nothing
68-
coalesce(x::Missing) = missing
69-
coalesce(x::Any, y...) = x
70-
coalesce(x::Some, y...) = x.value
71-
coalesce(x::Union{Nothing, Missing}, y...) = coalesce(y...)
72-
73-
"""
74-
notnothing(x)
66+
function something end
7567

76-
Throw an error if `x === nothing`, and return `x` if not.
77-
"""
78-
notnothing(x::Any) = x
79-
notnothing(::Nothing) = throw(ArgumentError("nothing passed to notnothing"))
68+
something() = throw(ArgumentError("No value arguments present"))
69+
something(x::Nothing, y...) = something(y...)
70+
something(x::Some, y...) = x.value
71+
something(x::Any, y...) = x

0 commit comments

Comments
 (0)