Open AdamSpeight2008 opened 6 years ago
Alternative Syntax
Unit SI
.Distance
[m] ' metres (length)
.Mass
[kg] ' kilograms (mass)
.Duration
[s] ' seconds
.Temperature
[K] ' Kelvins
[K].MinValue = 0
.AmountOfSubstance
[mol] ' Mole
.LuminousIntensity
[cd] ' candela
.ElectricCurrent
[A] ' Amperes
End Unit
Unit SI_Derived
.Distance
[min] = [s] / 60
[s] = [min] * 60
.Duration
[ms] = [s] / 100
[ns] = [s] * 1000000
.Frequency
[Hz] ' Hertz
[Hz] = [1/s]
[Hz] = [s^-1]
[KHz] = [Hz] / 1000
[MHz] = [KHz] / 1000
[GHz] = [MHz] / 1000
[THz] = [GHz] / 1000
.Angle
[deg] ' Degrees
End Unit
Is this different from #120 ?
@Bill-McC it is a different style to #120.
Do units of measure even need to be defined? Could they be handled the same way as named tuples today? We could define the units in place, either in member/local declarations or in the literals, like names in tuples. Conversions could be handled by regular old functions. (Or do you think implicit conversions are an essential part of this feature?)
Implementation-wise, I can imagine something like this
Function CalcVelocity(distance As Double[m], time As Double[s]) As Double[m/s]
becoming something like this
Function CalcVelocity(<Unit("m")> distance As Double, <Unit("s")> time As Double) As <Unit("m"), InvertedUnit("s")> Double
behind the scenes.
@gilfusion I think units of measure should be defined, as the operators that be are specific to that unit. They maybe able to be implemented via tuple (I've not look at implementation), but I rather them be an intrinsic part of the language, and also framework.
In general the only universal ones are +
(addition) and `-' (subraction) within the same unit of measure.
Any other should be defined upon the specific units.
Which the advantages of using units of measure, come into play, it catches issues and errors at compile-time.
Dim x = 10[m]
Dim y = 1
Dim q = x + y ' Compile-Time Error: Unit [m] doesn't support operator + with an integer.
Dim length = 10[m]
DIm quantity = 10
Dim total_length = length * quantity. ' Valid (if Unit[m] defines *( L As Double[m], R As Double ) As Double[m]
All units of measure should be Explicit then any conversion from unit to another to is explicitly made, so the user is sure about the potential loss of precision. An example using Composite Units Of Measure converting Imperial units to Metric unit (or visa-versa) would require an explicit cast,
Note I'm also using a new cast operator CUoM
eg CastUnitofMeasure)
Dim imperial_height = 6[']6["] ' eg 6 foot and 6 inches.
Dim metric_height As Double[m] = imperial_height ' would be an error
Thought of another usage of Composite Unit, indication of precision
Dim duration = measured_time[s][+-]25[ms]
' measured time period with an accuracy of plus or minus 25 milliseconds.
@AdamSpeight2008 Okay. I think we are thinking of two different approaches to units of measure. I was just thinking of them as an annotation, like an attribute, to mark a numeric value, but I think you are thinking of them as a new kind of data type (kind of like how Enums are their own data types). Does that sound right?
Also, looking at that precision example, do you see a way to get the individual pieces of a composite unit out? To get the inches portion out of a feet-inches composite, or get the precision part out of a time-precision composite?
@gilfusion Sounds right, I'm treating them as a new kind of datatype.
Also, looking at that precision example, do you see a way to get the individual pieces of a composite unit out? To get the inches portion out of a feet-inches composite, or get the precision part out of a time-precision composite?
Note This is extremely rough back of envelope code
Compiler could a set of abstract class and concrete classes, to which the Unit Of Measure code compile to. There will also require additional compilation step. Compile Units -> Compile Code
eg
MustInherit Class Unit
Public ReadOnly Property Symbol As String
Public ReadOnly Value As ??
Friend Sub New( Symobol As String, Value As ??)
Me.Symbol = Symbol
Me.Value = Value
End Sub
Overrides Function ToString() As String
Return $"{Value.ToString}[{Symbol}]"
End Function
End Class
Class WithPrecision
Public ReadOnly Property Source As U0
Sub New( source As Unit, value As ?? )
MyBase.New("+-", value)
Me.Source = Source
End Sub
Overrides Function ToString() As String
Return $"{Source.ToString}[MyBase.ToString]"
End Function
End Class
Class Second : Inherits Unit.Time
Sub New( Value As ??)
MyBase.New("s", Value )
End Sub
End Sub
We could have a partial solution to Complex Number Literals
Dim x As Numerics.Complex = -12.34[i]56.78
I've a repo that is developing the base class and initial Units. https://github.com/AdamSpeight2008/Unit @AnthonyDGreen VBnet Units Defined
I propose that we borrow from F# the language feature of Units Of Measure.
Units Of Measure expands on the type-safety principles, by optionally enhancing the type with a explicit kind.
Basic Structure (draft)
+
(Addition) and-
(Subtraction), only on the explicit unit being defined.+
and-
can be overridden.Define a Unit Of Measure
Implemented by a new block construct
Unit .... End Unit
, which is, similar to anamespace
block. These blocks can be imported.The language will provide a base set of units of measure (SI Units and their derived Units)
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