Closed hmontero1205 closed 2 years ago
Maybe we can make the units functions?
ms :: Word64 -> SSMTime
where SSMTime
is some appropriate representation of time.
after (ms 500) r 10
after (s 2) y x
Looks a little less chunky, and there's no need to annotate it with any type
@Rewbert that would probably be more idiomatic, but is there any way to make it postfix?
Unfortunately not. We can only write prefix & infix functions.
Would it make sense to add SSMTime as a valid variable type? I imagine there could be use cases for dynamically computing sleep/assignment time.
Hm then maybe it makes sense just keeping it as Exp Word64
, since that already supports that.
I think maybe the easiest thing to do (least amount of work) is to keep it as a Exp Word64
and have that be some unit of time (e.g ms), and then provide helper functions ms :: Exp Word64 -> Exp Word64
to convert a 5
to 5000
.
If we want to generate more specific code like your initial suggestion we probably want to add a dedicated time type. However, we would then replicate some functionality that SSMExp
already implements.
Unfortunately not. We can only write prefix & infix functions.
I played around briefly with the PostfixOperators
language extension, but that only works with symbols.
But you're right, doing prefix is much easier. If we can decide on a neat infix operator we could do something like:
(#) = flip ($)
x = 4 # ms
Purely cosmetic, but yeah definitely neater than my suggestion. Are there existing symbolic suggestions for a flipped $
operator?
I would be hesitant to define ms
as (* 1000)
(lifted to SSMExp
) since that is predicated on the base resolution being fixed at microseconds. Doing someting like after 1 v e
should not be well-defined since that base resolution of the time is platform-dependent.
Ultimately, I do think there should be a dedicated time type in the language, to force the user to specify the time units if anything. Under the hood this will be type aliased to u64
but that shouldn't be visible to the user. But that will certainly involve additional cases to the way we evaluate SSMExp
, and some helpers for lifting arithmetic operators to work on time values.
Ah, the "canonical" flipped $
operator is &
: https://hackage.haskell.org/package/base-4.8.0.0/docs/Data-Function.html
John and I chatted a bit more and we think a reasonable compromise would be to do something like changing the signature of after
to after :: SSMTime -> Ref a -> Exp a -> SSM ()
, where SSMTime
s are constructed like Sec <Word64-val>
or MilliSec <Word64-val>
. SSMTime's wouldn't be introduced to the frontend typesystem to avoid redundancy. This method would also avoid base resolution being done too high in the compiler stack -- we simply pass a SSMTime to a platform's codegen and let it do the conversion.
Opening for visibility in case anyone has anything else to add!
John and I discussed having dedicated time types for the frontend for specifying time durations in statements like
after
.. something like(5 :: Ms)
which then generates5 * SSM_MILLISECONDS
.