dotnet / dotnet/vblang

Units Of Measure

Open
#200 11 comments 2 reactions 0 assignees View on GitHub
Dominant language
No language data
Stars
328
Forks
71
PR merge metrics
No merged PRs in 30d

Description

I propose that we borrow from F# the language feature of [Units Of Measure](https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/units-of-measure).

**Units Of Measure** expands on the type-safety principles, by optionally enhancing the type with a explicit kind.

-----

## Basic Structure *(draft)*

```antlr
UnitOfMeasureBlock ::= Unit_Header Unit_Body Unit_Footer
Unit_Header ::= "Unit" Unit_Identifier Unit_Constraint?
Unit_Constraint ::= "As" typeidentifier
Unit_Footer ::= "End" "Unit"
Unit_Body ::= Unit_BodyLine*
Unit_BodyLine ::=
Unit_Definition ::= "[" Unit_Identifier_Symbol "]"
Unit_Operator ::=
Unit_CompositeBlock ::=
```

* Namespace definable
* **So you can import a specific set of units of measure.**
* Explicit Conversion only
* Limited operators predefined (or automatically implement)
* `+` (Addition) and `-` (Subtraction), only on the explicit unit being defined.
* Default `+` and `-` can be overridden.
* Comparison Operators are automatically implemented, for the explicit unit defined.

------

```vbnet
Imports UnitOfMeasure.SI

Module Example

Public Sub Main()
Dim G = 9.98[m/s^2]
Dim speed As [m/s] = distance[m] / time[s]
Dim Area As [m^2] = height[m] * width[m]
Dim Volume As [m^3] = height[m] * width[m] * depth[m]
End Sub

End Module
```

## Define a Unit Of Measure
Implemented by a new block construct `Unit .... End Unit`, which is, similar to a `namespace` block. These blocks can be imported.

The language will provide a base set of units of measure (SI Units and their derived Units)
```vbnet
Abstract Unit SI
Abstract Unit Distance
[m] ' metres ( A concrete implementation of an abstract unit SI.Distance
[m^2] = [m] * [m]
[m^3] = [m] * [m] * [m]
[m^3] = [m^2] * [m]
[m^3] = [m] * [m^2]
End Unit

Abstract Unit Mass
[kg] ' kilograms (mass)
End Unit

Abstract Unit Duration
[s] ' seconds
End Unit

Abstract Unit Temperature
[K] ' Kelvins
[K].Min = 0[K] ' Add constraint on the valid range of this Concrete Unit
End Unit

Abstract Unit AmountOfSubstance
[mol] ' Mole
End Unit

Abstract Unit LuminousIntensity
[cd] ' candela
End Unit

Unit ElectricCurrent
[A] ' Amperes
End Unit

End Unit
```

```vbnet
Unit SI_Derived

Unit Distance
Constant OneMinute = 1[min]
Constant SixtySeconds = 60[s]
' Explicit Conversions
[min] = [s] / 60
[s] = [min] * 60
End Unit

Unit Duration
' Explicit conversions
[ms] = [s] / 100
[ns] = [s] * 1000000
End Unit

Unit Frequency
[Hz] ' Hertz
' Permitted operators
[Hz] = [1/s] ' Operator /( C As Constant, s As [s] ) As [Hz]
[Hz] = [s^-1] ' Operator ^( s As [s], C as Constant ) As [Hz]
' Define conversion factors.
[KHz] = [Hz] / 1000
[MHz] = [KHz] / 1000
[GHz] = [MHz] / 1000
[THz] = [GHz] / 1000
End Unit

End Unit
```
```vb
Const C = 299792458[m/s]
Const G = 9.98[m/s^2]
Const Avogadro= (6.022140857 x 10^23)[mol^-1]
```

------

## Composite Units Of Measure
If an Unit Of Measure is followed by another Unit Of Measure, that is compos-able with it. It combines into a single composite UnitOfMeasure
Example
```vbnet
Unit Feet
[ft]
['] ' an alias for [fr]
Composite ["]( x As Double["] ) As [Ft][In]
End Composite
End Unit

Unit Inch
[in]
["] ' an alias for [in]
End Unit

```vbnet
Dim height = 6[']6["] 'eg 6 foot and 6 inches.
Dim length = 6["]6['] ' Invalid: Inches can't compose with feet. (Did you mean a Feet and Inches?)
```

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.