pa_macro: __LOCATION__ and DEFINE interaction #5456
Original bug ID: 5456
I'm trying to use pa_macro to generate compile-time IDs. For this puepose I defined something like
let register name f =
DEFINE Rfun(f) = (register LOCATION f);;
Rfun(fun _ -> 10);;
However, I notice that LOCATION always returns the same location, namely where this word occurs in the source code. This is very unfortunate in conjuction with DEFINE: One is normally interested in the location of the caller of the macro, but not in the location of the macro itself.
A better mechanism would be something like LOCATION_OF(id) where id would be a macro parameter. It would return the location of the actual parameter (i.e. where the macro is called).
As we are at it: LOCATION generates a Loc.t value. This means I have to link in camlp4 into the executable - which makes it slightly harder to use (it took 30 minutes to locate the signature of Loc, and to find Loc.to_string). It would be more useful if it just generated the location tuple, or even just a string.
Comment author: @gasche
The workaround is to pass LOCATION as an argument of the macro, at the usage site. It's a bit heavier but frankly bearable.
That is not exactly true. LOCATION expands to "Loc.of_tuple ". You can link and use Camlp4's Loc module, but you can equally well define your own Loc module, where of_tuple is just the identity, to get the tuple directly without linking anything. That's admittedly a hack (like the people that shadow Array.get to use the array indexing notation...), but a very reasonable workaround; and I consider this is by design.
Besides, it would be quite difficult to change this without breaking backward compatibility. On the contrary, it seems reasonable -- if technically feasible -- to try to expand LOCATION after expanding macro definitions, rather than before; that's a change in behavior, but maybe not compatibility-breaking (LOCATION should only be used for end-user reporting anyway).