Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Interval implementation #34

Open
JWood48 opened this issue Aug 14, 2020 · 12 comments
Open

Add Interval implementation #34

JWood48 opened this issue Aug 14, 2020 · 12 comments
Labels
enhancement New feature or request

Comments

@JWood48
Copy link

JWood48 commented Aug 14, 2020

Add an Interval implementation like:

data class Interval(val from: Instant, val to: Instant)
@imanushin
Copy link

I think think class can be extended:

data class Interval(override val start: Instant, override val endInclusive: Instant): ClosedRange<Instant> {
      init {
           require(start <= endInclusive) {
                 "Start should be before end, actual data: $this
           }
      }
}

Also I think we can also support sequences generation via implementing feature like this.

@ilya-g
Copy link
Member

ilya-g commented Aug 29, 2020

@JWood48, what are you going to represent with such a class? It's important to consider use cases to design the proposed type properly.

@jasonCodesAway
Copy link

This is very useful! Modeling a single point is time great, modeling a time range/interval is almost as common a use-case. Very handy for the overlap/intersection method in particular. Makes code readable/clean. Off the top of my head here are a couple popular libraries that do this:

  1. moment.js's luxon Interval
  2. joda time's Interval

@Whathecode
Copy link

Whathecode commented May 23, 2022

Intervals are not only useful for datetime, but any interval would make a great Kotlin language feature.

Therefore, I started a multiplatform generic interval project, kotlinx.interval. I use a similar approach as I did for C# intervals long ago. The operations a generic interval implementation needs are decoupled from the implementation. As such, when you want to support new types of intervals, all you need to provide is the set of operations.

Such virtual calls are probably not ideal when performance is concerned, but performance is not always an issue, and it is a good experiment to see what such a language-level API may look like. Furthermore, later language features may resolve performance issues. E.g., for .NET Core I used expression trees to have access to such "virtual" operators without any measurable impact.

Currently there is only the basis, and I haven't even introduced Interval<Instant, Duration> yet, but I'll start adding relevant operations (similar to those I added for a C# intervals) over time.

@JakeWharton
Copy link

It may behoove you to change the name / package of the project since it might give the wrong impression. Unless, of course, the goal is to contribute it verbatim (in which case you'd be wise to put such a statement in the readme and have a licensing/CLA plan in place). If you're just experimenting, using a proper package and library name seems fine.

@Whathecode
Copy link

Whathecode commented May 23, 2022

@JakeWharton I'm unaware of any trademark on the use of kotlinx, if that is what you are referring to. I in fact searched for exactly that prior to naming the package, and could not find any indication that it is. It's simply the most apt name; it's an std library extension. 🤷‍♂️ The package namespace of course makes it clear it's not official (io.github.whathecode.kotlinx.interval). That's what namespaces are for, no?

In terms of licensing, I think Apache 2.0 covers that exactly. Or am I overlooking something?

If Kotlin wants to adopt it, I'd feel privileged. But, it'd be more likely this may become a better more low-level integrated language feature, similar to ranges.

@Whathecode
Copy link

Update: I now included and published InstantInterval on Maven as part of the Whathecode/kotlinx-interval library.

@mgroth0
Copy link

mgroth0 commented Mar 18, 2024

I have a use case for this. I am rendering arbitrary timelines (which can be at any time scale), so naturally time ranges are a core part of the data model.

@Whathecode
Copy link

Whathecode commented Mar 18, 2024

@mgroth0 That's the exact use case why I originally wrote a generic interval implementation for C#. Also to facilitate mapping from pixel coordinates to time, e.g., on click/drag operations. And to help calculating intersections, etc. (You can see it in action here.)

The Kotlin library I linked to above adopts a similar design, which ended up working nicely for me, in Kotlin.

I didn't continue development for it since I no longer develop in Kotlin, and as a proof of concept it seems to work. But, I do see use cases for it in future projects I may pursue, so if you add issues for features you are missing, I can prioritize working on them in spare time. 🙂 I will also gladly accept PRs.

@mgroth0
Copy link

mgroth0 commented Mar 18, 2024

@Whathecode Thanks for sharing your work :)

I took a look at your implementation, and I think a generic implementation is not quite what I'm looking for. I cannot imagine needing a generic time interval and would find a concrete implementation more clean for my use case.

I am curious why time intervals would need to be a separate library. Maybe your use cases didn't quite fit with this library (e.g. you needed a generic implementation). But if we were to make a concrete implementation I think it might be small enough to fit in kotlinx-datetime, no?

@Whathecode
Copy link

Whathecode commented Mar 18, 2024

I am curious why time intervals would need to be a separate library.

I think intervals in general could even be part of the kotlin standard library, and of course, ranges are. But ranges are extremely limited in functionality.

When I made it for C#, it was in my "core" toolbox/base library. As I wrote 10 years ago, I used it heavily in my time line project (zooming, scrolling, iterating labels), but also to implement a generic binary search algorithm, general interpolation use cases, and value coercions in WPF. This requires operators like intersections, subtracting (and thus collections of intervals), open/closed ended bounds, etc.

(e.g. you needed a generic implementation)

You can either re-implement those operations for each concrete interval type, or you can have a generic solution like I pursue here, and those operations instantly become available on all concrete types (I simply haven't implemented that many yet in Kotlin ...). All that needs to be implemented for new types is a class which exposes some core operations used by the generic base class. That is why InstantInterval is only 9 LOC, but still benefits from any addition to Interval<T>.

@mgroth0
Copy link

mgroth0 commented Mar 18, 2024

Thanks for explaining. It does sounds to me like the generic hierarchy you wrote is essentially a much fancier version of the standard kotlin Range-like hierarchy. Sounds like a cool multi-purpose tool.

Maybe you could titrate out some of your core improvements and submit it as a PR to the Kotlin standard library as additions to the Range-like types? Or, given that they probably are hesitant accept PRs, you could write a KEEP proposal ?

I think that this thread is more focused on the specific need of a specialized datetime interval (which, now that I think of it, might benefit from implementing the standard ClosedRange or OpenEndRange interface). And I'd wager that most users of this library would prefer for a class such as this to be implemented in as small of a way as possible (concrete and without bloated features), at least the first iteration of it. I could be wrong, but maybe others should weigh in.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

9 participants