Proposal: Conforming NSDate to Comparable


(Chris) #1

Hello Swift Developers,

I think it's a good idea to conform NSDate to the Comparable protocol, so
instead of using:

if someDate.compare(today) == .OrderedAscending { }

Developers can easily compare using compare dates using comparison
operators:

if someDate < today { }

In my opinion, the code is still readable if developers use comparison
operators on NSDates.

Here's a quick implementation from my swift-corelibs-foundation fork:
https://github.com/chrisamanse/swift-corelibs-foundation/commit/3c4eff643c5271de5bec2461798051347be13916

Thank you.


(Brent Royal-Gordon) #2

I think it's a good idea to conform NSDate to the Comparable protocol, so instead of using:

if someDate.compare(today) == .OrderedAscending { }

Developers can easily compare using compare dates using comparison operators:

if someDate < today { }

I would also suggest we add Strideable, which would allow you to add and subtract NSTimeIntervals, plus subtract two NSDates to get the NSTimeInterval between them.

https://gist.github.com/brentdax/11b3275424d0833cfd99

···

--
Brent Royal-Gordon
Architechies


(Philippe Hausler) #3

In all that seems like a pretty reasonable concept. Foundation is going to be using the same evolution template as the rest of the Swift evolution process; could you fill out a draft of that and I can help campion your proposal to the component owner for NSDate and we can see how this will fair with the rest of the Darwin side of things.

As you can probably guess; operators are not taken lightly since they exist in the global scope and it is good to consider the ramifications of what even something as simple as comparison of dates has in general.

···

On Dec 5, 2015, at 3:36 PM, Chris Amanse via swift-corelibs-dev <swift-corelibs-dev@swift.org> wrote:

Hello Swift Developers,

I think it's a good idea to conform NSDate to the Comparable protocol, so instead of using:

if someDate.compare(today) == .OrderedAscending { }

Developers can easily compare using compare dates using comparison operators:

if someDate < today { }

In my opinion, the code is still readable if developers use comparison operators on NSDates.

Here's a quick implementation from my swift-corelibs-foundation fork: https://github.com/chrisamanse/swift-corelibs-foundation/commit/3c4eff643c5271de5bec2461798051347be13916

Thank you.
_______________________________________________
swift-corelibs-dev mailing list
swift-corelibs-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-corelibs-dev


(Pierre Habouzit) #4

-Pierre

···

On Dec 5, 2015, at 3:51 PM, Brent Royal-Gordon via swift-corelibs-dev <swift-corelibs-dev@swift.org> wrote:

I think it's a good idea to conform NSDate to the Comparable protocol, so instead of using:

if someDate.compare(today) == .OrderedAscending { }

Developers can easily compare using compare dates using comparison operators:

if someDate < today { }

I would also suggest we add Strideable, which would allow you to add and subtract NSTimeIntervals, plus subtract two NSDates to get the NSTimeInterval between them.

https://gist.github.com/brentdax/11b3275424d0833cfd99

NSDate (and dates/timestamps in general) is a poor choice for Strideable, because, DST.
A Calendar using this interface for a repeating event would be broken using this. Or you would break anyone who really wants to iterate every fixed 86400 seconds.

-Pierre


(Lily Ballard) #5

That's not a problem with Strideable. Making NSDate conform to
Strideable does nothing to encourage people as treating 86400 seconds as
being equal to 1 day. NSDate already has methods for measuring and
offsetting, the only difference with conforming to Strideable is the
name.

-Kevin Ballard

···

On Sat, Dec 5, 2015, at 07:10 PM, Pierre Habouzit via swift-evolution wrote:

NSDate (and dates/timestamps in general) is a poor choice for Strideable,
because, DST.
A Calendar using this interface for a repeating event would be broken
using this. Or you would break anyone who really wants to iterate every
fixed 86400 seconds.


(David Waite) #6

Both NSDate nor NSTimeInterval represent instants in time, not time within a calendaring system. Assuming 86400 seconds is a calendar day is a bug, same as assuming 365 days is a calendar year. That they are using the wrong time primitive doesn’t seem to be affected by whether NSDate implements Strideable or not.

(That there isn’t a comprehensive time system is another problem)

-DW

···

On Dec 5, 2015, at 8:10 PM, Pierre Habouzit via swift-evolution <swift-evolution@swift.org> wrote:

NSDate (and dates/timestamps in general) is a poor choice for Strideable, because, DST.
A Calendar using this interface for a repeating event would be broken using this. Or you would break anyone who really wants to iterate every fixed 86400 seconds.

-Pierre


(Brent Royal-Gordon) #7

NSDate (and dates/timestamps in general) is a poor choice for Strideable, because, DST.
A Calendar using this interface for a repeating event would be broken using this. Or you would break anyone who really wants to iterate every fixed 86400 seconds.

Sometimes you want to add an interval of time according to the user’s clock; NSTimeInterval/NSDate math will do the wrong thing there. But sometimes you just want to get an NSDate thirty seconds from now, and for all you care the user can fly to Timbuktu during that time. That’s the sort of thing I’m using this for:

  // Don’t add to undo manager if we’re too close to the last change
  guard now - lastChangeDate > undoCoalescingTimespan else { return }

It is simply not the case that *all* arithmetic on NSDates is incorrect unless it involves NSCalendar and NSDateComponents.

···

--
Brent Royal-Gordon
Architechies


(Chris) #8

Here's a draft of the the proposal:
https://gist.github.com/chrisamanse/2ab39e31e93d5c11d0b5

···

On Sun, Dec 6, 2015 at 7:52 AM Philippe Hausler <phausler@apple.com> wrote:

In all that seems like a pretty reasonable concept. Foundation is going to
be using the same evolution template as the rest of the Swift evolution
process; could you fill out a draft of that and I can help campion your
proposal to the component owner for NSDate and we can see how this will
fair with the rest of the Darwin side of things.

As you can probably guess; operators are not taken lightly since they
exist in the global scope and it is good to consider the ramifications of
what even something as simple as comparison of dates has in general.

On Dec 5, 2015, at 3:36 PM, Chris Amanse via swift-corelibs-dev < > swift-corelibs-dev@swift.org> wrote:

Hello Swift Developers,

I think it's a good idea to conform NSDate to the Comparable protocol, so
instead of using:

if someDate.compare(today) == .OrderedAscending { }

Developers can easily compare using compare dates using comparison
operators:

if someDate < today { }

In my opinion, the code is still readable if developers use comparison
operators on NSDates.

Here's a quick implementation from my swift-corelibs-foundation fork:
https://github.com/chrisamanse/swift-corelibs-foundation/commit/3c4eff643c5271de5bec2461798051347be13916

Thank you.

_______________________________________________
swift-corelibs-dev mailing list
swift-corelibs-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-corelibs-dev


(Tony Parker) #9

Hi Chris,

Thanks for bringing this idea to the list.

Is NSDate really the only thing that we want to conform to comparable, or is there a set of classes which should do so? I’d like to think about the larger set of consequences here (and if possible, deal with one coherent answer for all of Foundation rather than do these classes one at a time).

- Tony

···

On Dec 5, 2015, at 3:36 PM, Chris Amanse via swift-corelibs-dev <swift-corelibs-dev@swift.org> wrote:

Hello Swift Developers,

I think it's a good idea to conform NSDate to the Comparable protocol, so instead of using:

if someDate.compare(today) == .OrderedAscending { }

Developers can easily compare using compare dates using comparison operators:

if someDate < today { }

In my opinion, the code is still readable if developers use comparison operators on NSDates.

Here's a quick implementation from my swift-corelibs-foundation fork: https://github.com/chrisamanse/swift-corelibs-foundation/commit/3c4eff643c5271de5bec2461798051347be13916

Thank you.
_______________________________________________
swift-corelibs-dev mailing list
swift-corelibs-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-corelibs-dev


#10

Seems to me that anything with `-compare:` could conform to Comparable. The list, however, is surprisingly short, and half bridge over to native Swift types that are already Comparable:

- [NSDate compare:]
- [NSIndexPath compare:]
- [NSNumber compare:]
- [NSString compare:]

Looks like NSIndexPath may be the only other contender.

Stephen

···

On Dec 6, 2015, at 11:47 AM, Tony Parker via swift-evolution <swift-evolution@swift.org> wrote:

Hi Chris,

Thanks for bringing this idea to the list.

Is NSDate really the only thing that we want to conform to comparable, or is there a set of classes which should do so? I’d like to think about the larger set of consequences here (and if possible, deal with one coherent answer for all of Foundation rather than do these classes one at a time).

- Tony

On Dec 5, 2015, at 3:36 PM, Chris Amanse via swift-corelibs-dev <swift-corelibs-dev@swift.org <mailto:swift-corelibs-dev@swift.org>> wrote:

Hello Swift Developers,

I think it's a good idea to conform NSDate to the Comparable protocol, so instead of using:

if someDate.compare(today) == .OrderedAscending { }

Developers can easily compare using compare dates using comparison operators:

if someDate < today { }

In my opinion, the code is still readable if developers use comparison operators on NSDates.

Here's a quick implementation from my swift-corelibs-foundation fork: https://github.com/chrisamanse/swift-corelibs-foundation/commit/3c4eff643c5271de5bec2461798051347be13916

Thank you.
_______________________________________________
swift-corelibs-dev mailing list
swift-corelibs-dev@swift.org <mailto:swift-corelibs-dev@swift.org>
https://lists.swift.org/mailman/listinfo/swift-corelibs-dev

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution


(Chris) #11

In addition to what Stephen said, it seems that it would be good to use
comparison operators on objects that can be represented or visualized as a
value like NSDate, NSIndexPath, and NSNumber. Although, using comparison
operators on NSString or Strings would not be much clear to a reader of the
code since there are lots of ways that we can compare strings, such as
character count, or alphabetical order while being case insensitive, etc.

Chris

···

On Mon, Dec 7, 2015 at 1:48 AM Stephen Celis <stephen.celis@gmail.com> wrote:

Seems to me that anything with `-compare:` could conform to Comparable.
The list, however, is surprisingly short, and half bridge over to native
Swift types that are already Comparable:

- [NSDate compare:]
- [NSIndexPath compare:]
- [NSNumber compare:]
- [NSString compare:]

Looks like NSIndexPath may be the only other contender.

Stephen

On Dec 6, 2015, at 11:47 AM, Tony Parker via swift-evolution < > swift-evolution@swift.org> wrote:

Hi Chris,

Thanks for bringing this idea to the list.

Is NSDate really the only thing that we want to conform to comparable, or
is there a set of classes which should do so? I’d like to think about the
larger set of consequences here (and if possible, deal with one coherent
answer for all of Foundation rather than do these classes one at a time).

- Tony

On Dec 5, 2015, at 3:36 PM, Chris Amanse via swift-corelibs-dev < > swift-corelibs-dev@swift.org> wrote:

Hello Swift Developers,

I think it's a good idea to conform NSDate to the Comparable protocol, so
instead of using:

if someDate.compare(today) == .OrderedAscending { }

Developers can easily compare using compare dates using comparison
operators:

if someDate < today { }

In my opinion, the code is still readable if developers use comparison
operators on NSDates.

Here's a quick implementation from my swift-corelibs-foundation fork:
https://github.com/chrisamanse/swift-corelibs-foundation/commit/3c4eff643c5271de5bec2461798051347be13916

Thank you.
_______________________________________________
swift-corelibs-dev mailing list
swift-corelibs-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-corelibs-dev

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution