在语言中支持/整合测量单位的策略是什么?

时间:2011-09-20 10:03:27

标签: java f# language-design units-of-measurement

我从纯粹的语言设计观点出发,对“SI”单元的“实现”需要“特征”(语义和语法)。

如果某人声称某种语言对测量单位有很大的支持,那么通常会预期哪些“功能”?

  • 就像特殊文字或语法糖一样?
  • 使单位类型安全的特殊约定(但没有昂贵的运行时包装)?
  • 使用分数计算的特殊数学模式?
  • 各单位之间的自动转换和强制?

例如,F#已集成了对该语言中度量单位的支持。它是如何改进的? G。 Java a library

应该在语言中加入哪些功能以提高单元的可用性?哪些功能不一定与测量单位有关,但实现更好?

5 个答案:

答案 0 :(得分:3)

F#相对于Java UOM库的优势很简单 - 类型安全。如果您尝试添加3.<s>4.<m / s>,则会出现编译时错误。

在F#中,UOM在类型检查后被删除,因为它是唯一具有此类功能的.NET语言。

在回复评论时,这是一个简单的分数类型及其用法:

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

返回的值为Fraction<kg m/s>,其AsFloat值为0.5333333333

答案 1 :(得分:1)

从语言设计的角度来看,足以能够:

  1. 使用任意标签标记数据类型(不仅仅是字符串或其他基本标签,而是任意结构化标签)
  2. 在标签上执行任意编译时计算
  3. 给定操作数标签和运算符(函数),计算应用于标记操作数的函数结果的标签
  4. 使用C ++模板元编程可以完成所有and was done more than 10 years ago

    还有一个Haskell的实现,它使用Haskell(有限的)能力对类型类实例执行编译时计算。但它并不完整(AFAIK没有分数幂,也没有非SI单位)。

答案 2 :(得分:1)

魅力。我用谷歌搜索了这句话,“我确信我可以在Smalltalk中轻松地做到这一点,”并且偶然发现了针对JVM和Android的Frink http://futureboy.us/frinkdocs/

  

跟踪测量单位(英尺,米,吨,美元,瓦特等)   通过所有计算,允许你加,减,乘,   毫不费力地划分它们,确保答案出来   正确的,即使你混合加仑和升等单位。

当然关键是转换

  

单位转换数千种单位类型与巨大的内置数据文件。

和不确定性

  

支持间隔算术(也称为间隔计算)   计算,允许您自动计算误差范围和   所有计算中的不确定性。

我确信你可以用Java中的类来完成这项工作,但肯定会使用Ada,但这会很多(对不起)打字。

答案 3 :(得分:1)

在20世纪80年代的ACM SIGPLAN通知中有一篇很好的论文。这个想法是类型安全加上你在高中物理中学到的单位分析:例如,速度是英里/小时,时间是几小时,所以将它们相乘可以得到英里距离,类型系统强制执行你这样就不会犯类别错误。语言或元语言可以指定所有这些。作为另一个例子,我最近在Java中做了一些货币工作,其中CurrencyValue除以CurrencyValue给出了BigDecimal,即汇率; CurrencyValue乘以或除以BigDecimal给出了另一个CurrencyValue等等。

这基本上是你用来做旧的多选PSSC物理考试的方法:忘记物理学,只记住宇宙的一些常数,然后只是给出指定数量单位和单位的问题的理由需要答案,然后你可以自己构建所需的公式。

答案 4 :(得分:0)

现在可以在unitsofmeasurement.github.io下找到Java库的继承者(unitsofmeasurement.org)。它是测量单位的Java标准的所在地,JSR 363。看看吧。