# Range checking / bounds (of a variable) checking

**URL:** https://discourse.julialang.org/t/range-checking-bounds-of-a-variable-checking/13931
**Category:** General Usage
**Created:** [August 23, 2018, 11:51am UTC](https://discourse.julialang.org/t/range-checking-bounds-of-a-variable-checking/13931 "2018-08-23T11:51:18Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![scelles](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scelles/32/220408_2.png) [@scelles](https://discourse.julialang.org/u/scelles)
#### Post date: [August 23, 2018, 11:51am UTC](https://discourse.julialang.org/t/range-checking-bounds-of-a-variable-checking/13931/1 "2018-08-23T11:51:18Z")

</div>

Hello,

In my old memories, I recall that [Ada (programming language)](https://en.wikipedia.org/wiki/Ada_(programming_language)) provide a concept of “range” for checking that a numerical value stored in a variable is always between a lower bound and an upper bound.  
This kind of check, is done at run time.  
I wonder if this kind of mechanism currently exist in Julia.  
For example I would like to say that I store an unsigned integer 8 but that upper bound can’t be upper than 10 and lower bound must be greater than or equal to 1.  
I only find information about bound checking for array indices in doc.  
Any idea?

Kind regards

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [August 23, 2018, 12:14pm UTC](https://discourse.julialang.org/t/range-checking-bounds-of-a-variable-checking/13931/2 "2018-08-23T12:14:21Z")

</div>

Make your own type wrapping the number, implement the methods and provide the checking in an inner constructor.

```julia
julia> struct RangeNumber{T<:Number, R}
           v::T

           function RangeNumber(v::Number, r::UnitRange)
               v in r || error("$v not in $r")
               return new{typeof(v), r}(v)
           end
       end

julia> Base.:+(a::RangeNumber{T, R}, b::RangeNumber{T, R}) where {T, R} = RangeNumber(a.v+b.v, R)

julia> Base.:+(a::Number, b::RangeNumber{T, R}) where {T, R} = RangeNumber(a+b.v, R)

julia> Base.:+(a::RangeNumber{T, R}, b::Number) where {T, R} = RangeNumber(a.v+b, R)

julia> a = RangeNumber(3, 1:7)
RangeNumber{Int64,1:7}(3)

julia> a+a
RangeNumber{Int64,1:7}(6)

julia> a+a+a
ERROR: 9 not in 1:7
Stacktrace:
 [1] error(::String) at ./error.jl:33
 [2] RangeNumber(::Int64, ::UnitRange{Int64}) at ./REPL[1]:5
 [3] + at ./REPL[3]:1 [inlined]
 [4] +(::RangeNumber{Int64,1:7}, ::RangeNumber{Int64,1:7}, ::RangeNumber{Int64,1:7}) at ./operators.jl:502
 [5] top-level scope at none:0

julia> a+3
RangeNumber{Int64,1:7}(6)

julia> a+5
ERROR: 8 not in 1:7
Stacktrace:
 [1] error(::String) at ./error.jl:33
 [2] RangeNumber(::Int64, ::UnitRange{Int64}) at ./REPL[1]:5
 [3] +(::RangeNumber{Int64,1:7}, ::Int64) at ./REPL[5]:1
 [4] top-level scope at none:0

```

etc

---

<div class="post-metadata">

### Author: ![scelles](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scelles/32/220408_2.png) [@scelles](https://discourse.julialang.org/u/scelles)
#### Post date: [August 23, 2018, 1:37pm UTC](https://discourse.julialang.org/t/range-checking-bounds-of-a-variable-checking/13931/3 "2018-08-23T13:37:23Z")

</div>

Very interesting althought I would prefer to also be able to call

```
RangeNumber{Int64,1:7}(3)

```

So I can store the “restriction” (ie `RangeNumber{Int64,1:7}`) and use it later.

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [August 23, 2018, 1:39pm UTC](https://discourse.julialang.org/t/range-checking-bounds-of-a-variable-checking/13931/4 "2018-08-23T13:39:22Z")

</div>

Just add the constructor

```julia
julia> RangeNumber{T, R}(n) where {T, R} = RangeNumber(convert(T, n), R)

julia> RangeNumber{Int64,1:7}(3)
RangeNumber{Int64,1:7}(3)

julia> RangeNumber{Int64,1:7}(8)
ERROR: 8 not in 1:7

```

---

<div class="post-metadata">

### Author: ![scelles](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scelles/32/220408_2.png) [@scelles](https://discourse.julialang.org/u/scelles)
#### Post date: [August 23, 2018, 1:41pm UTC](https://discourse.julialang.org/t/range-checking-bounds-of-a-variable-checking/13931/5 "2018-08-23T13:41:46Z")

</div>

Great! Thanks @kristoffer.carlsson

---

<div class="post-metadata">

### Author: ![scelles](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scelles/32/220408_2.png) [@scelles](https://discourse.julialang.org/u/scelles)
#### Post date: [August 23, 2018, 2:01pm UTC](https://discourse.julialang.org/t/range-checking-bounds-of-a-variable-checking/13931/6 "2018-08-23T14:01:09Z")

</div>

I’m still a bit stuck up.

I would like to be able to store a restriction (range checking) but also the lack of range checking.

I did

```julia
abstract type AbstractRangeNumber end

Number(rn::AbstractRangeNumber) = rn.v

struct NoRangeNumber{T<:Number} <: AbstractRangeNumber
    v::T
    function NoRangeNumber(v::Number)
        return new{typeof(v)}(v)
    end
end

"""
    RangeNumber(v, r)

# Example
a = RangeNumber(3, 1:7)
"""
struct RangeNumber{T<:Number, R} <: AbstractRangeNumber
    v::T

    function RangeNumber(v::Number, r::UnitRange)
        v in r || error("$v not in $r")
        return new{typeof(v), r}(v)
    end
end

RangeNumber{T, R}(n) where {T, R} = RangeNumber(n, R)

Base.:+(a::RangeNumber{T, R}, b::RangeNumber{T, R}) where {T, R} = RangeNumber(a.v+b.v, R)
Base.:+(a::Number, b::RangeNumber{T, R}) where {T, R} = RangeNumber(a+b.v, R)
Base.:+(a::RangeNumber{T, R}, b::Number) where {T, R} = RangeNumber(a.v+b, R)

Base.:(==)(a::AbstractRangeNumber{T, R}, b::AbstractRangeNumber{T, R}) where {T, R} = a.v == b.v
Base.:(==)(a::Number, b::AbstractRangeNumber{T, R}) where {T, R} = a == b.v
Base.:(==)(a::AbstractRangeNumber{T, R}, b::Number) where {T, R} = a.v == b

```

and tests:

```julia
using Nextion: RangeNumber, NoRangeNumber
using Test

@testset "RangeNumber" begin
    @testset "construct / isequal" begin
        a = RangeNumber(3, 1:7)
        @test a == 3
    end

    @testset "addition / overflow" begin
        a = RangeNumber(3, 1:7)
        @test a + a == 6 
        @test_throws ErrorException a + a + a == 9
    end

    @testset "other construct" begin
        a = RangeNumber{Int64, 1:7}(3)
        @test a == 3

        @test_throws ErrorException a = RangeNumber{Int64, 1:7}(8)
    end

    @testset "NoRangeNumber" begin
        a = NoRangeNumber(3)
        @test a == 3
    end

end

```

but it’s failling for odd reason

```julia
$ julia test/test_range_number.jl 
ERROR: LoadError: LoadError: TypeError: in Type{...} expression, expected UnionAll, got Type{Nextion.AbstractRangeNumber}
Stacktrace:
 [1] top-level scope at none:0
 [2] include at ./boot.jl:317 [inlined]
 [3] include_relative(::Module, ::String) at ./loading.jl:1038
 [4] include at ./sysimg.jl:29 [inlined]
 [5] include(::String) at /home/scls/.julia/dev/Nextion/src/Nextion.jl:37
 [6] top-level scope at none:0
 [7] include at ./boot.jl:317 [inlined]
 [8] include_relative(::Module, ::String) at ./loading.jl:1038
 [9] include(::Module, ::String) at ./sysimg.jl:29
 [10] top-level scope at none:2
 [11] eval at ./boot.jl:319 [inlined]
 [12] eval(::Expr) at ./client.jl:399
 [13] top-level scope at ./none:3

```

The general idea is to be able to store either a restriction or a lack of restriction in numbers.
