-
Notifications
You must be signed in to change notification settings - Fork 22
Open
Labels
Milestone
Description
Since long, I wanted to simplify the type signature of initClock from
initClock ::
cl ->
m (MSF m () (Time cl, Tag cl), Time cl)to
initClock ::
cl -> MSF m () (Time cl, Tag cl)There are several reasons for the more complicated type signature:
- The extra
maction can be used to initialise a resource. (Although this is usually the least concern, the initialization could also happen upon the first tick, or be done with aReaderTnewtype.) - The
maction is used to generate an initial time. This has several advantages:- It is simpler to refer to the time since clock initialization.
- If the initial time was the first timestamp, then the first time difference would always be 0. With a dedicated initial time, we can often have an interval > 0 (although not always, e.g. in pure clocks).
- Sometimes we have no good tag value at the initialization, and one would have to artificially add one (or wrap the tag in a
Maybe)
But there are also downsides to this complicated type signature:
- It's complicated to explain and understand. It's extra boiler plate when writing a new clock, you now have to measure the time in the running clock and also at initialization. Overall, it's not conceptually nice.
- We always have to throw away one initial time when scheduling several clocks. This is an arbitrary choice which can lead to imprecision. If
initClockdirectly returns a running clock, we could simply merge the timestamp streams.
With #299 (automata) there would be a new downside: The state of the running clock is typically not known statically (because it is hidden behind a monadic action), therefore GHC cannot optimize the whole Rhine further after clock erasure. This causes a performance degradation that is not easily justifiable.
Overall I believe that after #299, a serious attempt at simplification should be made.