Skip to content

Simplify initClock? #304

@turion

Description

@turion

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 m action 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 a ReaderT newtype.)
  • The m action 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 initClock directly 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.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions