Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expand this proposal to include Unit-related math and utility functions #2

Open
TheOneTheOnlyJJ opened this issue Oct 21, 2024 · 6 comments
Labels

Comments

@TheOneTheOnlyJJ
Copy link

This issue is more of a discussion starter, not a final suggestion.

The use cases for a Measure object stretch far beyond the currently stated use cases and goals. Constraining the Measure object/API (we could call it an API, right?) to strictly these use cases greatly limits the potential for a standardized measuring API on the web. It makes sense, given that taking input and handling units and measurements is common in many applications.

I argue that inspiration can be taken from the best current state of the art regarding units and measurements on the web.

Among the libraries I've personally explored, is UnitMath.
The notable features offered by UnitMath and not this proposal are, among others:

While not all features offered by this library (or others) should necessarily be included in a standard web API, there is experience in these libraries that could be applied or considered in this proposal to make for a better spec.

I invite @ericman314, the creator of UnitMath, to leave his thoughts here.

@ericman314
Copy link

This is going to be a bit biased coming from the creator of UnitMath, but here we go:

  • Unit conversion and arithmetic -- Definitely agree that this would be very useful as part of the proposal, but there's some question as to how far you take it. Addition and subtraction between similar units is straightforward, and would probably cover most use cases. But do you also allow multiplication, division, and exponentiation? This can result in compound units like kilometers / hour. Being able to convert between that and miles / hour is definitely useful, but at the expense of added complexity of the API needing to understand compound units. Converting between volumes and mass is common in recipes, and this could be done by multiplying or dividing by a density.
  • Unit splitting -- Converting between decimal degrees and degrees/minutes/seconds is a classic use case here, as well as hours/minutes/seconds. Another use case could be scaling the ingredients of online recipes up or down, and representing the result in cups + tablespoons + teaspoons, etc., for locales that use those measurements.
  • Unit simplification -- This is actually much harder than it seems. The "correct" way to simplify units can depend on the locale, but there are still subjective preferences involved. Even within the same unit "system" (SI, CGS, US, etc.) there can be multiple ways to "simplify" a unit, which depends on context. For instance, when calculating torque, answers are typically expressed in foot pounds or newton meters. The latter is equivalent to joules; would that be an appropriate simplification?
  • Custom units and systems -- This would indeed be very powerful, and some users would need this if the units they want are not built-in. Alternatively, the spec could include every conceivable unit so it can always handle everyone's needs. But considering there are at least half a dozen definitions of "cup" depending on locale, this could get pretty crazy.
  • Unit serialization -- I would say that formatting units would be a must-have (the user could adjust the output by passing options). Parsing is a bit more difficult if you allow compound units, because of situations like 10 m / s / s. That results in an error in UnitMath (you need to write 10 m / s^2), but I would guess that we would want the spec to be able to parse anything that it can output.

In all cases, I would look at the newer Internationalization APIs that having been coming out recently and try to pattern the proposal after those.

@TheOneTheOnlyJJ
Copy link
Author

Thank you for your response, Eric!

I'd like to add a comment to this point

Even within the same unit "system" (SI, CGS, US, etc.) there can be multiple ways to "simplify" a unit, which depends on context. For instance, when calculating torque, answers are typically expressed in foot pounds or newton meters. The latter is equivalent to joules; would that be an appropriate simplification?

It's funny that I was sure there was no reliable way to solve this preferred unit specificity issue until I glanced over the units.xml, which is referenced in this proposal's Description section.
At around line 400 (393 to be more precise), the unitPreferenceData tag opens, and its contents are the preferred units for various real-world usage areas of different unit categories (analogous to quantities in UnitMath). I am sure these unit preferences can be leveraged to differentiate between the mentioned newton meters and joules when measuring torque.
If custom units are to be supported, they could also be integrated into such a system.
All that needs to be done is allow the API to take these usages as input before returning new units (upon arithmetic operations, conversions, formatting, etc.), just like the example from one of Ben's other proposals: Smart Unit Preferences.

Other than that, I agree with everything you've mentioned.

While this proposal may originate from the needs of the Internationalisation API, I stand by my statement that limiting the Measure API to strictly its needs holds it back enormously.
Getting this API right would eliminate the need for external libraries and all the overhead & friction of integrating them into projects.
Like Temporal did with dates & times, Measure could do with units & measures.

I am truly hopeful we can get units right once and for all. I'd also invite everybody reading this to consider the server-side usages of such an API. The opportunities are so much greater than Internationalisation here.

