Description
One of the facets of Clash that I have long struggled with is the treatment of naming top-level ports. Ensuring that the port-naming of a top-level entity remains consistent with the entity's actual type is annoying at best and a horrible source of bugs at worst. For this reason, I quickly find myself yearning for better tools for treating the representations of top-level entities' ports as composable, first-class objects.
To this end I have written clash-port-name
(which, in hindsight, would probably be better called clash-port-rep
). While the newly-added README
and Haddocks should hopefully start to explain the "why" and "how", what I would like to discuss here is the future of this package. While I am happy to continue maintaining this as an external package, I suspect that the the problem that it solves is universal enough to potentially warrant eventual upstreaming of it or something like it. I am opening this ticket as a forum to have this conversation.
Things I would do differently
clash-port-name
is just one point in the design space. There are various things that I think could be improved in it:
- the "mode" notion of
Clash.PortRep.TH.genHasPortRep
could likely be cleaner - the library includes a generic deriving mechanism via
generics-sop
. Sadly, I have found that in practice this mechanism tends to be a very good trigger ofclash
compiler bugs and consequently I generally don't rely on it. This is sad because in general I think it is much more composable than the TH-based deriving mechanism. - while I think having both an explicit dictionary type (
Port
) and the typeclass is helpful, use of the typeclass is a bit less convenient as a result. Adding a few convenient class-centric accessors (e.g.toPortName :: forall a. HasPortRep a => a -> PortRep a
) may be a good idea. - it can still be awkward to modify the behavior of the derived instances as
Port
is both (a) an isomorphism between a Haskell type and a generic product, (b) an isomorphism between each of the factors and its external bit encoding, and (c) a naming for the factors. Ideally, you wouldn't need to rewrite (a) in order to affect (b) and (c). Thegenerics-sop
deriving mechanism is IMHO much better than TH in this regard.