6 ms·
Dimensional Analysis in Programming Languages (2018)
- btrettel 7y ago> An important theorem in dimensional analysis is the Buckingham π theorem, which states that the laws of physics do not depend on the choice of a specific system of measurement. That's not what the Buckinham pi theorem states. The Buckingham pi theorem is a statement about the functional dependencies of dimensionally homogeneous equations. https://en.wikipedia.org/wiki/Buckingham_%CF%80_theorem https://en.wikipedia.org/wiki/Buckingham_%CF%80_theorem I guess the writer mirrored some language on Wikipedia which indicated that the physical laws being independent of the choice of units is a consequence of the theorem. Anyway, I don't mean to detract from what otherwise appears to be an interesting and comprehensive summary of dimensional homogeneity checking in programming languages.
- mirekrusin 7y agoGood summary but why Julia is missing?
- exdsq 7y agoOver the last week it seems Julia has become the new Lisp of HN.
- shele 7y agoWe rather do not call Julia a Lisp lest people notice.
- stellalo 7y agoThe post is from May 2018, so prior to the 1.0 splash. Although Nim is mentioned in the post. I guess one simply cannot be expected to survey all there is, really...
- mirekrusin 7y ago...yes, but it has plenty of exotic entries, doesn't it?
- deleted 7y ago[deleted]
- quantified 7y agoThank you for the pointers. A system of units is hobbled without including the necessary counts of objects/measurement events, which is open-ended. Mass per person is different than mass per chicken or per 787, for example.
- gugagore 7y agoI mean, yes. It's also incomplete if it doesn't include a notion of directionality to e.g. distinguish between energy (force and displacement aligned) and torque (force and displacement perpendicular). The SI system isn't perfect, but expressing at least some dimensional information to be checked by machine feels like a step in the right direction.
- quantified 7y agoIt certainly is. The more meaning we need to attach to a number, the more expensive it is, and SI is a really good start.
- roel_v 7y agoGood libraries will let you define custom units that let you express things like this. Boost.Units does.
- gumby 7y agoSince this was written a library proposal to add units to C++ has been submitted to wg21: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1935r0.html http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p193...
- aj7 7y agoI believe it’s well developed in LabView.
- stellalo 7y agoJulia has the Unitful.jl package for handling units: https://github.com/PainterQubits/Unitful.jl https://github.com/PainterQubits/Unitful.jl
- dunefox 7y agoThis looks worse than the Java units: julia> 1u"kg" == 1000u"g" # Equivalence implies unit conversion true Java: Length distance = 100 mph * 3 hr;
- sents 7y agoYou can do this: julia> using Unitful.DefaultSymbols julia> 50m / s 50 m s^-1
- dunefox 7y agoNice, that's much better.
- ChrisRackauckas 7y agoAnd you can manually define them: const m = u"m" 50m There's actually nothing special in the compiler for unit implementation. This is just using the fact that `2x` is valid Julia code, where now x is something that overloads a dispatch to turn the number into a number with units. By default it uses string macros to keep the namespace clear, but you can fill the namespace with whatever you want.
- ChrisRackauckas 7y agoAlso note that these are zero runtime overhead: they act at compile-time through the type system and type-check or add in multiplications when conversions need to occur, but the compiled code is just floating point operations without reference to units or unit checking. It's a great system since it means you can always use units, even in performance critical code. And it works throughout the ecosystem, so you can even use it in linear algebra and things like ODE solves. Here's an example of solving an ODE with units: https://tutorials.juliadiffeq.org/html/type_handling/03-unitful.html https://tutorials.juliadiffeq.org/html/type_handling/03-unit...
- jakeogh 7y agopint wrapper that does fuzzy matching: https://github.com/jakeogh/unitcalc https://github.com/jakeogh/unitcalc unitcalc 50stones kg unitcalc 1lightyear nm unitcalc 7fortnights decades unitcalc 99mi/sec fathom/month unitcalc 3.14radians/fortnight degrees/ms unitcalc 0.2W eV/century unitcalc 0.2J/ns ton_TNT/month Pint is excellent. If you put in units that need a dimension to convert, the exception says what is missing, it could ask for that value, but havent figured it out yet; obviously dont want to parse the exception message. The framework to tell it physics exists, so stuff like: unitcalc 0.2eV femtograms should be possible.
- mckinney 7y agoJava provides exceptional dimensional and unit support via the Manifold framework [1]. Length distance = 100 mph * 3 hr; Force f = 5.2 kg m/s/s; // same as 5.2 N Mass infant = 9 lb + 8.71 oz; [1] https://github.com/manifold-systems/manifold/tree/master/manifold-deps-parent/manifold-ext#unit-expressions https://github.com/manifold-systems/manifold/tree/master/man...
- nemoniac 7y agoFrom the Linux command line, you can use units(1): $ units "firkin furlong per fortnight" Definition: 5.6659503e-06 m^4 / s $
- dnautics 7y ago> If you've used strongly-typed programming languages before, the relationship between dimensional analysis and type theory is rather obvious Author clearly hadn't tried multiplying a user-input time value with a time constant (like milliseconds) in Go, a strongly typed language
- dunefox 7y agoAlso *statically typed.
- stared 7y agoI think dimensions in physics serve as some interesting types, with their built-in arithmetics. I miss them in the languages I use (Python, TypeScript). I would love to have e.g. "percent" or "probability" type. So that when "100 percent === 1 probability", with proper autocasting. Same for quite a few other qualities (e.g. logit -(softmax)-> probabilities). Before I get "just use Haskell" or something in that line. IMHO for anything practical, ecosystem >>> language syntax and stuff. So the question is: are there any solid Python or TypeScript approaches for these systems?
- leni536 7y agoProbability is unitless. Percent is just literally 0.01 . Angle units have a similar problem.
- stared 7y agoI think you missed the point. Units != dimensions. E.g. angle in radians, degrees and full rotations differs by a factor. It is a typical, and common, mistake that would benefit from such system.
- quantified 7y agoAll numeric concepts that have any meaning whatsoever have units/“dimensions”. Probability is in units of possible outcomes. If your chances are affected non-linearly, you’d express that (chance of death per inch of penetration). No percentages are unitless. If they were, you could substitute them without consequence, like applying an interest rate percentage in place of a mortality rate pecentage or an alcohol-to-water percentage. Angles, exponents, counts all fit in units, just more complex unit expressions.
- touisteur 7y agoIsn't the idea to mix types and dimensionality analysis? With mathematics libraries in a language like Ada your angles will usually be one type, your distances another, and the rate of change another, and so on.
- ryanianian 7y ago
- pron 7y agoAlso worth mentioning is the Units Checker [1] for Java, which uses Java 8+'s pluggable type systems feature to introduce units as intersection types. [1]: https://checkerframework.org/manual/#units-checker https://checkerframework.org/manual/#units-checker
- philzook 7y agoI wonder to what degree dimensional analysis and free theorems are connected. The rabbit out of the hat style reasoning feels very similar to me. I suppose one could use polymorphic type variables as units with the appropriate definitions of arithmetic operations. I don't suppose anyone has a reference on this?
- brandmeyer 7y agoReynolds Number, Prandtl number, power factor, efficiency, anything that is a fraction of full range, mechanical strain, etc. There are many terms in an engineering project that are unitless. Having a system to automatically check the units on the remaining scalars is cute, but doesn't do anything to prevent you from improperly performing operations that relate efficiency and power factor by accident, for example. Multi-input, multi-output control systems regularly assemble state vectors out of terms that have mixed units. You can easily have amps, volts, meters per second, and radians per second in the same mathematical vector. I have yet to see a compile-time unit-checking scheme that adequately addressed those issues.
- touisteur 7y agoUgh... Kalman filters...
- mckinney 7y agoCan you provide an example involving "operations that relate efficiency and power factor by accident" or similar? I'd like to better understand your problem domain.
- brandmeyer 7y agoThat's kindof like asking for an example of operations that relate length and speed by accident. The whole point is that it is an accident. Its exactly the kind of accident that embedding units into your type system is supposed to prevent. I just find that the kind of trivial examples that folks support this way are just that - trivial examples. They don't scale to the kinds of problems that I am faced with solving.
- jlokier 7y agoI implemented this in C++ for a commercial game engine many years ago. Both internally, and in the API used by games on top. We used Emacs-Lisp to generate a collection of C++ classes with all of the arithmetic operaters that were allowed, and only those. "friend" is your friend for this in C++. We mostly used floating point to represent values, but could also use integers with scale factors (automatically applied in the operators), which is nearly equivalent to fixed point. For things where vectors made sense, 1d, 2d and 3d vector types were available. So Position2d and Position3d. Absolute and relative values were distinguished: You could substract two absolutes to get a relative, but you couldn't add two absolutes. You could add a relative to an absolute to get an absolute. And for time intervals we used wraparound arithmetic and comparisons, like the Linux kernel has the time_before() macro, so absolute times could continue "growing" without overflow in a running game. Using the classes looked like a bit like this: Position3d p1, p2; Direction3d d = p2 - p1; Absolute_Time t1, t2; Time_Interval t = t2 - t1; Velocity3d v; object.set_position(p1 + t * v); These types were used pervasively throughout all the game engine, gameplay logic, "AI" and so on. The constraints provided great type-checking and effectively documented a lot of code as well. This being a game engine, they had to be fast. So they were all inline methods, in classes containing just a number, or up to 3 numbers for vectors. Using GNU C++ this compiled down to the same machine code as if we hand-coded the arithmetic in the traditional way; we checked. So there was no runtime cost. It was very satisfying to use.