Skip to content

Docstring pollution #137

@mikmoore

Description

@mikmoore

It appears that some Base functions extended to ::Quaternion arguments contribute their own docstrings that are near-verbatim repeats of the existing versions from Base. They don't provide any new information but they are printed via >help? anyway, cluttering the output. It doesn't seem sustainable for every package that adds a new type to document semantically-unchanged functions just for the sake of saying that they do exactly what the docstrings already said they do. If anything, this makes them more confusing (in addition to the clutter) because the user may try to spot the difference.

Other packages don't seem to take this approach. Base doesn't feel the need to document that sign works on Rational specifically, nor does DualNumbers feel the need to do the same for Dual. For that matter, Quaternions doesn't (yet) feel the need to do this for the majority of its extended functions (arithmetic, ==, exp, sin, etc.).

Offending functions at the present time appear to be:

  • real -- only adds a "See also: imag_part, quat" to the real(::Quaternion) method
  • conj
  • sign -- we don't even provide a custom implementation
  • inv -- proposed by Update around inv #133

At least the real docstring adds literally something, if only references. I can't see why quat is relevant there, and it's already linked from Quaternion which seems a more reasonable place. Discoverability of imag_part is important (arguably, field access is fine) but I would argue imag is a much better place to find it than real. That said, I wouldn't be excited to clutter that docstring either. I despise "not implemented" errors, but this is more of a "the operation is ill-defined for this type" error so I could be convinced to do something like

Base.imag(::Quaternion) = throw(ArgumentError("`Base.imag(::Quaternion)` is not defined. See Quaternions.imag_part`."))

to help discoverability. I vaguely recall there were "error hints" being considered for Base at some point (which seems like an even better solution), but I don't know if those ever became a thing.

It's unfortunate that round does appear to need ::Quaternion-specific documentation for the imaginary-part rounding modes, but I don't see a way around that. The only thing I would have considered (breaking change now, technically, although perhaps not in any actual use) would be that the imaginary parts all share a rounding mode (in which case we would have followed the round(::Complex,...) semantics). It's not easy to imagine that many people have needs to round imaginary parts differently from each other, so I wouldn't have hated making users roll-their-own for that level of control. It doesn't benefit from being part of Base.round anyway, because no other version accepts 4 RoundingModes. But this is a matter for a separate issue and not one that I feel strongly about since it'd be breaking to remove that functionality.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions