6 ms·
Unit of measures are a great example of what a type system can do, and something not enough languages support. F#[1] and Scala[2] are two that I know of that do
by mdm12 4y ago
Unit of measures are a great example of what a type system can do, and something not enough languages support. F#[1] and Scala[2] are two that I know of that do support UOMs. Like you, I haven't had the need to use them in the domains I work in, but I imagine that they would be invaluable in certain contexts.
[1] https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/units-of-measure https://learn.microsoft.com/en-us/dotnet/fsharp/language-ref...
[2] https://github.com/typelevel/squants https://github.com/typelevel/squants
- leephillips 4y agoJulia has this via a package: Measurements.jl.
- docandrew 4y agoPackages exist for Ada, too: http://archive.adaic.com/tools/CKWG/Dimension/Physical_units_with_GNAT_GPL_2013-AUJ35.1.pdf http://archive.adaic.com/tools/CKWG/Dimension/Physical_units...
- throwawaymaths 4y agoIt's also something that some languages seriously screw up. Consider multiplying a time (which is typed in go) with a numerical value... suppose what I want is a user to input number of time intervals to wait. So the user wants 5, and the interval is 2500 milliseconds. The way you get 12500 milliseconds out of that made me want to throw my computer out the window.
- Chinjut 4y agoI don't understand. What should you get instead?
- morelisp 4y agoGo does not have operator overloading, and numeric operators must have identical types. So if you have `var x int = 5` and `var t time.Duration = 2500 * time.Millisecond`, you have to `time.Duration(x) * t` or `time.Duration(x * int(t))`. It's slightly better than languages with no operator overloading nor newtypes at all (well, actually a lot better given other things you can use newtypes for) but without operator overloading using it just for units, with no other API machinery, is usually a bad idea.
- throwawaymaths 4y agoTwo options: 1. Don't type units like that. 2. Allow the * operator to multiply a time-unitful value with an untimed scalar and disallow using it with two time-unitful values. Presumably the requirement that * operands are the same is arbitrarily modifiable and go developers have control over what types operators take.
- morelisp 4y ago1. Uh, ok. Might as well throw out the whole thread then? 2. A "time unit" is not a special type of value. You can construct arbitrary types of integers, and it is common to do so. `*` has no clue what a time is, just that it's "not an int" (for example).
- xigoi 4y agoThe commenter you're replying to expressed it confusingly. The point is that in Go, 5 * time.Milliseconds(2500) is a type error, and instead you need to do time.Nanoseconds(5) * time.Milliseconds(2500).
- morelisp 4y ago`5 * time.Milliseconds(2500)` is not a type error, though `int(5) * time.Milliseconds(2500)` is. (This is especially relevant because you really mean `5 * (2500 * time.Millisecond)` vs. int(5) * (2500 * time.Millisecond)`, as there is no `time.Milliseconds` function.)
- xigoi 4y agoThanks, I don't remember exactly how it worked. It doesn't take away from the stupidity.