Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file ast_builder_intf.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292openAstlibopenPpxlib_ast.AsttypesopenPpxlib_ast.ParsetreemoduletypeS=sigtype'awith_loctypearrow_argument:=Shim.arrow_argumenttypearrow_result:=Shim.arrow_resulttypemodality:=Shim.Modality.ttypemodalities:=Shim.Modalities.ttypemodes:=Shim.Modes.ttypeinclude_kind:=Shim.Include_kind.tmodulePcstr_tuple_arg:=Shim.Pcstr_tuple_arg(** {2 Modes} *)(** Construct a [Ptyp_arrow] *)valptyp_arrow:(arrow_argument->arrow_result->core_type)with_loc(** Construct a multi-argument arrow type with the provided arguments and result.
@raise [Invalid_argument] if the input list is empty. *)valtarrow:(arrow_argumentlist->arrow_result->core_type)with_loc(** As [tarrow], but will return the result if the input list is empty rather than
erroring; this means the result type cannot have a mode annotation. *)valtarrow_maybe:(arrow_argumentlist->core_type->core_type)with_loc(** Construct a [Pexp_constraint] with modes *)valpexp_constraint:(expression->core_typeoption->modes->expression)with_loc(** Construct a [Ppat_constraint] with modes *)valppat_constraint:(pattern->core_typeoption->modes->pattern)with_loc(** Contruct a [value_binding] with modes *)valvalue_binding:(pat:pattern->expr:expression->modes:modes->value_binding)with_loc(** Construct a [Pcstr_tuple], a representation for the contents of a tupled variant
constructor, that attaches the provided modalities to each field. *)valpcstr_tuple:((modalitylist*core_type)list->constructor_arguments)with_loc(** Construct a [Psig_include] with modalities *)valpsig_include:(modalities:modalities->include_description->signature_item)with_loc(** Construct a [Pcstr_tuple], a representation for the contents of a tupled variant
constructor, that attaches no modalities to any field. Equivalent to [pcstr_tuple]
with every [modality list] being [None] *)valpcstr_tuple_no_modalities:core_typelist->constructor_arguments(** Splits a possibly-modality-annotated field of a tupled variant constructor into a
pair of its modality and the unannotated field. If the resulting mode is [None],
then the field is returned unchanged. *)valget_tuple_field_modalities:Pcstr_tuple_arg.t->modalitylist*core_type(** Splits a possibly-modality-annotated label declaration into a pair of its modality
and the unannotated label declaration. If the resulting modality is [None], then
the label declaration is returned unchanged. *)valget_label_declaration_modalities:label_declaration->modalitylist*label_declarationvallabel_declaration:(name:stringLocation.loc->mutable_:mutable_flag->modalities:modalitylist->type_:core_type->label_declaration)with_locvalget_value_description_modalities:value_description->modalitylist*value_descriptionvalvalue_description:(name:stringLocation.loc->type_:core_type->modalities:modalitylist->prim:stringlist->value_description)with_locvalpcstr_tuple_arg:(modalities:modalitylist->type_:core_type->Pcstr_tuple_arg.t)with_locvalinclude_infos:(?attrs:attributes->kind:include_kind->'a->'ainclude_infos)with_loc(** {2 N-ary functions} *)(** Many comments below make reference to the Jane Street compiler's treatment of
function arity. These comments refer to a parsetree change made to upstream OCaml in
https://github.com/ocaml/ocaml/pull/12236, but that Jane Street has mirrored
internally already.
The treatment of arity can be summarized as follows:
- In a previous version of OCaml, a function's runtime arity was inferred at a
late stage of the compiler, after typechecking, where it fuses together
nested lambdas.
- In the new version of OCaml (both upstream OCaml after #12236 and the
internal Jane Street compiler), a function's runtime arity is purely a syntactic
notion: it's the number of parameters in a [fun x1 ... xn -> body] construct,
with some special allowances for function cases.
Why is arity important? In native code, application sites of a function to [n]
syntactic arguments will trigger a fast path (where arguments are passed in
registers) only if the function's runtime arity is [n].
As a result, ppxes must take more care than before to generate functions of the
correct arity. Now, a nested function like [fun x -> fun y -> e] has arity 1
(returning still another function of arity 1) instead of arity 2. All bindings
below that construct functions are documented as to the arity of the returned
function.
Some examples of arity:
- 2-ary function: [fun x y -> e]
- 1-ary function returning 1-ary function: [fun x -> fun y -> e]
- 3-ary function: [fun x y -> function P1 -> e1 | P2 -> e2]
- 2-ary function returning 1-ary function: [fun x y -> (function P1 -> e1 | P2 -> e2)]
- 2-ary function returning 1-ary function: [fun x -> function P1 -> function P2 -> e]
Notably, unparenthesized [function] has a special meaning when used as a direct body
of [fun]: the [function] becomes part of the arity of the outer [fun]. The same
does not apply for multiple nested [function]s, even if they each have a single
case; the nested [function]s are treated as unary. (See the last example.)
*)typefunction_param=Shim.Pexp_function.function_paramtypefunction_constraint=Shim.Pexp_function.function_constrainttypefunction_body=Shim.Pexp_function.function_bodymoduleLatest:sig(** Avoid shadowing [pexp_function] in Ppxlib's AST builder. *)valpexp_function:(?attrs:attributes->function_paramlist->function_constraintoption->function_body->expression)with_locend(** Create a function with unlabeled parameters and an expression body. Like
{!Ppxlib.Ast_builder.eapply}, but for constructing functions.
[coalesce_fun_arity] is relevant for the Jane Street compiler. By default,
[coalesce_fun_arity] is [true].
Suppose there is a call [eabstract pats body ~coalesce_fun_arity]
- If [colaesce_fun_arity] is [true], the arity of the returned function
is the same as the arity of:
[add_fun_params (List.map params ~f:(Fun.param Nolabel)) body]
- If [coalesce_fun_arity] is [false], then the arity of the returned function
is the length of [pats].
In other words, [coalesce_fun_arity = true] allows you to build up the arity of
an already-constructed function rather than necessarily creating a new function.
*)valeabstract:(?coalesce_fun_arity:bool->?return_constraint:core_type->patternlist->expression->expression)with_loc(** [unary_function cases] is [function <cases>]. When used with the Jane Street
compiler, the function's runtime arity is 1, so the fast path for function
application happens only when application sites of the resulting function receive
1 argument. To create a function with multiple argument that pattern-matches on
the last one, use [add_param] or [add_params] to add more parameters.
Alternatively, use [pexp_function] to provide all parameters at once.
The attributes of the resulting expression will be the [attrs] argument together
with any attributes added by the Jane Street compiler.
*)valunary_function:(?attrs:attributes->caselist->expression)with_loc(** [fun_param lbl pat] is [Pparam_val (lbl, None, pat)]. This gives a more
self-documenting way of constructing the usual case: value parameters without
optional argument defaults.
*)valfun_param:(arg_label->pattern->function_param)with_loc(** Say an expression is a "function" if it is a [Pexp_fun] or a [Pexp_function].
All functions have parameters and arity.
Suppose [add_param lbl def pat e ==> e']. Then, letting
[param = Pparam_val (lbl, def, pat)],
- If [e] is a function with arity [n], then [e'] is a function with arity [n+1].
[param] is added at the outermost layer. For example, if
[e = fun <params> -> <body>], then [e' = fun <param :: params> -> body].
The attributes on the resulting expression will be the [attrs] argument
together with any attributes already present on [e].
- If [e] is not a function, then [e'] is a function with arity [1], namely:
[fun <param> -> <e>]. The attributes of the resulting expression will be the
[attrs] argument together with any attributes added by the Jane Street compiler.
*)valadd_fun_param:(?attrs:attributes->?return_constraint:core_type->arg_label->expressionoption->pattern->expression->expression)with_loc(** [add_params params e] is [List.fold_right params ~init:e ~f:add_param].
Note the [fold_right]: if [e] is [fun <params'> -> <body>], then
[add_params params e] is [fun <params @ params'> -> <body>].
*)valadd_fun_params:(?attrs:attributes->?return_constraint:core_type->function_paramlist->expression->expression)with_loc(** This operation is a no-op, except as interpreted by the Jane Street compiler.
If [e] is a function with arity [n] with an expression body that itself is
a function with arity [m], then [coalesce_fun_arity e] is a function of arity
[n + m].
You should usually call [coalesce_fun_arity] on metaquot fun expressions whose body
may be a function, e.g.:
[coalesce_fun_arity [%expr fun x y -> [%e possibly_function]]]
*)valcoalesce_fun_arity:expression->expression(** {2 Unboxed types} *)valptyp_unboxed_tuple:((stringoption*core_type)list->core_type)with_locvalpexp_unboxed_tuple:((stringoption*expression)list->expression)with_locvalppat_unboxed_tuple:((stringoption*pattern)list->closed_flag->pattern)with_loc(** {3 Expression literals} *)(** e.g. [#42L] *)valeint64_u:(int64->expression)with_loc(** e.g. [#42l] *)valeint32_u:(int32->expression)with_loc(** e.g. [#42n] *)valenativeint_u:(nativeint->expression)with_loc(** e.g. [#42.] *)valefloat_u:(float->expression)with_loc(** {3 Pattern literals} *)(** e.g. [#42L] *)valpint64_u:(int64->pattern)with_loc(** e.g. [#42l] *)valpint32_u:(int32->pattern)with_loc(** e.g. [#42n] *)valpnativeint_u:(nativeint->pattern)with_loc(** e.g. [#42.] *)valpfloat_u:(float->pattern)with_locendmoduletypeS_with_implicit_loc=Swithtype'awith_loc:='amoduletypeS_with_explicit_loc=Swithtype'awith_loc:=loc:Location.t->'amoduletypeAst_builder=sig(** Jane Street-internal extensions to {!Ppxlib.Ast_builder}. The bindings below
([Default], [Make], etc.) are parallel to bindings exported from
[Ppxlib.Ast_builder]. *)moduletypeS_with_implicit_loc=S_with_implicit_locmoduleDefault:S_with_explicit_locmoduleMake(_:sigvalloc:Location.tend):S_with_implicit_locvalmake:Location.t->(moduleS_with_implicit_loc)end