Hi! I started using ppxlib quite heavily recently, and it's super useful, thanks! However, I find that having to pass a ~loc to all constructors / having to always have a loc variable in scope is a bit tedious, and sometimes leads to overly verbose code.
In my ppx deriver I defined a tiny wrapper around all constructors that take in a ~loc, and defined a simple algebraic effect to instead store the location without having to make it explicit. The implementation is just this:
open Ppxlib
open Ast_builder.Default
type _ Effect.t += Get_loc : location Effect.t
let with_loc (loc : location) f =
let open Effect.Deep in
try f () with effect Get_loc, k -> continue k loc
let get_loc () = Effect.perform Get_loc
let ( let@ ) = ( @@ )
(* Override anything we need *)
let pexp_ident x = pexp_ident ~loc:(get_loc ()) x
let ppat_any () = ppat_any ~loc:(get_loc ())
(* etc ... *)
(* Usage is simple! *)
let@ () = with_loc my_loc in
let my_ident = pexp_ident (Lident "foo") in ...
This allows me to write the ppx without having to worry about locations: I just wrap the top-most element with the location i care about, and optionally re-wrap sub-items if i want a more precise location there. I still need a loc in scope when using the ppx, but that just requires a let loc = get_loc ()
Is this something that would be of interest to other users of ppxlib? I would be happy to open a PR and add this as an optional replacement to Ast_builder.Default. Or does this go completely against the intended use of locations? At least in our codebase this has proven quite useful :)
Hi! I started using ppxlib quite heavily recently, and it's super useful, thanks! However, I find that having to pass a
~locto all constructors / having to always have alocvariable in scope is a bit tedious, and sometimes leads to overly verbose code.In my ppx deriver I defined a tiny wrapper around all constructors that take in a
~loc, and defined a simple algebraic effect to instead store the location without having to make it explicit. The implementation is just this:This allows me to write the ppx without having to worry about locations: I just wrap the top-most element with the location i care about, and optionally re-wrap sub-items if i want a more precise location there. I still need a
locin scope when using the ppx, but that just requires alet loc = get_loc ()Is this something that would be of interest to other users of ppxlib? I would be happy to open a PR and add this as an optional replacement to
Ast_builder.Default. Or does this go completely against the intended use of locations? At least in our codebase this has proven quite useful :)