#1 - 

Currently, DispatchQueue.after() takes an absolute time as the “after” 
parameter. This makes it hard to understand how to use it; you need to go 
digging through generated interfaces to find out what a ‘DispatchTime’ is and 
how you construct it (by getting the .now() and adding a DispatchTimeInterval 
using one of the easily-missable operator overloads, if you were wondering).

Here is what DispatchQueue.after looks like now:

public func after(when: DispatchTime, qos: DispatchQoS = .unspecified, flags: 
DispatchWorkItemFlags = [], execute work: @convention(block) () -> Void)

So to use it, you have to type:

DispatchQueue.main.after(when: DispatchTime.now() + .milliseconds(250))   { /* 
do stuff */ }

I don’t believe this is a great fit with the Swift API Guidelines. I believe 
the name “after” already implies that the time is relative, the argument label 
should be dropped, and that 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 (or better yet, modelling via 
an enum or boolean switch — see #2). Additionally, There are overloads with 
“wallTime” parameter labels which seem only to duplicate type information (the 
monotonic and walltime clocks are actually split at the type level) and could 
be more concise and readable. The principle is that, ultimately, you should 
just be able to write the above code like this:

DispatchQueue.main.after(.milliseconds(250)) { /* do stuff */ }

Or

DispatchQueue.main.at(DispatchTime.now() + .seconds(3)) { /* do stuff */ }

It’s not something you use all the time (like .sync/.async), but I find that 
whenever I do need it I’m frustrated by how needlessly complex it is to 
decipher and use. I would find these methods much more obvious, I could figure 
out how to use them much more quickly, and I think I’d remember how to use them 
more quickly.

—

#2 - 

Actually, while writing this down it’s becoming clearer and clearer that the 
idea to split DispatchTime (the monotonic clock) and DispatchWallTime (the wall 
clock) at the type level is probably a bad idea.

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. Perhaps we should look at replacing these clock 
variations with a more descriptive enum or boolean, rather than a separate 
type. For example:

struct DispatchTime {                       // replaces DispatchTime and 
DispatchWallTime
    let rawValue : dispatch_time_t
    let clock : Clock

    enum Clock { case monotonicClock; case wallClock }
}

This would not obsolete the discussion at the start about “after”. The name 
“after” still implies that I want something done at some duration relative to 
an absolute point in time (usually now).

Thoughts? 
There have been some really in-depth naming discussions on here recently, so 
I’m interested to hear what you make of it.

Karl
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to