Why do I need to put so many parenthesis:
Printf.printf "%f \n" (rectangle_area 25.3 (-1.0));;
this doesnt work:
Printf.printf "%f \n" (rectangle_area 25.3 -1.0);;
Why do I need to put so many parenthesis:
Printf.printf "%f \n" (rectangle_area 25.3 (-1.0));;
this doesnt work:
Printf.printf "%f \n" (rectangle_area 25.3 -1.0);;
The problem is that rectangle_area 25.3 -1.0
is treated the same as (rectangle_area 25.3) - 1.0
- it’s trying to treat the things on the left and right of the -
as int
expressions and then do subtraction.
So, as shown by Levi_Roth, the minus sign by itself means subtraction.
If there was a different minus-sign to negate a value it could be unambiguous… and there is such a sign: ~-
(tilde-minus). OCaml doesn’t support unicode operators, otherwise you might use the actual unicode minus and subtraction symbols, though still have the problem of typing them conveniently.
Note that there is a different negation operator for floats: ~-.
so your expression could be (rectangle_area 25.3 ~-.1.0)
. Yes, it’s ugly, probably moreso than parens, but we either need a way to express our intent or the compiler must make guesses. The problem with guessing and type-inference is that in more complex code examples a simple programmer error can mislead a guessing-compiler to compile code that doesn’t do what you intended at all.
Your editor might support a feature to replace symbol patterns with unicode characters. In Vim I use the “conceal” feature to show unicode-negation for the ~-
and ~-.
, so I type the series of characters, but see a smaller and raised minus-sign which looks distinct from subtraction. A hack of sorts, but ideals are rarely practical to achieve. And this ideal fell off the rails when typewriters used the same “dash” for all dash-like symbols…
So the minus sign is overloaded: (-1)
and (-1.0)
are both valid. It’s an inconsistency which is a concession to the fact that -
for negation is exceedingly common. Usually overloading is not allowed in OCaml.
The unary minus operator is not overloaded. For instance,
let x = 1.
let y = -x
fails, as expected, with
Error: This expression has type float but an expression was expected of type
However, in -1.0
, the minus sign is part of the numerical literal, and is thus translated directly.
To summarize:
-
is a binary (infix) operator and is treated by the parser correspondingly~-
for unary integer negation~-.
for unary floating point negation-
as an unary operator the parser will do this, e.g., let x = -1
, or even in -1 * -1
.I stand corrected… so it’s a special parsing rule!