This seems difficult-to-impossible to achieve in the current model of PPX type-derivers. It would require carrying information about type declarations alpha, beta, and how they were processed by PPX derivers forward to type declaration t. That breaks the model of PPX derivers, which would seem to specify that each type-declaration is treated independently of all that precede and all that follow.
A possible workaround might be to require that all three types be put in a single recursive typedecl. But then the model is that all three types are derived, which means you’d have a getter named a1 for both types alpha and t. And similarly for setters.
It seems difficult to see how one comes up with a coherent model for how such a deriver should work. BUT, once one came up with such a sensible model, I think this should be almost trivial to implement.
Do you have a well-fleshed-out proposal for how this should work ?
I’ve been doing an external code generation (i.e. not ppx-based) for the game project I’m working on. So, in a sense yes, but since your question is more likely about ppx-based methods specifically, then no.
I would like to invite a discussion on how to approach this problem in more general way than through PPX, if PPX has limitations (not just in current incarnation, but in its underlying idea) that make it not the right tool for the job. I do not mind code-generation, but I would appreciate a methodology that would not e.g. rely on using Coq to hand-roll my own code generators.
The approach I’m taking is generating OCaml code with a tool that is closely coupled with the language itself, namely Coq. However, that feels a bit too black-belt for more casual code.
@Chet_Murthy@techol I could change my original question to the following one. In practice, it should work as well, and may forgo the technicalities that arise with an attempt to use PPX in the original case.
How could we generate
type t =
{
a1 : int ;
a2 : float ;
b1 : int ;
b2 : string ;
}
[@@deriving fields]
from two known record types alpha and beta (defined above), using PPX, and how could we define corresponding conversion functions.
@Chet_Murthy If the alpha and beta are known record types, we should be able to pull this off with the current approach. Other type constructs could simply be rejected. What do you think?
It seems that somehow my reply to you has gotten lost, so I’ll rewrite it. When you write
If the alpha and beta are known record types
I think it would be useful to be precise as to what type-derivers are given by the PPX machinery. Suppose we have the following three typedecls, each of which defines a single type:
type alpha = <blabla>
type beta = <blabla>
type t = alpha * beta [@@deriving fields]
The deriver “fields” is given the typedecl to which it is an annotation, and nothing more. It is not given the preceding type-decls, nor any environment for looking up type information (which does not exist, b/c PPX rewriting happens immediately after parsing, and long before any type-checking). In a similar way, in the single typedecl which defines three types:
type alpha = <blabla>
and beta = <blabla>
and t = alpha * beta [@@deriving fields]
the type-deriver is given the entire type-decl, which consists three types, and so the deriver “knows” the type definitions of alpha and beta. So perhaps you could do something like [@@deriving fields {ignore=[alpha;beta], flatten=[t]}] ? This might tell the deriver to not generate field-accessors for those two types, but of course, it could go ahead and use them for generation on other types (viz. t). And for type t, it could be told to “flatten” the type for purposes of generating accessors.
Perhaps that would meet your needs? If so, it should be straightforward to modify the ppx_fields_conv deriver to do what you want, I would think.