I was thinking that names help in those areas where algebraically correct operations can still lead to broken domain logic. Type systems help verifying that a specified algebra functions coherently but they do not help in designing that algebra.
I.e velocity v, acceleration a are modeled as floats. To integrate from instance in time t0 to t1, v1 = v0 + (t1 - t0) * a.
Now, I can replace any of those arithmetic operators with other arithmetic operators and still the statement is algebraically correct. However, the calculation is probably wrong,e .g. v1 = v0 * (t1 / t0) - a is a such broken permutation.
Naming time at point 0 as t0 and at point 1 as t1 are helpful mnemonics that help here.
Sure, we can create data types (that contain floats) Acceleration, TimeBefore, TimeAfter, VelocityBefore and VelocityAfter and create function (since we are ignoring names) asdf->VelocityBefore->TimeBefore->TimeAfter->Acceleration->VelocityAfter but the rub is - the implementation of that function needs to do that floating point arithmetic at some point.
Wrapping it in an algebraically explicit container does nothing to help in the correctness of the computation in itself. The main benefit here is for the end user in form of explicit types. Here, the function signature proves the OP:s point - signatures can be enough to document a function. However, it does nothing to verify the implementation.
Floating point operations are inherently "dynamically typed" in the sense that from a semantic point of view only some operations make sense when forming equations but modeling all of these relations using a type hierarchy is really, really cumbersome - and after the type hierarchy is in place, the hierarchy itself cannot prove the equation is correct, it just sets it in stone. Maths in inherently dynamically typed and good names help write better equations. If anyone have counter examples to prove this notion wrong I would appreciate them.