Recently, I have been playing around with a little units of measurement
system in D. As this topic has already been brought up quite a number of
times here, I thought I would put my implementation up for discussion here.
When this topic came up previously, it has been proposed to include
units support with Phobos, and thus I have merged my work into my Phobos
fork. Please note, however, that even if we should come to the
conclusion that we really want something like this in Phobos, this is
not a formal review request yet. There are still a couple of items left
on my to-do list, but I'd like to get some feedback first.
Anyway, here is a link to the code:
https://github.com/klickverbot/phobos/tree/units (std/units.d and
std/si.d). Also, I put up a build of the DDoc output at
http://klickverbot.at/code/units/std_units.html resp.
http://klickverbot.at/code/units/std_si.html.
A couple of notes:
- DDoc emits the documentation for some template functions twice,
once for the template, and once for the eponymous function itself (bug
4107). Is there a workaround for this issue? This also affects, amongst
others, the docs for std.container.
- The documentation could use quite a bit of work in general, I'd be
happy about any suggestions.
- In a previous discussion, Andrei brought up the topic of categorical
types implemented as quantities without any operators defined. An extra
template parameter to disable arithmetic could easily be added to
Quantity, if deemed useful. However, I think that using an units system
to define them is pretty much overkill, as neither conversions nor
arithmetic operations would be used.
- Currently, »auto« returns are used quite liberally for things that
should »just work«, e.g. just mirror underlying value type operations.
This has the advantage of keeping code and function signatures readable,
but obviously also hides the real type from the user. Any other thoughts
on this?
- I have followed the general Phobos guidelines to use template
constraints where they would logically belong (and where they are
actually implementable without hacks due to DMD bugs), instead of, say,
static asserts or just letting instantiation fail. However, this way,
you lose the ability to specify helpful error messages (which is
somewhat important as the underlying types can be quite complex), and
the DDoc documentation is cluttered up somewhat.
- The helper functions for creating instances of new unit types
(scale, affine, ...) are currently template functions taking an instance
of the unit they manipulate as actual argument. This is only for
»historical« reasons really, would it be cleaner to use just templates?
- If this library should really be included into Phobos eventually, I
am not quite sure about the right organization of the code. While I
think that std.units would be a good fit for the core module, I am not
sure how modules containing definitions of actual physical units and
other related code (e.g. CODATA values for the natural constants) should
be organized. Putting them directly into std.* is certainly a bad idea,
as it would add even more clutter to the already crowded (overcrowded,
in my opinion) package. What about a new std.physical (or similar) package?
David