While trying to create an Ltac definition that loops over a variable-length argument list, I encountered the following unexpected behavior on Coq 8.4pl2. Can anyone explain it to me?
Ltac ltac_loop X :=
match X with
| 0 => idtac "done"
| _ => (fun Y => idtac "hello"; ltac_loop Y)
end.
Goal True.
ltac_loop 0. (* prints "done" as expected *)
ltac_loop 1 0. (* prints "hello" then "done" as expected *)
ltac_loop 1 1 0. (* unexpectedly yields "Error: Illegal tactic application." *)
Let's expand the last invocation of
ltac_loop
to see what's happening:There you can see the problem: you are trying to apply something that is not a function to an argument, which results in the error you saw. The solution is to rewrite the tactic in continuation-passing style: