Skip to content

Commit

Permalink
make coalesce handle only missing; add something to handle `not…
Browse files Browse the repository at this point in the history
…hing`/`Some`

fixes #26927
  • Loading branch information
JeffBezanson committed May 25, 2018
1 parent 779cf84 commit 6caeb71
Show file tree
Hide file tree
Showing 32 changed files with 225 additions and 187 deletions.
2 changes: 1 addition & 1 deletion base/client.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ color_normal = text_colors[:normal]
function repl_color(key, default)
env_str = get(ENV, key, "")
c = tryparse(Int, env_str)
c_conv = coalesce(c, Symbol(env_str))
c_conv = something(c, Symbol(env_str))
haskey(text_colors, c_conv) ? c_conv : default
end

Expand Down
2 changes: 1 addition & 1 deletion base/compiler/ssair/show.jl
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ function compute_ir_line_annotations(code::IRCode)
first_mismatch = nothing
end
end
last_depth = coalesce(first_mismatch, x+1)-1
last_depth = something(first_mismatch, x+1)-1
if min(depth, last_depth) > last_printed_depth
printing_depth = min(depth, last_printed_depth + 1)
last_printed_depth = printing_depth
Expand Down
90 changes: 45 additions & 45 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -736,10 +736,10 @@ end
@deprecate charwidth textwidth

@deprecate find(x::Number) findall(!iszero, x)
@deprecate findnext(A, v, i::Integer) coalesce(findnext(isequal(v), A, i), 0)
@deprecate findfirst(A, v) coalesce(findfirst(isequal(v), A), 0)
@deprecate findprev(A, v, i::Integer) coalesce(findprev(isequal(v), A, i), 0)
@deprecate findlast(A, v) coalesce(findlast(isequal(v), A), 0)
@deprecate findnext(A, v, i::Integer) something(findnext(isequal(v), A, i), 0)
@deprecate findfirst(A, v) something(findfirst(isequal(v), A), 0)
@deprecate findprev(A, v, i::Integer) something(findprev(isequal(v), A, i), 0)
@deprecate findlast(A, v) something(findlast(isequal(v), A), 0)
# to fix ambiguities introduced by deprecations
findnext(pred::Function, A, i::Integer) = invoke(findnext, Tuple{Function, Any, Any}, pred, A, i)
findprev(pred::Function, A, i::Integer) = invoke(findprev, Tuple{Function, Any, Any}, pred, A, i)
Expand Down Expand Up @@ -1223,47 +1223,47 @@ end
@deprecate_binding HasOrder Ordered
@deprecate_binding ArithmeticOverflows ArithmeticWraps

@deprecate search(str::Union{String,SubString}, re::Regex, idx::Integer) coalesce(findnext(re, str, idx), 0:-1)
@deprecate search(s::AbstractString, r::Regex, idx::Integer) coalesce(findnext(r, s, idx), 0:-1)
@deprecate search(s::AbstractString, r::Regex) coalesce(findfirst(r, s), 0:-1)
@deprecate search(s::AbstractString, c::Char, i::Integer) coalesce(findnext(isequal(c), s, i), 0)
@deprecate search(s::AbstractString, c::Char) coalesce(findfirst(isequal(c), s), 0)
@deprecate search(a::ByteArray, b::Union{Int8,UInt8}, i::Integer) coalesce(findnext(isequal(b), a, i), 0)
@deprecate search(a::ByteArray, b::Union{Int8,UInt8}) coalesce(findfirst(isequal(b), a), 0)
@deprecate search(a::String, b::Union{Int8,UInt8}, i::Integer) coalesce(findnext(isequal(b), unsafe_wrap(Vector{UInt8}, a), i), 0)
@deprecate search(a::String, b::Union{Int8,UInt8}) coalesce(findfirst(isequal(b), unsafe_wrap(Vector{UInt8}, a)), 0)
@deprecate search(a::ByteArray, b::Char, i::Integer) coalesce(findnext(isequal(UInt8(b)), a, i), 0)
@deprecate search(a::ByteArray, b::Char) coalesce(findfirst(isequal(UInt8(b)), a), 0)

@deprecate search(s::AbstractString, c::Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}, i::Integer) coalesce(findnext(in(c), s, i), 0)
@deprecate search(s::AbstractString, c::Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}) coalesce(findfirst(in(c), s), 0)
@deprecate search(s::AbstractString, t::AbstractString, i::Integer) coalesce(findnext(t, s, i), 0:-1)
@deprecate search(s::AbstractString, t::AbstractString) coalesce(findfirst(t, s), 0:-1)

