Let’s say I have a bunch of nested let…in statements. I noticed that if I have
(* a bunch of let... in above *)
let test = expr1 in
(* a bunch of let ... in below *)
I get this Error (warning 26): unused variable test, yet when I change it to let _ = expr1 in ... or let () = expr1 in ... there are no error messages.
I understand let _ = is pattern matching for anything and let () = is pattern matching for anything of type unit, but does this mean that my expr1 is just being executed anywhere? Is it being called once?
Yes, expr1 is being evaluated, but the warning is telling you that its result, while being bound to a variable, is not being used.
As expr1 is of type unit there is no point in binding its result to a variable. The usual way is to use the sequencing operator ; in that case:
...
expr1;
...
If expr1did return something other than unit then, indeed, let _ = expr1 or let _test = expr1 would be the way to tell the compiler that you want to explicitly ignore its return value. In general preceding a name with an underscore signals the compiler that it should not trigger an “unused” warning for that name.