Continuing the discussion from Upcoming Cmdliner 2.0 changes that need your attention:
The loss of deep pattern matching can be a pain. For example, experienced it with PrintBox – it exposes the main type as a view which only works with shallow matching.
printbox type view
This is a problem specifically because of the the design of PrintBox where backends and extensions are whole separate packages. Would be fine to keep PrintBox.t
abstract by default, but opt-in concrete for backends and extensions.
1 Like
Right, I’m sure exceptions exists. But the thing I did in cmdliner was particularly stupid, namely in 2011 I defined:
type 'a conv = 'a parser * 'a formatter
There is no interest in pattern matching here… unless there is. While sifting through package failures I saw many cmdliner users that were reusing bits of the predefined converters so they would write:
let parse, _ = Arg.int32 in
…
Which is totally natural – I’m to blame for having exposed a pair – but provides no gain if you compare it to the silently recommended way since 2017:
let parse = Arg.conv_parser Arg.int32
The next error was likely to wait 8 more years to make it abstract, though I didn’t try to track down if people using pairs wrote the code before 2017.
But I still think that in most of my libraries I’d be pressed to find an example where exposing concrete type to “regular” users of the library makes sense. And I know a few other were I did and I will regret it, e.g. (Vg.Font.t
or Vg.Path.outline
).
There are also a few other cases where exposing the representation is useful, but the all the ones I can think of are for some sort of advanced usage like writing a new backend for processing a representation. In this case I think it’s better to convert with a representation type exposed in a T.Private
or T.Repr
module. For example Vgr.Private
or Jsont.Repr
or Htmlit.El.Low
– which shows that I have been highly inconsistent in naming these modules :–)
3 Likes