@deprecate rsearch(s::AbstractString, c::Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}, i::Integer) coalesce(findprev(in(c), s, i), 0)
@deprecate rsearch(s::AbstractString, c::Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}) coalesce(findlast(in(c), s), 0)
@deprecate rsearch(s::AbstractString, t::AbstractString, i::Integer) coalesce(findprev(t, s, i), 0:-1)
@deprecate rsearch(s::AbstractString, t::AbstractString) coalesce(findlast(t, s), 0:-1)

@deprecate rsearch(str::Union{String,SubString}, re::Regex, idx::Integer) coalesce(findprev(re, str, idx), 0:-1)
@deprecate rsearch(str::Union{String,SubString}, re::Regex) coalesce(findlast(re, str), 0:-1)
@deprecate rsearch(s::AbstractString, r::Regex, idx::Integer) coalesce(findprev(r, s, idx), 0:-1)
@deprecate rsearch(s::AbstractString, r::Regex) coalesce(findlast(r, s), 0:-1)
@deprecate rsearch(s::AbstractString, c::Char, i::Integer) coalesce(findprev(isequal(c), s, i), 0)
@deprecate rsearch(s::AbstractString, c::Char) coalesce(findlast(isequal(c), s), 0)
@deprecate rsearch(a::Union{String,ByteArray}, b::Union{Int8,UInt8}, i::Integer = lastindex(a)) coalesce(findprev(isequal(b), a, i), 0)
@deprecate rsearch(a::String, b::Union{Int8,UInt8}, i::Integer = lastindex(a)) coalesce(findprev(isequal(Char(b)), a, i), 0)
@deprecate rsearch(a::ByteArray, b::Char, i::Integer = lastindex(a)) coalesce(findprev(isequal(UInt8(b)), a, i), 0)

@deprecate searchindex(s::AbstractString, t::AbstractString) first(coalesce(findfirst(t, s), 0:-1))
@deprecate searchindex(s::AbstractString, t::AbstractString, i::Integer) first(coalesce(findnext(t, s, i), 0:-1))
@deprecate rsearchindex(s::AbstractString, t::AbstractString) first(coalesce(findlast(t, s), 0:-1))
@deprecate rsearchindex(s::AbstractString, t::AbstractString, i::Integer) first(coalesce(findprev(t, s, i), 0:-1))

@deprecate searchindex(s::AbstractString, c::Char) coalesce(findfirst(isequal(c), s), 0)
@deprecate searchindex(s::AbstractString, c::Char, i::Integer) coalesce(findnext(isequal(c), s, i), 0)
@deprecate rsearchindex(s::AbstractString, c::Char) coalesce(findlast(isequal(c), s), 0)
@deprecate rsearchindex(s::AbstractString, c::Char, i::Integer) coalesce(findprev(isequal(c), s, i), 0)
@deprecate search(str::Union{String,SubString}, re::Regex, idx::Integer) something(findnext(re, str, idx), 0:-1)
@deprecate search(s::AbstractString, r::Regex, idx::Integer) something(findnext(r, s, idx), 0:-1)
@deprecate search(s::AbstractString, r::Regex) something(findfirst(r, s), 0:-1)
@deprecate search(s::AbstractString, c::Char, i::Integer) something(findnext(isequal(c), s, i), 0)
@deprecate search(s::AbstractString, c::Char) something(findfirst(isequal(c), s), 0)
@deprecate search(a::ByteArray, b::Union{Int8,UInt8}, i::Integer) something(findnext(isequal(b), a, i), 0)
@deprecate search(a::ByteArray, b::Union{Int8,UInt8}) something(findfirst(isequal(b), a), 0)
@deprecate search(a::String, b::Union{Int8,UInt8}, i::Integer) something(findnext(isequal(b), unsafe_wrap(Vector{UInt8}, a), i), 0)
@deprecate search(a::String, b::Union{Int8,UInt8}) something(findfirst(isequal(b), unsafe_wrap(Vector{UInt8}, a)), 0)
@deprecate search(a::ByteArray, b::Char, i::Integer) something(findnext(isequal(UInt8(b)), a, i), 0)
@deprecate search(a::ByteArray, b::Char) something(findfirst(isequal(UInt8(b)), a), 0)

@deprecate search(s::AbstractString, c::Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}, i::Integer) something(findnext(in(c), s, i), 0)
@deprecate search(s::AbstractString, c::Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}) something(findfirst(in(c), s), 0)
@deprecate search(s::AbstractString, t::AbstractString, i::Integer) something(findnext(t, s, i), 0:-1)
@deprecate search(s::AbstractString, t::AbstractString) something(findfirst(t, s), 0:-1)

@deprecate rsearch(s::AbstractString, c::Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}, i::Integer) something(findprev(in(c), s, i), 0)
@deprecate rsearch(s::AbstractString, c::Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}) something(findlast(in(c), s), 0)
@deprecate rsearch(s::AbstractString, t::AbstractString, i::Integer) something(findprev(t, s, i), 0:-1)
@deprecate rsearch(s::AbstractString, t::AbstractString) something(findlast(t, s), 0:-1)

@deprecate rsearch(str::Union{String,SubString}, re::Regex, idx::Integer) something(findprev(re, str, idx), 0:-1)
@deprecate rsearch(str::Union{String,SubString}, re::Regex) something(findlast(re, str), 0:-1)
@deprecate rsearch(s::AbstractString, r::Regex, idx::Integer) something(findprev(r, s, idx), 0:-1)
@deprecate rsearch(s::AbstractString, r::Regex) something(findlast(r, s), 0:-1)
@deprecate rsearch(s::AbstractString, c::Char, i::Integer) something(findprev(isequal(c), s, i), 0)
@deprecate rsearch(s::AbstractString, c::Char) something(findlast(isequal(c), s), 0)
@deprecate rsearch(a::Union{String,ByteArray}, b::Union{Int8,UInt8}, i::Integer = lastindex(a)) something(findprev(isequal(b), a, i), 0)
@deprecate rsearch(a::String, b::Union{Int8,UInt8}, i::Integer = lastindex(a)) something(findprev(isequal(Char(b)), a, i), 0)
@deprecate rsearch(a::ByteArray, b::Char, i::Integer = lastindex(a)) something(findprev(isequal(UInt8(b)), a, i), 0)

@deprecate searchindex(s::AbstractString, t::AbstractString) first(something(findfirst(t, s), 0:-1))
@deprecate searchindex(s::AbstractString, t::AbstractString, i::Integer) first(something(findnext(t, s, i), 0:-1))
@deprecate rsearchindex(s::AbstractString, t::AbstractString) first(something(findlast(t, s), 0:-1))
@deprecate rsearchindex(s::AbstractString, t::AbstractString, i::Integer) first(something(findprev(t, s, i), 0:-1))

@deprecate searchindex(s::AbstractString, c::Char) something(findfirst(isequal(c), s), 0)
@deprecate searchindex(s::AbstractString, c::Char, i::Integer) something(findnext(isequal(c), s, i), 0)
@deprecate rsearchindex(s::AbstractString, c::Char) something(findlast(isequal(c), s), 0)
@deprecate rsearchindex(s::AbstractString, c::Char, i::Integer) something(findprev(isequal(c), s, i), 0)

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

Expand Down
1 change: 1 addition & 0 deletions base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -701,6 +701,7 @@ export
ismissing,
missing,
skipmissing,
something,

# time
sleep,
Expand Down
2 changes: 1 addition & 1 deletion base/file.jl
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ function _win_tempname(temppath::AbstractString, uunique::UInt32)
tempp = cwstring(temppath)
tname = Vector{UInt16}(undef, 32767)
uunique = ccall(:GetTempFileNameW,stdcall,UInt32,(Ptr{UInt16},Ptr{UInt16},UInt32,Ptr{UInt16}), tempp,temp_prefix,uunique,tname)
lentname = coalesce(findfirst(iszero,tname), 0)-1
lentname = something(findfirst(iszero,tname), 0)-1
if uunique == 0 || lentname <= 0
error("GetTempFileName failed: $(Libc.FormatMessage())")
end
Expand Down
28 changes: 27 additions & 1 deletion base/missing.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ showerror(io::IO, ex::MissingException) =
print(io, "MissingException: ", ex.msg)



nonmissingtype(::Type{Union{T, Missing}}) where {T} = T
nonmissingtype(::Type{Missing}) = Union{}
nonmissingtype(::Type{T}) where {T} = T
Expand Down Expand Up @@ -188,3 +187,30 @@ function Base.iterate(itr::SkipMissing, state...)
end
item, state
end

"""
coalesce(x, y...)
Return the first value in the arguments which is not equal to [`missing`](@ref),
if any. Otherwise return `missing`.
# Examples
```jldoctest
julia> coalesce(missing, 1)
1
julia> coalesce(1, missing)
1
julia> coalesce(nothing, 1) # returns `nothing`
julia> coalesce(missing, missing)
missing
```
"""
function coalesce end

coalesce() = missing
coalesce(x::Missing, y...) = coalesce(y...)
coalesce(x::Any, y...) = x
8 changes: 4 additions & 4 deletions base/parse.jl
Original file line number Diff line number Diff line change
Expand Up @@ -278,16 +278,16 @@ function tryparse_internal(::Type{Complex{T}}, s::Union{String,SubString{String}
end

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

# find trailing im/i/j
iᵢ = coalesce(findprev(in(('m','i','j')), s, e), 0)
iᵢ = something(findprev(in(('m','i','j')), s, e), 0)
if iᵢ > 0 && s[iᵢ] == 'm' # im
iᵢ -= 1
if s[iᵢ] != 'i'
Expand Down
4 changes: 2 additions & 2 deletions base/path.jl
Original file line number Diff line number Diff line change
Expand Up @@ -381,8 +381,8 @@ function relpath(path::String, startpath::String = ".")
break
end
end
pathpart = join(path_arr[i+1:coalesce(findlast(x -> !isempty(x), path_arr), 0)], path_separator)
prefix_num = coalesce(findlast(x -> !isempty(x), start_arr), 0) - i - 1
pathpart = join(path_arr[i+1:something(findlast(x -> !isempty(x), path_arr), 0)], path_separator)
prefix_num = something(findlast(x -> !isempty(x), start_arr), 0) - i - 1
if prefix_num >= 0
prefix = pardir * path_separator
relpath_ = isempty(pathpart) ?
Expand Down
2 changes: 1 addition & 1 deletion base/shell.jl
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ function shell_parse(str::AbstractString, interpolate::Bool=true;
end
function consume_upto(j)
update_arg(s[i:prevind(s, j)])
i = coalesce(peek(st), (lastindex(s)+1,'\0'))[1]
i = something(peek(st), (lastindex(s)+1,'\0'))[1]
end
function append_arg()
if isempty(arg); arg = Any["",]; end
Expand Down
56 changes: 24 additions & 32 deletions base/some.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
A wrapper type used in `Union{Some{T}, Nothing}` to distinguish between the absence
of a value ([`nothing`](@ref)) and the presence of a `nothing` value (i.e. `Some(nothing)`).
Use [`coalesce`](@ref) to access the value wrapped by a `Some` object.
Use [`something`](@ref) to access the value wrapped by a `Some` object.
"""
struct Some{T}
value::T
Expand All @@ -33,47 +33,39 @@ function show(io::IO, x::Some)
end

"""
coalesce(x, y...)
notnothing(x)
Return the first value in the arguments which is not equal to
either [`nothing`](@ref) or [`missing`](@ref), or the last argument.
Unwrap arguments of type [`Some`](@ref).
Throw an error if `x === nothing`, and return `x` if not.
"""
notnothing(x::Any) = x
notnothing(::Nothing) = throw(ArgumentError("nothing passed to notnothing"))

"""
something(x, y...)
Return the first value in the arguments which is not equal to [`nothing`](@ref),
if any. Otherwise throw an error.
Arguments of type [`Some`](@ref) are unwrapped.
# Examples
```jldoctest
julia> coalesce(nothing, 1)
julia> something(nothing, 1)
1
julia> coalesce(missing, 1)
julia> something(Some(1), nothing)
1
julia> coalesce(1, nothing)
1
julia> something(missing, nothing)
missing
julia> coalesce(nothing, nothing) # returns nothing, but not printed in the REPL
julia> coalesce(Some(1))
1
julia> coalesce(nothing, Some(1))
1
julia> something(nothing, nothing)
ERROR: ArgumentError: No value arguments present
```
"""
function coalesce end

coalesce(x::Any) = x
coalesce(x::Some) = x.value
coalesce(x::Nothing) = nothing
coalesce(x::Missing) = missing
coalesce(x::Any, y...) = x
coalesce(x::Some, y...) = x.value
coalesce(x::Union{Nothing, Missing}, y...) = coalesce(y...)

"""
notnothing(x)
function something end

Throw an error if `x === nothing`, and return `x` if not.
"""
notnothing(x::Any) = x
notnothing(::Nothing) = throw(ArgumentError("nothing passed to notnothing"))
something() = throw(ArgumentError("No value arguments present"))
something(x::Nothing, y...) = something(y...)
something(x::Some, y...) = x.value
something(x::Any, y...) = x
6 changes: 3 additions & 3 deletions base/stacktraces.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ module StackTraces

import Base: hash, ==, show
using Base.Printf: @printf
using Base: coalesce
using Base: something

export StackTrace, StackFrame, stacktrace

Expand Down Expand Up @@ -247,12 +247,12 @@ all frames above the specified function). Primarily used to remove `StackTraces`
from the `StackTrace` prior to returning it.
"""
function remove_frames!(stack::StackTrace, name::Symbol)
splice!(stack, 1:coalesce(findlast(frame -> frame.func == name, stack), 0))
splice!(stack, 1:something(findlast(frame -> frame.func == name, stack), 0))
return stack
end

function remove_frames!(stack::StackTrace, names::Vector{Symbol})
splice!(stack, 1:coalesce(findlast(frame -> frame.func in names, stack), 0))
splice!(stack, 1:something(findlast(frame -> frame.func in names, stack), 0))
return stack
end

Expand Down
4 changes: 2 additions & 2 deletions base/statistics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -228,10 +228,10 @@ The mean `mean` over the region may be provided.
var(A::AbstractArray; corrected::Bool=true, mean=nothing, dims=:) = _var(A, corrected, mean, dims)

_var(A::AbstractArray, corrected::Bool, mean, dims) =
varm(A, coalesce(mean, Base.mean(A, dims=dims)); corrected=corrected, dims=dims)
varm(A, something(mean, Base.mean(A, dims=dims)); corrected=corrected, dims=dims)

_var(A::AbstractArray, corrected::Bool, mean, ::Colon) =
real(varm(A, coalesce(mean, Base.mean(A)); corrected=corrected))
real(varm(A, something(mean, Base.mean(A)); corrected=corrected))

varm(iterable, m; corrected::Bool=true) = _var(iterable, corrected, m)

Expand Down
10 changes: 5 additions & 5 deletions base/strings/search.jl
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ function _searchindex(s::Union{AbstractString,ByteArray},
end
end

_searchindex(s::AbstractString, t::AbstractChar, i::Integer) = coalesce(findnext(isequal(t), s, i), 0)
_searchindex(s::AbstractString, t::AbstractChar, i::Integer) = something(findnext(isequal(t), s, i), 0)

function _search_bloom_mask(c)
UInt64(1) << (c & 63)
Expand All @@ -149,7 +149,7 @@ _nthbyte(a::Union{AbstractVector{UInt8},AbstractVector{Int8}}, i) = a[i]

function _searchindex(s::String, t::String, i::Integer)
# Check for fast case of a single byte
lastindex(t) == 1 && return coalesce(findnext(isequal(t[1]), s, i), 0)
lastindex(t) == 1 && return something(findnext(isequal(t[1]), s, i), 0)
_searchindex(unsafe_wrap(Vector{UInt8},s), unsafe_wrap(Vector{UInt8},t), i)
end

Expand All @@ -162,7 +162,7 @@ function _searchindex(s::ByteArray, t::ByteArray, i::Integer)
elseif m == 0
return 0
elseif n == 1
return coalesce(findnext(isequal(_nthbyte(t,1)), s, i), 0)
return something(findnext(isequal(_nthbyte(t,1)), s, i), 0)
end

w = m - n
Expand Down Expand Up @@ -317,7 +317,7 @@ end
function _rsearchindex(s::String, t::String, i::Integer)
# Check for fast case of a single byte
if lastindex(t) == 1
return coalesce(findprev(isequal(t[1]), s, i), 0)
return something(findprev(isequal(t[1]), s, i), 0)
elseif lastindex(t) != 0
j = i ncodeunits(s) ? nextind(s, i)-1 : i
return _rsearchindex(unsafe_wrap(Vector{UInt8}, s), unsafe_wrap(Vector{UInt8}, t), j)
Expand All @@ -339,7 +339,7 @@ function _rsearchindex(s::ByteArray, t::ByteArray, k::Integer)
elseif m == 0
return 0
elseif n == 1
return coalesce(findprev(isequal(_nthbyte(t,1)), s, k), 0)
return something(findprev(isequal(_nthbyte(t,1)), s, k), 0)
end

w = m - n
Expand Down
Loading

0 comments on commit 6caeb71

Please sign in to comment.