clash-compiler icon indicating copy to clipboard operation
clash-compiler copied to clipboard

Expose `Clash.Class.Counter` methods

Open gergoerdi opened this issue 1 year ago • 6 comments

Currently, functions like countMin and countSuccOverflow are marked in the documentation as internal implementation details that shouldn't be used by client code. But they (or something similar) would be very useful in a lot of cases where we only want to count "once" and then do something else.

I realize overflow detection can be achieved "on the outside" by adding one more bit to the counter, without access to these functions by doing something like:

let ((bitCoerce @(Index 2) -> overflow), x') = countSucc (0, x)
in x' <$ guard (not overflow)

but this is not really readable (it could be improved a bit if we had a Counter Bool instance). And I'm not sure what similar trick could apply to countMin.

gergoerdi avatar Jul 11 '23 09:07 gergoerdi

I think the API I would prefer is one that consists of countMin, and countSuccChecked :: (Counter a) => a -> Maybe a. Then both countSucc and countSuccOverflow are trivially recoverable:

countSucc = fromMaybe countMin . countSuccChecked
countSuccOverflow = maybe (True, countMin) (False,) . countSuccChecked

gergoerdi avatar Jul 11 '23 09:07 gergoerdi

The nice thing about (Bool, a) is that you don't need a branch to determine the overflowed number. While this is a bit of a micro-optimization, I do feel it's the right thing to do.

How about simply moving the internal functions public? I don't think we discovered any downsides to the private API so far, so as far as I'm concerned it's fine as it is.

martijnbastiaan avatar Jul 12 '23 18:07 martijnbastiaan

Are there any plans to implement this?

gergoerdi avatar Oct 31 '23 10:10 gergoerdi

Would simply exposing the internal functions be okay? In that case, it's easily done.

martijnbastiaan avatar Nov 03 '23 14:11 martijnbastiaan

We could also add an instance for Counter a => Maybe a And then you can get your interface with:

countSuccChecked :: Counter a => a -> Maybe a
countSuccChecked = countSucc . Just

leonschoorl avatar Nov 09 '23 16:11 leonschoorl

Also I think we should probably add instances for Bool and Bit

leonschoorl avatar Nov 09 '23 16:11 leonschoorl

@gergoerdi I'd be happy to move this forward; could you comment on my replies?

martijnbastiaan avatar Mar 09 '24 14:03 martijnbastiaan

I'm happy with the suggested ways of doing thidls, because the Maybe instance would give me what I need.

gergoerdi avatar Mar 10 '24 13:03 gergoerdi

See https://github.com/clash-lang/clash-compiler/pull/2692

martijnbastiaan avatar Mar 10 '24 16:03 martijnbastiaan