0.0 == 0.0
is false
when I execute that expression in the interactive REPL:
$ ocaml
OCaml version 4.02.3
# 0.0 == 0.0;;
- : bool = false
# 0.0 = 0.0;;
- : bool = true
But it's true
if I compile and run this program:
let _ =
print_endline (string_of_bool (0.0 == 0.0));
print_endline (string_of_bool (0.0 = 0.0))
dune file:
(executable (name main))
Compiling and running it:
$ dune --version
1.0.0
$ dune exec ./main.exe
true
true
How could 0.0 == 0.0
ever be false
, and why would it be a different value when executing this code natively?
A boolean. The mathematical convention in Boolean algebra is to use 0 for false and 1 for true, so it makes sense to follow that convention. I think this way also makes more sense intuitively.
Because the shell interprets 0 as true this command conveniently works as expected. If the shell were to interpret 0 as false then you'd have to invert the interpreted exit status for each operation. In short, it would be nonsensical for the shell to interpret 0 as false given the convention that applications return 0 for a successful exit status.
because the concept of zero being equivalent to false is well-understood. The languages are designed like that because the math makes sense. That came first. @Morwenn, it goes back to the 19th century and George Boole. People have been representing False as 0 and True as !0 for longer than there have been computers.
Return code could mean Error code, and hence 0 (False) could mean no error, that way True = 1, and False = 0. The concept of error codes to Boolean values does not have to be tied to me? Bash is a programming (scripting) language, but it's also a shell and a user-interface. If 0 was error, then the program could only present one kind of error.
Note for OCaml beginners: the "normal" equality is =
. The ==
operator tests if two value have the same memory address.
The ==
operator is sometimes quite hard to understand. To quote the OCaml manual:
On non-mutable types, the behavior of ( == ) is implementation-dependent; however, it is guaranteed that
e1 == e2
impliescompare e1 e2 = 0
.
float
being a non-mutable type, there is no guarantee of its behavior on two equal values.
Now, let's see exactly what happens.
In the case of the interpreter, your expressions are evaluated without much optimization. The point is to put your code to execution quickly, not to have your code run fast. So when it sees a 0.0
constant, the programs allocates a new physical memory block that contains the appropriate data "float 0.0
". Allocate the same constant two times and you get two different memory addresses. Hence a 0.0 == 0.0
returns false
Now the native code compiler is much more smarter. It tries to minimize memory usage and execution time. When it sees that the same immutable constant is allocated two times, it considers "there is no point in allocating the same thing twice, let's allocate once".
In a way, the compiler turns 0.0 == 0.0
in let c = 0.0 in c == c
. This is why you get true
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With