# Implementing a zero width type for IntervalSets

**URL:** <https://discourse.julialang.org/t/implementing-a-zero-width-type-for-intervalsets/23444>\
**Category:** General Usage\
**Tags:** question\
**Created:** [April 23, 2019, 2:09pm UTC](https://discourse.julialang.org/t/implementing-a-zero-width-type-for-intervalsets/23444 "2019-04-23T14:09:43Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)\
**Post date:** [April 23, 2019, 2:09pm UTC](https://discourse.julialang.org/t/implementing-a-zero-width-type-for-intervalsets/23444/1 "2019-04-23T14:09:43Z")

</div>

This is about using the foundations of [IntervalSets.jl](https://github.com/JuliaMath/IntervalSets.jl) for my own purposes.

I’d like to be able to dispatch on sets that have zero width (i.e. sets whose end points are identical) differently than on sets with a width larger than zero. So I want to define a new subtype of `AbstractInterval` (e.g. `CollapsedInterval` or some such), and all the functions necessary for all the machinery of `IntervalSets` to work as expected. Basically have the same behavior as if I tested `IntervalSets` on, say, `1..1`.

For this to work, what is the minimal set of functions I should define for my subtype? I’m asking because in their [README.md#L12](https://github.com/JuliaMath/IntervalSets.jl/edit/master/README.md#L12) they state that this package is intended to be built on, but I couldn’t find the minimal set of functions I’d need to define.

Thanks!

---

<div class="post-metadata">

**Author:** ![dlfivefifty](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlfivefifty/32/1959_2.png) [@dlfivefifty](https://discourse.julialang.org/u/dlfivefifty)\
**Post date:** [April 23, 2019, 9:36pm UTC](https://discourse.julialang.org/t/implementing-a-zero-width-type-for-intervalsets/23444/2 "2019-04-23T21:36:10Z")

</div>

The comments here might help:

[https://github.com/JuliaMath/IntervalSets.jl/blob/master/src/IntervalSets.jl](https://github.com/JuliaMath/IntervalSets.jl/blob/master/src/IntervalSets.jl)

First: do you know at compile time whether the endpoints are open or closed? If so, subtype `TypedEndpointsInterval{:closed,:closed}` and then I believe you only need to override `endpoints`. Otherwise, also override `closedendpoints`.

PRs to improve the docs would be appreciated.

---

<div class="post-metadata">

**Author:** ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)\
**Post date:** [April 24, 2019, 7:39am UTC](https://discourse.julialang.org/t/implementing-a-zero-width-type-for-intervalsets/23444/3 "2019-04-24T07:39:26Z")

</div>

Very cool, thank you, but, why are the arguments of `duration` limited to integers and dates…? Wouldn’t it be better to define it along similar lines to the implementation of `width`:

```julia
function duration(A::AbstractInterval)
    _width = rightendpoint(A) - leftendpoint(A)
    max(zero(_width), _width + oneunit(_width)) # this works when T is a Date
end

```

This way it should work with _any_ typed interval.

---

<div class="post-metadata">

**Author:** ![dlfivefifty](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlfivefifty/32/1959_2.png) [@dlfivefifty](https://discourse.julialang.org/u/dlfivefifty)\
**Post date:** [April 24, 2019, 7:43am UTC](https://discourse.julialang.org/t/implementing-a-zero-width-type-for-intervalsets/23444/4 "2019-04-24T07:43:45Z")

</div>

I didn’t write that function or use it so wouldn’t know. Maybe make a PR and see if anyone pipes up?

---

<div class="post-metadata">

**Author:** ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)\
**Post date:** [April 24, 2019, 7:47am UTC](https://discourse.julialang.org/t/implementing-a-zero-width-type-for-intervalsets/23444/5 "2019-04-24T07:47:36Z")

</div>

~~will do!~~ will wait for @Tamas_Papp’s response (can see him typing)

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [April 24, 2019, 7:53am UTC](https://discourse.julialang.org/t/implementing-a-zero-width-type-for-intervalsets/23444/6 "2019-04-24T07:53:21Z")

</div>

I actually deleted what I was typing, wondering if it made sense. The gist was that I would just define a type wrapping a `<:Real`, and for that `endpoints`, and `closedendpoints`, and then whatever else is needed for your functionality, then I guess you should be fine.

Another solution would be a trait-like

```julia
iszerowidth(interval) = Val{leftendpoint(interval) = rightendpoint(interval)}()

```

which is dynamic _per se_, but propagating this would make the callees type stable.

---

<div class="post-metadata">

**Author:** ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)\
**Post date:** [April 24, 2019, 9:19am UTC](https://discourse.julialang.org/t/implementing-a-zero-width-type-for-intervalsets/23444/7 "2019-04-24T09:19:26Z")

</div>

Did the [PR](https://github.com/JuliaMath/IntervalSets.jl/pull/51).

> [@Tamas\_Papp](#):
>
> The gist was that I would just define a type wrapping a `<:Real` , and for that `endpoints` , and `closedendpoints` , and then whatever else is needed for your functionality, then I guess you should be fine.

This was what I started with (and might return to), cause really, I don’t need that much. But I love the idea of these light meta-packages, such as `IntervalSets`, that can be used everywhere, so I figured I might try to make use of their existing API. But if implementing a subtype is more tedious than implementing a wrapper with needed functionality then it defeats the purpose.

> [@Tamas\_Papp](#):
>
> Another solution would be a trait-like
> 
> ```julia
> iszerowidth(interval) = Val{leftendpoint(interval) ==* rightendpoint(interval)}()
> 
> ```
> 
> which is dynamic _per se_ , but propagating this would make the callees type stable.

(\* changed the `=` to `==`) I need to read more about traits. How exactly would this work…?

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [April 24, 2019, 9:22am UTC](https://discourse.julialang.org/t/implementing-a-zero-width-type-for-intervalsets/23444/8 "2019-04-24T09:22:05Z")

</div>

broadly

```julia
do_stuff(interval) = _do_lots_of_stuff(iszerowidth(interval), interval)

_do_lots_of_stuff(::Val{true}, interval) = ...

```

The first layer would use dynamic dispatch, eg as an `if`. Come to think of it, even a branch should not be that costly within a function, so this may not be worth it.
