mpusz / mp-units

The quantities and units library for C++
https://mpusz.github.io/mp-units/
MIT License
1.09k stars 87 forks source link

Refactor file system layout for systems #249

Closed mpusz closed 3 years ago

mpusz commented 3 years ago

The current systems' layout is not the most user-friendly. Let's take SI for an example: https://github.com/mpusz/units/blob/master/src/include/units/physical/si/si.h. Base dimensions and derived dimensions are split to separate directories which might be clean but is not the best interface for the users if they want to include each quantity kind separately (we even officially discourage people to use si.h until modules arrive). This might be nice and clean for domain experts but will be hard to use for a casual C++ developer:

#include <units/physical/si/derived/volume.h>
#include <units/physical/si/base/time.h>
#include <units/quantity_io.h>
#include <iostream>

using namespace units::physical;

constexpr auto foo(Volume auto v, Time auto t)
{
  return v / t;
}

int main()
{
  using namespace si::unit_constants;
  std::cout << foo(220 * m3, 15 * s) << "\n";
}

Should we just put all the headers to the si subdirectory together with:

or maybe there is a better option.

Ideas are welcomed 😉

johnmcfarlane commented 3 years ago

Consider treating subdirectories like namespaces, i.e. for avoiding collision, not for generating dichotomies. (That Python video applies equally well to C++.)

IOW, I would choose <units/si.h> unless there's more than one header called si.h (or some other really compelling reason to do otherwise).

mpusz commented 3 years ago

Hi @johnmcfarlane :-) Thanks for the feedback. I agree that keeping namespaces and directories consistent is a good point here. I am just a bit worried that things like si/constants.h will disappear among hundreds of quantities defined by the SI system.

mpusz commented 3 years ago

On the other hand, I do not think that <units/si.h> is a good solution. I would prefer to keep units directory for a generic library framework. Who knows, maybe we will only standardize the framework at the first shot, and systems definitions will follow later?

As systems are extensions, and there may be separate vendors providing their own system definitions I think they should go to some dedicated subdirectory. We may create <units/system/si> or <units/system/physical/si>.

I chose to add a physical group to gather all the systems that comply with the regular "physical" ISQ (https://mpusz.github.io/units/glossary.html#term-International-System-of-Quantities) rules of the world (opposed to for example natural unit systems). All such systems share generic quantities/dimensions definitions (https://github.com/mpusz/units/blob/master/src/include/units/physical/dimensions.h, https://github.com/mpusz/units/blob/master/src/include/units/physical/dimensions/speed.h) which does not necessary imply SI right away.

gitsbi commented 3 years ago

I do think that keeping folders and namespaces aligned is a good practice in general, but I would not stick to it slavishly. If it makes sense to divert from that, then that's what the freedom C++ grants us is there for.

Regarding your concrete example: I think just leaving out derived/ and base/ from the include path would help. When defining volumetric flow as a unit, users do not care whether the units involved are base units or derived ones.

This becomes even more obvious when using voltage and current: The SI system makes current a base unit, and voltage a derived one, but if this would have been decided the other way around back then, it wouldn't have any impact on the our understanding of physics today at all. IME, electrical engineers generally see them as equally fundamental and do not care which one is considered more fundamental by SI.

To conclude my opinion: While there is a distinction between these two, I don't think it makes much difference in practice. It might be useful to be able to determine whether some unit is a base one (although I struggle to come up with a concrete example for what this might be needed). But the library should not burden users to remember the difference when they create their own units.

mpusz commented 3 years ago

It seems that I closed this one too early. After thinking about it a bit more it seems that we need a bigger clean up to be more correct and technical (for ISO standardization needs). This is why I am going to:

mpusz commented 3 years ago

Please vote on this one if you think we should put all systems in system subdirectory. For example:

#include <units/system/isq/si/speed.h>
mpusz commented 3 years ago

For now, we do not define all quantities and units defined in the SI and ISO 80000. So there will be even more headers under si.

Please vote on this one if you think we should structure quantities in subdirectories defined by the ISQ (https://en.wikipedia.org/wiki/ISO/IEC_80000#Overview):

For example:

#include <units/isq/si/space_and_time/speed.h>
mpusz commented 3 years ago

Please vote on this one if you think that we should introduce domain-specific header files that will aggregate all quantities of each domain: