Open jackfirth opened 8 years ago
Let me make sure I know what you mean. Do you mean that we just provide the existing resolvers plus a constructor of (gap-resolver? overlap-resolver? -> offset-provider?)
? So users can use the existing ones and create new offset resolvers from the existing gap/overlay resolvers, but they can't create new ways of resolving gaps and overlaps?
One one hand, I like this simplification, but it would effectively mean that we don't really expect anything other than moment
to implement gen:moment-provider
-- since it's really the provider's responsibility to use the offset resolvers. Of course, if you don't know what a resolver's signature is, then there's no way to use it. Possibly other moment providers could be implemented in terms of moment
, but this change would disallow any that aren't. That said, I can't really think of why anyone would want to implement gen:moment-provider
.
By the way, I'm currently working on moving the Gregor code into a new tree while cleaning it up a bit. The biggest change is that I'm simplifying the internal representations of the basic data types. For example, instead of the date
struct containing a YMD
struct and a Julian date number, it will simply contain a year, a month, and a day. That is, it will essentially be what the YMD
struct is now.
More to the point, though, I'm also making two changes to resolvers:
(or/c moment? #f)
but instead (or/c (integer-in -64800 64800) #f)
-- which is to say, an optional UTC offset in seconds. Obviously this will be invisible to clients if we make resolvers opaque -- which goes to your point about being able to change the API.current-offset-resolver
and current-arithmetic-offset-resolver
. The former defaults to resolve-offset/raise
and the latter resolve-offset/retain
. The former is used as the default value of any #:resolve-offset
parameter except in date arithmetic functions, where the latter is used instead.Re: clarification - I believe that's what I mean. Let me be more explicit: I would create a module defining gap-resovler
, overlap-resolver
, and offset-resolver
structs, along with defining the existing offset resolvers, and constructors of the form (gap-resolve-proc/c -> gap-resolver?)
, (overlap-resolve-proc/c -> overlap-resolver?)
, and (gap-resolver? overlap-resolver? -> offset-resolver?)
. These constructors can handle adapting in the future in the case of changes to the resolver signatures. In addition, the module would create each of the existing resolvers (causing them to be created without being wrapped in contracts).
This does mean only Gregor is capable of using the resolvers, meaning nobody can implement gen:moment-provider
. I can't think of a decent reason for implementing that either - as I understand it, the primary purpose of the generic interfaces is for interop with Racket's date data structures. In this case, Gregor would be providing the implementations of these interfaces for interop. In the case of some other third-party date/time package, maybe some sort of gregor/provider
library for exposing the necessary internals? With suitable documentation that the exact interfaces are less stable than the rest of Gregor.
Offset/gap/overlay resolvers are functions with a particular kind of signature. If the API changes in a way that new parameters need to be added, removed, or moved around, all client code using custom offset resolvers breaks. The details of a resolver's implementation are only useful to Gregor users constructing their own resolvers - most users don't need anything beyond the already provided ones. Instead Gregor could provide constructors that accept the resolver functions and produce opaque resolver values instead. This has a number of advantages:
This is something that bit me in the lens package a while back. It would be tricky to add this to Gregor in a backwards compatible way, but it could be worth it. Let me know what you think!