What does the minus sign by itself mean?

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.

1 Like

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:

  1. - is a binary (infix) operator and is treated by the parser correspondingly
  2. for unary (prefix) minus operator there are two special syntaxes:
    • ~- for unary integer negation
    • ~-. for unary floating point negation
  3. when it is possible to unambiguously interpret - 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!