开发者

What are the strategies to support/integrate units of measurements in languages?

开发者 https://www.devze.com 2023-04-06 06:55 出处:网络
I wonder from purely language-design point of view which \"features\" (semantically and syntactically) an \"implementation\" of SI units would require.

I wonder from purely language-design point of view which "features" (semantically and syntactically) an "implementation" of SI units would require.

Which "functionality" is generally expected if someone claims that a language has great support for units of measurements?

  • Just something like special literals or syntactic sugar?
  • Special conventions which make units typesafe (b开发者_StackOverflow中文版ut without costly runtime wrapping)?
  • A special math mode for computations with fractions?
  • Automatic conversions and coercion between units?

For instance F# has integrated support for units of measurements in the language. How does it improve over e. g. a library for Java?

Which features should be built into the languages to improve usability of units? Which features are not necessarily related to units of measurement but make an implementation nicer?


F#'s advantage over a Java UOM library is simple - type safety. You will get compile-time errors if you attempt to add 3.<s> and 4.<m / s>.

In F#, UOM are erased after the type-checking, because it is the only .NET language with such feature.

In reply to comment, here is a simple fraction type and its usage:

type Fraction<[<Measure>] 'a>(a : int, b : int) =
    member __.Divisor = a
    member __.Dividend = b
    member __.AsFloat = float a / float b
    static member (*) (a : Fraction<'a>, b : Fraction<'b>) : Fraction<'a * 'b> =
        Fraction(a.Divisor * b.Divisor, a.Dividend * b.Dividend)

type [<Measure>] m
type [<Measure>] kg
type [<Measure>] s

let a = Fraction<m / s>(4, 3)
let b = Fraction<kg>(2, 5)
let ``a times b`` = a * b

And the value returned is of type Fraction<kg m/s> and its AsFloat value is 0.5333333333.


From a language-design point of view, it's enough to be able to :

  1. tag data types with arbitrary labels (not just string or other primitive labels, but arbitrarily structured labels)
  2. perform arbitrary compile-time calculations on labels
  3. given operand labels and an operator (function), calculate the label of the result of the function applied to labelled operands

This all can be done and was done more than 10 years ago with C++ template metaprogramming.

There's also an implementation for Haskell that uses Haskell's (limited) ability to perform compile-time calculations over typeclass instances. It's not as complete though (AFAIK no fractional powers and no non-SI units).


Fascinating. I googled this tinkling,"I am sure I could do this quite easily in Smalltalk," and stumbled upon Frink http://futureboy.us/frinkdocs/ which targets the JVM and Android.

Tracks units of measure (feet, meters, tons, dollars, watts, etc.) through all calculations and allows you to add, subtract, multiply, and divide them effortlessly, and makes sure the answer comes out correct, even if you mix units like gallons and liters.

and of course key to this is conversion

Unit Conversion between thousands of unit types with a huge built-in data file.

and uncertainty

Supports Interval Arithmetic (also known as Interval Computations) in calculations, allowing you to automagically calculate error bounds and uncertainties in all of your calculations.

I'm sure you could do this with classes in Java and definitely with Ada, but that would be a lot of (I'm sorry) typing.


There was a good paper in the ACM SIGPLAN Notices about this in the 1980s. The idea was type safety plus the kind of unit analysis you learn in high school physics: for example, a speed is miles/hour, a time is hours, so multiplying them together gives a distance in miles, and the type system enforces that for you so you can't make category mistakes. The language or meta-language would have ways to specify all that. As another example, I recently did some currency work in Java where a CurrencyValue divided by a CurrencyValue gave a BigDecimal, i.e. an exchange rate; a CurrencyValue multipled or divided by a BigDecimal gave another CurrencyValue, etc.

This is basically how you used to do the old multi-choice PSSC Physics exams: forget the physics, just memorize a few constants of the universe, then just reason about the problem given the units of the specified quantities and the units of the answer required, then you can construct the formula required yourself.


The successor to the library for Java (unitsofmeasurement.org) can now be found under unitsofmeasurement.github.io. It is home to the Java standard for Units of Measurement, JSR 363. Check it out.

0

精彩评论

暂无评论...
验证码 换一张
取 消