Skip to content

Commit 4166209

Browse files
S. SahmS. Sahm
authored andcommitted
in fact there is no need for Stop
it is just Const really amazing
1 parent 3c70797 commit 4166209

8 files changed

Lines changed: 92 additions & 107 deletions

File tree

src/Const.jl

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,30 @@
1-
struct Const{E, T}
1+
struct Const{T}
22
value::T
3-
Const{E}(value::T) where {E, T} = new{E, T}(value)
43
end
5-
Const(value) = Const{Any}(value)
6-
Const{T}(x::Const) where T = Const{T}(x.value)
74

85
# == controversy https://github.com/JuliaLang/julia/issues/4648
96
Base.:(==)(a::Const, b::Const) = a.value == b.value
107

8+
function Base.show(io::IO, x::Const)
9+
print(io, "Const($(repr(x.value)))")
10+
end
11+
12+
isconst(::Const) = true
13+
isconst(other) = false
14+
15+
1116
# const just does nothing, i.e. leaves everything constant
17+
Base.iterate(c::Const) = nothing
1218
Base.foreach(f, c::Const) = nothing
13-
function Base.map(f, c::Const{E}) where E
14-
Const{Out(f, E)}(c.value)
15-
end
19+
Base.map(f, c::Const) = c
20+
Iterators.flatten(c::Const) = c
1621

17-
Base.eltype(::Type{<:Const{E}}) where E = E
1822
Base.eltype(::Type{<:Const}) = Any
23+
24+
# Const is covariate
25+
Base.convert(::Type{Const{T}}, x::Const) where {T} = Const(Base.convert(T, x.value))
26+
promote_rule(::Type{Const{T}}, ::Type{Const{S}}) where {T, S<:T} = Const{T}
27+
28+
# we need this for safety, if someone overwrites typejoin for Unions with Const
29+
Base.typejoin(::Type{Const{T}}, ::Type{Const{T}}) where T = Const{T}
30+
Base.typejoin(::Type{<:Const}, ::Type{<:Const}) = Const

src/DataTypesBasic.jl

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,16 @@ functions, we go with Approach 2. That applies to Option, Try and Either.
2929
"""
3030
module DataTypesBasic
3131

32-
export Const,
33-
Identity, Stop,
32+
export Const, Identity,
3433
Option, issomething, iftrue, iffalse, getOption, # isnothing, Nothing, Some comes from Base
3534
Either, either, isleft, isright, getleft, getright, getleftOption, getrightOption, flip_left_right,
36-
Try, Failure, @Try, @TryCatch, issuccess, isfailure, MultipleExceptions,
35+
Try, Thrown, @Try, @TryCatch, issuccess, isexception, MultipleExceptions,
3736
ContextManager, @ContextManager
3837

3938
using IsDef
4039

4140
include("Const.jl")
4241
include("Identity.jl")
43-
include("Stop.jl")
4442
include("Option.jl")
4543
include("Try.jl")
4644
include("Either.jl")

src/Either.jl

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,20 @@
1-
const Either{L, R} = Union{Stop{L}, Identity{R}}
2-
Either{L, R}(x::L) where {L, R} = Stop(x)
1+
const Either{L, R} = Union{Const{L}, Identity{R}}
2+
Either{L, R}(x::L) where {L, R} = Const(x)
33
Either{L, R}(x::R) where {L, R} = Identity(x)
44
Either{L}(x::R) where {L, R} = Identity(x)
5-
Either{L}(x::L) where {L} = Stop(x)
6-
7-
# Stop is covariate
8-
Base.convert(::Type{Stop{T}}, x::Stop) where {T} = Stop(Base.convert(T, x.value))
9-
promote_rule(::Type{Stop{T}}, ::Type{Stop{S}}) where {T, S<:T} = Stop{T}
5+
Either{L}(x::L) where {L} = Const(x)
106

117

128
# TypeJoin should work with Identity and Either
139

14-
# typejoin Stop & Identity
15-
Base.typejoin(::Type{Stop{L}}, ::Type{Identity{R}}) where {L, R} = Either{L, R}
16-
Base.typejoin(::Type{Identity{R}}, ::Type{Stop{L}}) where {L, R} = Either{L, R}
17-
# typejoin Stop & Either
18-
Base.typejoin(::Type{Stop{L}}, ::Type{<:Either{L, R}}) where {L, R} = Either{L, R}
19-
Base.typejoin(::Type{<:Either{L, R}}, ::Type{Stop{L}}) where {L, R} = Either{L, R}
20-
Base.typejoin(::Type{<:Stop}, ::Type{<:Either{<:Any, R}}) where {R} = Either{<:Any, R}
21-
Base.typejoin(::Type{<:Either{<:Any, R}}, ::Type{<:Stop}) where {R} = Either{<:Any, R}
10+
# typejoin Const & Identity
11+
Base.typejoin(::Type{Const{L}}, ::Type{Identity{R}}) where {L, R} = Either{L, R}
12+
Base.typejoin(::Type{Identity{R}}, ::Type{Const{L}}) where {L, R} = Either{L, R}
13+
# typejoin Const & Either
14+
Base.typejoin(::Type{Const{L}}, ::Type{<:Either{L, R}}) where {L, R} = Either{L, R}
15+
Base.typejoin(::Type{<:Either{L, R}}, ::Type{Const{L}}) where {L, R} = Either{L, R}
16+
Base.typejoin(::Type{<:Const}, ::Type{<:Either{<:Any, R}}) where {R} = Either{<:Any, R}
17+
Base.typejoin(::Type{<:Either{<:Any, R}}, ::Type{<:Const}) where {R} = Either{<:Any, R}
2218
# typejoin Identity & Either
2319
Base.typejoin(::Type{Identity{R}}, ::Type{<:Either{L, R}}) where {L, R} = Either{L, R}
2420
Base.typejoin(::Type{<:Either{L, R}}, ::Type{Identity{R}}) where {L, R} = Either{L, R}
@@ -32,7 +28,7 @@ Base.typejoin(::Type{<:Either}, ::Type{<:Either}) = Either
3228

3329
# Conversion should also work with Either
3430
Base.convert(::Type{Either{L, R}}, x::Identity) where {L, R} = Identity(Base.convert(R, x.value))
35-
Base.convert(::Type{Either{L, R}}, x::Stop) where {L, R} = Stop(Base.convert(L, x.value))
31+
Base.convert(::Type{Either{L, R}}, x::Const) where {L, R} = Const(Base.convert(L, x.value))
3632

3733
Base.eltype(::Type{<:Either{L, R}}) where {L, R} = R
3834
Base.eltype(::Type{<:Either{<:Any, R}}) where {R} = R
@@ -43,26 +39,26 @@ Base.eltype(::Type{<:Either}) = Any
4339
# ------------------
4440

4541
function either(left_false, comparison::Bool, right_true)
46-
comparison ? Identity(right_true) : Stop(left_false)
42+
comparison ? Identity(right_true) : Const(left_false)
4743
end
4844

49-
flip_left_right(x::Stop) = Identity(x.value)
50-
flip_left_right(x::Identity) = Stop(x.value)
45+
flip_left_right(x::Const) = Identity(x.value)
46+
flip_left_right(x::Identity) = Const(x.value)
5147

52-
isleft(e::Stop) = true
48+
isleft(e::Const) = true
5349
isleft(e::Identity) = false
5450

55-
isright(e::Stop) = false
51+
isright(e::Const) = false
5652
isright(e::Identity) = true
5753

58-
getleft(e::Stop) = e.value
54+
getleft(e::Const) = e.value
5955
# getleft(e::Identity) = nothing # throw an error if getleft is called on Identity
6056

61-
# getright(e::Stop) = nothing # throw an error if getright is called on Stop
57+
# getright(e::Const) = nothing # throw an error if getright is called on Const
6258
getright(e::Identity) = e.value
6359

64-
getleftOption(e::Stop{L}) where {L} = Identity{L}(e.value)
60+
getleftOption(e::Const{L}) where {L} = Identity{L}(e.value)
6561
getleftOption(e::Identity) = nothing
6662

67-
getrightOption(e::Stop) = nothing
63+
getrightOption(e::Const) = nothing
6864
getrightOption(e::Identity{R}) where {R} = e

src/Identity.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ function Base.show(io::IO, x::Identity)
88
print(io, "Identity($(repr(x.value)))")
99
end
1010

11+
isidentity(::Identity) = true
12+
isidentity(other) = false
13+
14+
1115
Base.get(a::Identity) = a.value
1216
Base.eltype(::Type{<:Identity{T}}) where T = T
1317
Base.eltype(::Type{<:Identity}) = Any

src/Stop.jl

Lines changed: 0 additions & 28 deletions
This file was deleted.

src/Try.jl

Lines changed: 33 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,37 @@
1-
const Try{T} = Union{Stop{<:Exception}, Identity{T}}
1+
const Try{T} = Union{Const{<:Exception}, Identity{T}}
22
Try(t) = Identity(t)
3-
Try(t::Exception) = Stop(t)
3+
Try(t::Exception) = Const(t)
44
Try{T}(t::T) where T = Identity(t)
5-
Try{T}(other) where T = Stop(other)
5+
Try{T}(other) where T = Const(other)
66

77

88

99
"""
10-
Failure is like Exception, however can also cary stacktraces
10+
Thrown is like Exception, however can also cary stacktraces
1111
"""
12-
struct Failure{E} <: Exception
12+
struct Thrown{E} <: Exception
1313
exception::E
1414
stacktrace::Vector
1515
end
1616

1717
# == controversy https://github.com/JuliaLang/julia/issues/4648
18-
function Base.:(==)(a::Failure, b::Failure)
18+
function Base.:(==)(a::Thrown, b::Thrown)
1919
a.exception == b.exception && a.stack == b.stack
2020
end
2121

22+
function Base.show(io::IO, x::Thrown)
23+
print(io, "Thrown($(repr(x.exception)))")
24+
end
2225

2326
# Multiline version, following https://docs.julialang.org/en/v1/manual/types/#man-custom-pretty-printing-1
24-
function Base.show(io::IO, ::MIME"text/plain", exc::Failure{E}) where {E}
25-
println(io, "Failure{$E}($(repr(exc.exception)))")
27+
function Base.show(io::IO, ::MIME"text/plain", exc::Thrown{E}) where {E}
28+
println(io, "Thrown($(repr(exc.exception)))")
2629
for (exc′, bt′) in exc.stacktrace
2730
showerror(io, exc′, bt′)
2831
println(io)
2932
end
3033
end
31-
function Base.showerror(io::IO, ::MIME"text/plain", exc::Failure)
34+
function Base.showerror(io::IO, ::MIME"text/plain", exc::Thrown)
3235
Base.show(io, MIME"text/plain"(), exc)
3336
end
3437

@@ -66,9 +69,9 @@ function Base.showerror(io::IO, ::MIME"text/plain", exc::MultipleExceptions)
6669
Base.show(io, MIME"text/plain"(), exc)
6770
end
6871

69-
Base.merge(f1::Failure, f2::Failure) = MultipleExceptions((f1, f2))
70-
Base.merge(f::Failure, e::Exception) = MultipleExceptions((f, e))
71-
Base.merge(e::Exception, f::Failure) = MultipleExceptions((e, f))
72+
Base.merge(f1::Thrown, f2::Thrown) = MultipleExceptions((f1, f2))
73+
Base.merge(f::Thrown, e::Exception) = MultipleExceptions((f, e))
74+
Base.merge(e::Exception, f::Thrown) = MultipleExceptions((e, f))
7275
Base.merge(es::MultipleExceptions, e::Exception) = MultipleExceptions(tuple(es.exceptions..., e))
7376
Base.merge(e::Exception, fs::MultipleExceptions) = MultipleExceptions(tuple(e, fs.exceptions...))
7477
Base.merge(es1::MultipleExceptions, es2::MultipleExceptions) = MultipleExceptions(tuple(es1.exceptions..., es2.exceptions...))
@@ -79,20 +82,20 @@ promote_rule(::Type{Try{T}}, ::Type{Try{S}}) where {T, S<:T} = Try{T}
7982

8083

8184

82-
# typejoin Failure & Failure
83-
# Base.typejoin(::Type{Failure{E}}, ::Type{Failure{E}}) where E = Failure{E}
84-
# Base.typejoin(::Type{<:Failure}, ::Type{<:Failure}) = Failure
85+
# typejoin Thrown & Thrown
86+
# Base.typejoin(::Type{Thrown{E}}, ::Type{Thrown{E}}) where E = Thrown{E}
87+
# Base.typejoin(::Type{<:Thrown}, ::Type{<:Thrown}) = Thrown
8588
# # typejoin Identity & Identity
8689
# Base.typejoin(::Type{Identity{T}}, ::Type{Identity{T}}) where T = Identity{E}
8790
# Base.typejoin(::Type{<:Identity}, ::Type{<:Identity}) = Identity
88-
# # typejoin Failure & Identity
89-
# Base.typejoin(::Type{Failure{E}}, ::Type{Identity{T}}) where {T, E} = Try{T, E}
90-
# Base.typejoin(::Type{Identity{T}}, ::Type{Failure{E}}) where {T, E} = Try{T, E}
91-
# # typejoin Failure & Try
92-
# Base.typejoin(::Type{Failure{E}}, ::Type{<:Try{T, E}}) where {T, E} = Try{T, E}
93-
# Base.typejoin(::Type{<:Try{T, E}}, ::Type{Failure{E}}) where {T, E} = Try{T, E}
94-
# Base.typejoin(::Type{<:Failure}, ::Type{<:Try{T}}) where T = Try{T}
95-
# Base.typejoin(::Type{<:Try{T}}, ::Type{<:Failure}) where T = Try{T}
91+
# # typejoin Thrown & Identity
92+
# Base.typejoin(::Type{Thrown{E}}, ::Type{Identity{T}}) where {T, E} = Try{T, E}
93+
# Base.typejoin(::Type{Identity{T}}, ::Type{Thrown{E}}) where {T, E} = Try{T, E}
94+
# # typejoin Thrown & Try
95+
# Base.typejoin(::Type{Thrown{E}}, ::Type{<:Try{T, E}}) where {T, E} = Try{T, E}
96+
# Base.typejoin(::Type{<:Try{T, E}}, ::Type{Thrown{E}}) where {T, E} = Try{T, E}
97+
# Base.typejoin(::Type{<:Thrown}, ::Type{<:Try{T}}) where T = Try{T}
98+
# Base.typejoin(::Type{<:Try{T}}, ::Type{<:Thrown}) where T = Try{T}
9699
# # typejoin Identity & Try
97100
# Base.typejoin(::Type{Identity{T}}, ::Type{<:Try{T, E}}) where {T, E} = Try{T, E}
98101
# Base.typejoin(::Type{<:Try{T, E}}, ::Type{Identity{T}}) where {T, E} = Try{T, E}
@@ -115,7 +118,7 @@ macro Try(expr)
115118
r = $(esc(expr))
116119
Identity{typeof(r)}(r)
117120
catch exc
118-
Stop(Failure(exc, Base.catch_stack()))
121+
Const(Thrown(exc, Base.catch_stack()))
119122
end
120123
end
121124
end
@@ -128,7 +131,7 @@ macro TryCatch(exception, expr)
128131
Identity{typeof(r)}(r)
129132
catch exc
130133
if exc isa $(esc(exception))
131-
Stop(Failure(exc, Base.catch_stack()))
134+
Const(Thrown(exc, Base.catch_stack()))
132135
else
133136
rethrow()
134137
end
@@ -137,12 +140,12 @@ macro TryCatch(exception, expr)
137140
end
138141

139142
issuccess(::Identity) = true
140-
issuccess(::Stop{<:Exception}) = false
143+
issuccess(::Const{<:Exception}) = false
141144

142-
isfailure(::Identity) = false
143-
isfailure(::Stop{<:Exception}) = true
145+
isexception(::Identity) = false
146+
isexception(::Const{<:Exception}) = true
144147

145148
Base.eltype(::Type{<:Try{T}}) where T = T
146149
Base.eltype(::Type{<:Try}) = Any
147-
# somehow the normal Stop eltype got broken
148-
Base.eltype(::Type{<:Stop{<:Exception}}) = Any
150+
# somehow the normal Const eltype got broken
151+
Base.eltype(::Type{<:Const{<:Exception}}) = Any

src/convert.jl

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44
# Vector
55
Base.convert(::Type{<:Vector}, x::Identity) = [x.value]
66
Base.convert(::Type{<:Vector}, x::Nothing) = []
7-
Base.convert(::Type{<:Vector}, x::Stop) = []
7+
Base.convert(::Type{<:Vector}, x::Const) = []
88

9-
# Stop
10-
Base.convert(::Type{<:Stop}, x::Nothing) = Stop(nothing)
11-
function Base.convert(::Type{Stop}, x::Vector)
9+
# Const
10+
Base.convert(::Type{<:Const}, x::Nothing) = Const(nothing)
11+
function Base.convert(::Type{Const}, x::Vector)
1212
@assert !isempty(x) "can only convert empty Vector to Nothing, got $(x)"
13-
Stop([])
13+
Const([])
1414
end
1515

1616
# Nothing
@@ -20,5 +20,5 @@ function Base.convert(::Type{Nothing}, x::Vector)
2020
end
2121

2222
# Identity
23-
# Nothing and Stop are just passed through when asked to convert to identity
24-
Base.convert(::Type{Identity}, x::Union{Nothing, Stop}) = x
23+
# Nothing and Const are just passed through when asked to convert to identity
24+
Base.convert(::Type{Identity}, x::Union{Nothing, Const}) = x

test/Try.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
@test issuccess(@Try 5)
22
@test !issuccess(@Try error("hi"))
3-
@test isfailure(@Try error("hi"))
4-
@test !isfailure(@Try 5)
3+
@test isexception(@Try error("hi"))
4+
@test !isexception(@Try 5)
55

6-
@test (@Try error("hi")) isa Stop{<:Failure}
6+
@test (@Try error("hi")) isa Const{<:Thrown}
77

88

99
me = MultipleExceptions(ErrorException("hi"))
@@ -13,5 +13,5 @@ me = MultipleExceptions(ErrorException("hi"))
1313

1414
@test eltype(Try{Int}) == Int
1515
@test eltype(Identity{Int}) == Int
16-
@test eltype(Failure) == Any
17-
@test eltype(Stop{Failure}) == Any
16+
@test eltype(Thrown) == Any
17+
@test eltype(Const{Thrown}) == Any

0 commit comments

Comments
 (0)