I'm really looking forward to @ben-allen's opinion on what we've discussed here up until this point.

@ben-allen
Copy link
Collaborator

I'm very excited about this feedback, and about what I've been hearing from people at the TC39 plenary. When I prepared this draft of the proposal, my expectation was that the unit conversion aspect of Smart Units, and then in turn the unit conversion aspect of Measure, would receive significant pushback. However, I've received more or less the opposite, with lots of encouragement to increase the scope of Measure.

> Like Temporal did with dates & times, Measure could do with units & measures.

Wow! That is both very high praise and very daunting.

> Custom units and systems -- This would indeed be very powerful, and some users would need this if the units they want are not built-in. Alternatively, the spec could include every conceivable unit so it can always handle everyone's needs. But considering there are at least half a dozen definitions of "cup" depending on locale, this could get pretty crazy.

I'm trying to avoid craziness as much as possible, at least right now. A reason I like CLDR's units.xml as a data source is that they've already done the work on what units are in sufficiently widespread use and have sufficiently stable definitions from locale to locale. This is almost but not quite a proxy for what conversions people might want to make in general. Following on your example, for my part I'm loathe to dive into the array of slightly different definitions of "cup", since

  1. Discoverability becomes a concern
  2. If we drastically expand the number of measurements, the size of the data becomes a concern. If we're just using the units.xml units, we're only dealing with about 8kb.

> Converting between volumes and mass is common in recipes, and this could be done by multiplying or dividing by a density.

Ah, once again the cups unit is a concern/problem. We've carefully dodged this in Smart Units by selecting units that aren't involved in cooking. It feels a little bit like a joke stating this in these terms, but it is absolutely not.

Thank you for the encouraging feedback! More on all of this in a bit -- I'm in the middle of a major revision of the proposal.

@TheOneTheOnlyJJ
Copy link
Author

CLDR's units.xml is indeed a solid base to start with. It also includes most of the units anyone could want.
If data size is a concern we want control over, we could use a fork of their file, including, excluding, adding & modifying its contents to better wrap the API. We'd then need to also consider the issue of maintaining said file and keeping in mind concerns of backward compatibility.

I'm trying to avoid craziness as much as possible, at least right now. A reason I like CLDR's units.xml as a data source is that they've already done the work on what units are in sufficiently widespread use and have sufficiently stable definitions from locale to locale. This is almost but not quite a proxy for what conversions people might want to make in general. Following on your example, for my part I'm loathe to dive into the array of slightly different definitions of "cup", since

  1. Discoverability becomes a concern
  2. If we drastically expand the number of measurements, the size of the data becomes a concern. If we're just using the units.xml units, we're only dealing with about 8kb.

It's understandable to avoid such complications as much as possible.
However, designing the API so developers can add their custom units would solve this issue and, to some extent, the issue of data size. This way, developers can consult the supported units (which are already mostly the stable, "official", internationally standardized ones) and add the ones they need as they see fit.

Maybe Eric could give some advice on this topic if he's got the time & availability, once the initial revised API you work on is done. I recommend this because his system for adding custom units is very flexible and new units can be specified in terms of pre-existing units, constants, etc.

An alternative, or even better, complementary way of adding custom units could be loading a raw XML/JSON file in the shape of units.xml (or whatever structure the API ends up using) through a function. This way, both web pages and servers could quickly inject new units in the API from their resource directories.

I'm not experienced in contributing to web standards but would like to help as much as I can with this proposal, as it would solve a major pain point in one of my personal projects.

@ericman314
Copy link

One decision that needs to be made early on is what arithmetic operations Measure will support. If it only has to support simple conversion, and possibly addition and subtraction, then units like meter, meter-squared, and meter-per-second could be completely separate and independent. This alone would probably meet the needs of most use cases.

But if you're aiming to make a fully-featured API to support multiplication, division, and other operations, it will need to have a deeper understanding of the physical relationships between units like meter and meter-per-second. Whether this extends to arbitrary dimensions that may not have a true physical meaning (for example, kg^7), or is restricted to a set of known physical quantities is up to you. But these decisions will affect how units and custom units are defined, and whether units.xml will work as-is.

I think a fully-featured API for units would be amazing. We might even convince some folks in the science and engineering communities to give Javascript a try. At the very least, it would lower the barrier to entry for making educational science- and engineering-related websites. There are really a lot of potential applications.

@ericman314
Copy link

You may be interested in this, @josdejong

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants