Something like:
unit type Meters = m
unit type Seconds = s
function sleep(time: Int[s]): void
val speed = 5.4 m/s // Type = Float[m/s]
val distance = parseFloat(prompt('enter time')) * 1 m // Convert unitless to meters just by multiplying
val time = distance / speed // Type = Float[s]
print("${time}") // Prints "# s"
print("${time / 1 s} seconds") // Prints "# seconds"
val complexUnit = 7 * 1 lbf/in2 // 7 lbf/in2
// != 7 psi (too hard to infer) but you can write a converter function
function toPsi<N : Numeral>(value: N[lbf/in2]): N[psi] {
return value * 1 psi*in2/lbf
}
It requires extending number parsing, type parsing (if the brackets aren't already part e.g. in TypeScript), and extending types to support units of measurement at least if they are statically known to be subtypes of `Numeral`.Naming variables with their units doesn't solve the issue of mis-casting and using units incorrectly, and newtypes are too inconvenient (and sometimes impossible without affecting performance) so nobody uses them. Even as a very software-focused programmer I encounter units like seconds, bytes, pixels, etc. all the time, they are almost never newtypes, and I get bugs from forgetting to convert or converting incorrectly.