| > If you look upthread, there was a mention of F# unit types. And the syntax is `3<unit>` not `3 * unit` - 1 is a scalar
- 1m is a quantity
- 2 * 1m "casts" 2 to a meter, but really this is just multiplying a quantity by a scalar
- 2 * 1m * 1m "casts" 2 to meter², multiplying 2 quantities then by a scalar I insist, `1 * m` does not make sense. This is not a valid mathematical expression, because a unit can never be on its own without a value. > expression of a unit without a value is (or should be to my mind, based on my education) a cast There is no casting in math. Mainly because there is no types, only objects with operations. A vector is not a scalar and you can't cast it into a scalar. A quantity is not a scalar either, and you can't cast one into another. A quantity is an object, you can multiply 2 quantities together, but you can't add them if they are different. You can multiply a quantity to a scalar, but you still can't add a scalar to a quantity. |
Well, yeah, F# represents this at the type level. Which I’ve said elsewhere in the discussion is preferable. Not knowing Go, but knowing it only recently gained generics, I read multiplying by `time.Seconds` (which does not have a visible 1 associated with it) as perhaps performing an operator-overloaded type cast to a value/type with the Seconds unit assigned to it. I’ve since learned that Go also does not support operator overloading, so I now know that wouldn’t be the case. But had that been the case, it isn’t inconceivable that unitlessValue * valuelessUnit * valuelessUnit = unitlessValue * valuelessUnit. Because…
> I insist, `1 * m` does not make sense. This is not a valid mathematical expression, because a unit can never be on its own without a value.
Well, if you insist! But you seem to be imposing “mathematical expression” on an expression space where that’s already not the case? Whatever you may think of operator overloading, it is a thing that exists and it is a thing that “makes sense” to people using it idiomatically.
Even in languages without overloading, expressions which look like maths don’t necessarily have a corresponding mathematical representation. An equals infix operator in maths is a statement, establishing an immutable fact. Some languages like Erlang honor this, many (most? I strongly suspect most) don’t! I couldn’t guess without researching it also treat infix = statements as an expression which evaluated to a value.
The syntax of infix operators is generally inspired by mathematical notation, but it’s hardly beholden to that. The syntax of programming languages generally is not beholden to mathematical notation. Reacting as if it’s impossibly absurd that someone might read 1 * time.Seconds * time.Seconds as anything other than 1 * 1s * 1s is just snobbery.
Not knowing Go, I focused on the syntax and the explicit values, and tried to build a syntax tree on top of it. I’m not a fan of infix operators, and I am a fan of lisps, so my mental syntax model was (* (* 1 time.Seconds) time.Seconds)), which still doesn’t “make sense” mathematically, but it can make sense if `*` is a polymorphic function which accepts unquantified units.