> On 13 Jul 2016, at 18:47, Anthony Chivetta via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
> 
>> On Jul 13, 2016, at 9:18 , Karl via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>> nuances about the clock (basically, whether or not it pauses during system 
>> sleep) are edge-cases which can be handled for the majority of users with a 
>> sensible default value
> 
> I’m going to stay out of the naming part of the conversation for the moment 
> and just address this point…
> 
> I disagree strenuously: it’s a super important distinction that is frequently 
> the cause of subtle but bad bugs!
> 
> Lets start with the fact that you (presumably not the novice user you 
> describe below) actually got the difference between the two clocks wrong.  
> Here’s the current behavior (on Darwin, not sure what Linux currently 
> implements):
> 
>   - DispatchTime is a clock that only advances forward and tracks the amount 
> of time the computer is awake.
> 
>   - DispatchWillTime is a clock that tracks as a UTC clock would, generally 
> moving ahead during sleep, but is *not* monotonic.  It can move forward, 
> backward, upside down, whatever it wants.  And frequently it will.
> 

Yeah I know, I don’t think I got the clocks wrong. I forgot that the UTC clock 
can move around, but yeah, of course it can; fair enough.

> And this stuff is hard: if you are writing a tea timer app and you pick 
> either of these, you have a bug.  DispatchTime, the bug is that if the user 
> locks their device and it falls asleep the alarm won’t fire upon wake.  
> DispatchWallTime, if the device realizes its clock is ahead or behind the 
> “real” time the elapsed duration won’t be what you expect.  (Should we have a 
> third that works for the tea timer? Absolutely…)
> 

Do you think that is adequately expressed in the API? 

I don’t, and I believe the current system of type-based overloads is not a good 
way to ensure people don’t accidentally use the wrong one. Maybe we should 
rename the methods which take each type to make it more of a conscious decision 
(I’m happy with that, because in that case we definitely have reasonable 
default values 😎)

> So, what’s the sensible default you had in mind that won’t fail for a large 
> portion of use cases?  Safety is an important design point in an API surface 
> and making these distinctions clear to developers is absolutely critical to 
> achieving that goal.

The default clock depends on the context of what you’re doing. If I’m using 
DispatchQueue.after, I would say the monotonic clock is a reasonable default. 
Typically you’re going to be scheduling short fire-once things like performing 
an animation after a second or two (at the most). In that case, system sleep 
isn’t an issue - even on iOS where the user can lock the screen at any moment; 
your long-running alarm that crosses sleep events will still fire, it just 
won’t fire *immediately* upon wake. iOS in general makes a point not to offer 
guarantees about what will happen to your app if it ever goes in to the 
background, and offers alternative backgrounding and local notification APIs 
instead.

And again, if you considered it and really need that timer to fire immediately 
if the system dozed off for a little bit in-between, that’s available as an 
explicit consideration.

I could see how there’s an argument for a third type of timer; it’s obviously a 
complex topic, and we should provide a reasonable default if possible; even if 
that’s a platform-specific alias.

> 
> (Of course, Foundation.Timer gets all of the above horribly wrong, IMHO.  We 
> should fix that too…)
> 
>>  (the monotonic and walltime clocks are actually split at the type level)
> 
> DispatchTime is not a monotonic clock.  At least, not in the POSIX sense.  So 
> let’s not call it that.  (Linux’s failure to implement POSIX correctly 
> notwithstanding.)
> 
>> Novice users are not going to understand what’s going on here - I expect 
>> most of them to default to the more generic-sounding “DispatchTime” without 
>> any idea of the implications of this.
> 
> If that’s the case, that’s a good argument for forcing users to make the 
> choice in an even more obvious and explicit way.  Not making it easier to use 
> one or the other when they’ll likely get it wrong.
> 

Yes, that was the motivation behind saying we should merge them - while writing 
it, it feels like you’re on a bit of a tightrope - one slip and this code could 
mean something very different.

Karl

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

Reply via email to