Thanks all for the discussion here so far!
@hyphenrf, you’ve already received links to the most important resources that could help you from @lambda_foo. I’ll just add some things about Ast_pattern since that’s what you seem most interested in.
There are two things you need to understand about Ast_pattern to get comfortable with it: its concept and the combinators it provides (with “combinators”, I’m referring to the functions that let you construct new ast_patterns from other ast_patterns that you already have). To get a feeling for what combinators Ast_pattern provides, it’s good to separate the Ast_pattern functions into three kinds: the special helper functions, which are the ones from alt to pack3; the “entry point” combinators pstr, psig, ptyp and ppat; and the combinators that are generated from the Parsetree module in the same way as the Ast_builder functions are generated, which are pretty much all the others.
Some background about Ast_builder to understand the last kind: for the various kinds of record fields and value constructors in the compiler Parsetree module, there are certain functions in Ast_builder that let you build the corresponding parsetree (aka AST) node. How that correspondence looks like is explained at the beginning of the docs of the Ast_builder module. Once you know how to use Ast_builder to construct a node of a certain AST type T, it will be easy to use Ast_pattern to construct an ast_pattern that matches a node of type T: if there’s an Ast_builder.Default function foo to construct a node of AST type T, then there’s also an Ast_pattern function foo to construct the corresponding ast_pattern that matches such nodes of type T. That’s explained at the beginning of the docs of the Ast_pattern module with an example. Do you have questions about that example?
That example also uses the entry point pstr. Unless your pattern is simple enough to use one of ppxlib’s helper functions directly (such as single_expr_payload), you will always need one of the four entry point functions pstr, psig, ptyp or ppat. Which of the four entry point functions you should choose, depends on what kind of payload you want the user to pass in to your extension node (or deriver): a structure, a signature, a core type, or a pattern (you have some info on that in one of the sections of the blog post @lambda_foo has pointed you to). The most common situation is having a structure as payload and hence using pstr. In that situation, you need to construct an ast_pattern, that matches values of type structure (I’ve explained how to do that via the generated functions in the last paragraph. apart from that, you can also use the special helper functions), and pass that ast_pattern to pstr.
To pick up your example about Ast_pattern.(pstr nil): One of the sections in the mentioned blog post explains Ast_pattern a bit. At the end of that section, it’s pointed out that Ast_pattern.(pstr nil) is the pattern you need to “prohibit a payload”. However, I think what you want to understand is why that’s the pattern you need. As explained, you need to construct an ast_pattern that matches values of type structure and pass that ast_pattern to pstr. Now, why is the ast_pattern you want to pass to pstr given by nil? That’s because structure is defined as a list of structure items. Since you don’t want any payload at all, you want a pattern matching the empty list. That’s what nil does.
All that being said, our documentation is really not complete enough and
Something seems to be missing. There’s just so little info online on it.
is definitely not the kind of user experience we want folks to have when using ppxlib. We have two things on our near-future to-do list that will hopefully improve that situation. One is making the different docs (info on blog posts, user manual, API docs) easier to find and available at the same place. And the other one is adding a section to the user manual on how to construct (Ast_builder and metaquot) and destruct (Ast_pattern and metaquot) AST nodes. @Kakadu, if you want to give that a go (or, if you prefer, only the part about Ast_pattern), that’s awesome!
Edit: Apart from getting a general understanding about how Ast_pattern works and understanding the example of Ast_pattern.(str nil), what you most seem to be struggling with are the special Ast_pattern helper functions (which, in my classification above, are the “first kind” of Ast_pattern functions). What I’ve tried to do with my answer was to help you (and others) understand how Ast_pattern works in general which should help getting a better grip on all of Ast_pattern, including the helper functions. I haven’t explained the helper functions the way I did with the other two kinds of functions (i.e. in a general way), since that doesn’t really work given that all of them have their own individual behavior. So what needs to be done for them is adding documentation to the API of each of those helper functions. I’ll take note of that for our todo-list 