The semantics you propose is inherently stateful: delays accumulates some state and [@@visitors]'s meaning (nitpick: I think it should be a floating attribute, [@@@visitors]) depends on the current state. You could design a similar facility using names for references instead of implicit state: type foo = Bar | Baz let x : foo option ref = ref None [@@@deriving.for foo (visitors)] (If we had access to the type-checking environment, [@@deriving.for p] could be valid for any qualified identifier p that points to a transparent definition in the current environment. Given the current ppx pipeline, I suppose that would have to be restricted to being in the syntactic scope of an actual declaration.) Hongbo Zhang introduced a similar "deriving from a distance" feature in his preprocessor Fan, for the reason you give, and also to allow deriving boilerplate code of datatypes defined in third-party libraries without having to modify them directly. On Wed, Jan 4, 2017 at 8:08 AM, François Pottier wrote: > > Hello all, > > I am currently in the process of writing a ppx_deriving plugin, called > "visitors". Overall, this has been a pleasant experience; a few hundred > lines > of code have been sufficient to obtain nontrivial results. > > In normal use, the user writes something like this: > > type foo = > Bar | Baz > [@@deriving visitors] > > and some generated code is inserted just after the definition of the type > foo. > > However, I have reached a situation where the generated code cannot be > placed > just after the type definition. That is, I need to allow user-written code > to > appear after the type definition and before the generated code. > > For instance, this user-written code could be a declaration of a global > variable "x", whose type is "foo ref", and which the generated code uses. > The > declaration of "x" must appear after the definition of the type "foo", > because > the type of "x" mentions "foo". And the declaration of "x" must appear > before > the generated code, because the generated code (intentionally) refers to > "x". > > I am imagining that perhaps the user could write something like this: > > type foo = > Bar | Baz > [@@deriving visitors { delayed = true } > > let x : foo option ref = > ref None > > [@@visitors] > > The effect of the flag { delayed = true } would be to store the generated > code > somewhere in memory (instead of emitting right away), and the effect of the > floating attribute [@@visitors] would be to fetch that code from memory and > emit it. > > To me, this seems somewhat ugly, but workable. Does ppx_deriving offer a > better approach? Does anyone have a better suggestion? Comments are > appreciated. > > Best regards, > > -- > François Pottier > francois.pottier@inria.fr > http://gallium.inria.fr/~fpottier/ > > -- > Caml-list mailing list. Subscription management and archives: > https://sympa.inria.fr/sympa/arc/caml-list > Beginner's list: http://groups.yahoo.com/group/ocaml_beginners > Bug reports: http://caml.inria.fr/bin/caml-bugs >