let foo = (a, b) => {
print_string(string_of_int(a) ++ " " ++ string_of_int(b));
};
let x = ref(0);
let bar = () => {
x := x^ + 1;
x^
};
foo(bar(), bar());
The code above produces different results between Bucklescript and js_of_ocaml.
Bucklescript: 1 2
js_of_ocaml: 2 1
This is painful, since it means it’s my responsibility as a developer
to keep track of what functions that have side-effects,
and to work-around the problem using temporaries, e.g.:
let a = bar();
let b = bar();
foo(a, b);
Would it be possible to improve the developer experience in ReasonML?
Here comes an idea I would like to discuss with the ReasonML community:
IF the compiler could detect if a function could possibly have side-effects,
THEN for any expressions containing multiple calls to such functions,
the evaluation order could be enforced to always be left-to-right.
ELSE IF the expression only contains calls to pure functions,
THEN the compiler could evaluate them in any order, perhaps even in parallell
in a future multi-core ReasonML compiler.
I don’t know much about the ReasonML compiler, so I don’t know if
the idea above is realistic or not.
If it’s not, then maybe at least it would be possible to develop
a new compiler warning that would detect expressions containing
multiple calls to functions that could potentially have side-effects.
Thoughts?