This is the description of warning 27 from the OCaml manual:
27 Innocuous unused variable: unused variable that is not bound with
let
noras
, and doesn't start with an underscore (_
) character.
This warning is turned on by jbuilder --dev
, and I'm curious to know in which cases people find it useful. For me, it's an annoyance to get warnings when I write code like this:
$ utop -w +27 utop # fun (x, y) -> x;; Characters 8-9: Warning 27: unused variable y. - : 'a * 'b -> 'a = <fun>
or like that:
utop # let error loc msg = failwith (loc ^ ": " ^ msg);; val error : string -> string -> 'a = <fun> utop # let rec eval = function | `Plus (loc, a, b) -> eval a + eval b | `Minus (loc, a, b) -> eval a - eval b | `Star (loc, a, b) -> eval a * eval b | `Slash (loc, a, b) -> let denom = eval b in if denom = 0 then error loc "division by zero" else eval a / denom | `Int (loc, x) -> x ;; Characters 33-36: Warning 27: unused variable loc. Characters 73-76: Warning 27: unused variable loc. Characters 112-115: Warning 27: unused variable loc. Characters 287-290: Warning 27: unused variable loc. val eval : ([< `Int of 'b * int | `Minus of 'c * 'a * 'a | `Plus of 'd * 'a * 'a | `Slash of 'e * 'a * 'a | `Star of 'f * 'a * 'a ] as 'a) -> int = <fun>
I know that prepending an underscore to the identifiers as in _loc
suppresses the warnings, but it's not compatible with my notions that:
- variables starting with an underscore are ugly and are meant for use in generated code, hidden from the programmer;
- a name given to something should not have to change based on how it's used (including unused).
Using underscores, the code becomes:
(* Here we have _loc or loc depending on whether it's used. *) let rec eval = function | `Plus (_loc, a, b) -> eval a + eval b | `Minus (_loc, a, b) -> eval a - eval b | `Star (_loc, a, b) -> eval a * eval b | `Slash (loc, a, b) -> let denom = eval b in if denom = 0 then error loc "division by zero" else eval a / denom | `Int (_loc, x) -> x
or
(* Here it can be hard to know what _ stands for. *) let rec eval = function | `Plus (_, a, b) -> eval a + eval b | `Minus (_, a, b) -> eval a - eval b | `Star (_, a, b) -> eval a * eval b | `Slash (loc, a, b) -> let denom = eval b in if denom = 0 then error loc "division by zero" else eval a / denom | `Int (_, x) -> x
Plus (_loc, a, b)
, I know that I don't need to pay attention to_loc
. Depending on the scenario,Plus (_, a, b)
can be even better; it clearly shows we only care about positional valuesa
andb
here; it doesn't matter what_
is, it's discarded/unused in the body anyway – Mulanlet add a b = a + a
. – Richard-Degenne_loc
as something auto-generated that I should probably not touch and I suppose not everyone reads it this way. – Martin Jambonlet
oras
). However I do remember reporting the wrong location in camlp4 code due to having code likelet f loc x = match x with Foo (_, y) -> error loc "..."
which should have beenlet f loc x = match x with Foo (loc, y) -> error loc "..."
. ymmv – Martin Jambon