Giter Club home page Giter Club logo

ppx's Introduction

Ppx - Meta-programming for OCaml

This project is under construction

For more info, see this blog post.

Travis status AppVeyor status

Overview

The ppxlib project provides the basis for the ppx system, which is currently the officially supported method for meta-programming in OCaml. It offers a principled way to generate code at compile time in OCaml projects.

Ppxlib comes with a user manual aimed at both users and authors of ppx rewriters.

History

This repository was created by merging several older projects. See the history for more details.

Ppx_view

A ppx rewriter that provides pattern matching on abstract types by transforming patterns into views/expressions.

Syntax

ppx_view transforms the patterns of match/function constructs wrapped inside [%view] extensions by replacing matches against constructors with function calls.

For instance, in the following code:

match%view expr with
| Constr var -> var

the constructor Constr is turned into a call to the function constr, which is expected to be a view pattern:

val constr : (string, 'a, 'b) View.t -> (expression, 'a, 'b) View.t

Technically, the above expression is rewritten into:

Viewlib.View.match_ __POS__
    [Viewlib.View.case (constr Viewlib.View.__)
       (fun (Viewlib.View.Var_snoc (Viewlib.View.Var_nil, var)) -> var)]
    expr

where __ is used to capture the variable.

Mapping

ppx_view applies the following mapping:

  • a literal constant c of type typ is mapped to View.typ c;

  • an interval pattern c1..c2 is mapped to View.interval e1 e2 where ci is mapped to ei;

  • a variable pattern is mapped to View.__;

  • a catch-all pattern is mapped to View.drop;

  • a record pattern { lbl1 = p1; lbl2 = p2; ... } is mapped to lbl1'match e1 (lbl2'match e2 ...) where pi is mapped to ei;

  • a constructor pattern C (p1, ..., pn) is mapped to c e1 ... en where pi is mapped to ei, except for constructors from the core library:

    • Some is mapped to View.some;
    • None is mapped to View.none;
    • :: is mapped to View.cons;
    • [] is mapped to View.nil;
    • () is mapped to View.unit;
    • true is mapped to View.true_;
    • false is mapped to View.false_.

Note: the following patterns are currently not supported:

  • polymorphic variants;
  • lazy;
  • module unpacking;
  • exceptions.

Library

The Parseview module of the library contains the functions corresponding to the constructors and records from the Parsetree module. Such functions use "shortcuts" to xyz_desc fields, allowing to directly match constructors:

open Viewast

let is_zero : Parsetree.expression -> true = function%view
  | Pexp_constant (Pconst_integer ("0", _)) -> true
  | Pexp_ident { txt = Lident "zero"; _ } -> true
  | _ -> false

The access to other fields is done through a [@view ...] annotation:

open Viewast

let is_zero : Parsetree.expression -> true = function%view
  | (Pexp_constant (Pconst_integer ("0", _)))[@view { pexp_loc; }] -> true, pexp_loc
  | Pexp_ident { txt = Lident "zero"; loc; } -> true, loc
  | _ -> false, Location.none

The library also provides an Ast_viewer module that acts as the counterpart of the Ast_helper module. It allows to write patterns very similar to the corresponding expressions:

open Viewast

let twice_mapper =
  let module H = Ast_helper in
  let module M = Ast_mapper in
  let module V = Ast_viewer in
  let super = M.default_mapper in
  let expr self e =
    match%view super.expr self e with
    | V.Exp.Constant (V.Const.String (str, _)) ->
      H.Exp.constant (H.Const.string (str ^ str))
    | other ->
      other
  and pat self p =
    match%view super.pat self p with
    | V.Pat.Constant (V.Const.String (str, _)) ->
      H.Pat.constant (H.Const.string (str ^ str))
    | other ->
      other
  in
  { super with expr; pat; }

Not patterns

Following the proposal in MPR#7628, not pattern are implemented through the Not constructor, that is rewritten to View.not. Not patterns allow to write patterns that are matched if a subpattern is not matched as in:

match%view expr with
| Pexp_constant (Not (Pconst_integer _ | Pconst_float _)) ->
  (* expr is not a number *)
| Pexp_constant (Pconst_integer _) ->
  (* expr is an integer *)
| Pexp_constant (Pconst_float _) ->
  (* expr is a float *)

Not patterns cannot contain variables.

Limitations

The major limitations of view patterns are the lack of checks for non-redundancy and exhaustivity.

ppx's People

Contributors

aalekseyev avatar actionshrimp avatar ceastlund avatar hhugo avatar jeremiedimino avatar kakadu avatar khady avatar nathanreb avatar octachron avatar rgrinberg avatar trefis avatar xclerc avatar xvilka avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.