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