Skip to content

Support 5.5 with ppx#47

Open
brandonzstride wants to merge 4 commits intoLexiFi:masterfrom
brandonzstride:support-5.5
Open

Support 5.5 with ppx#47
brandonzstride wants to merge 4 commits intoLexiFi:masterfrom
brandonzstride:support-5.5

Conversation

@brandonzstride
Copy link
Copy Markdown
Contributor

Summary

This PR adds ppx support for the new language features in OCaml 5.5.

Polymorphic function parameters and modular explicits in OCaml 5.5 both require type annotations, so the eta-expansion done by the ppx is now nontrivial; it must preserve type annotations. With type annotations come optional arguments with default values, which contain expressions that may depend on previous arguments, so previous arguments should not be renamed in order for type annotations to work. Thankfully, as far as I can tell, polymorphic parameters cannot be optional, and there is no syntax for optional or labelled modular explicits. Hence, neither needs to be handled.

The code in this PR does not depend on OCaml 5.5, and it works for previous versions with only one small regression: unpacked module arguments cannot shadow each other, which seems like a silly programming pattern anyways.

(* Since module names are kept during unpacking, shadowing is now an error. *)
let[@landmark] shadow ((module M) : (module S)) ((module M) : (module S)) =
  ()

Reviewing

This PR is implemented in four commits, the first two of which are not actually required for 5.5 support and are just general upgrades. This PR seems best reviewed commit-by-commit.

  1. Add tests corresponding to the examples in Update for ppxlib 0.36.0 compatibility #45
  2. Maximally eta-expand functions so that the timing of a function does not happen until it is fully applied. The previous behavior used a function called max_list that actually returned a minimum list. It seemed like a typo, and this commit fixes it and adds a test.
  3. Keep type annotations for polymorphic parameters. Also keep attributes, which may silence warnings and should be kept on the new value binding (found while instrumenting opam; see testing below) so that the new value binding continues to silence such warnings.
  4. Unpack module arguments so that module-dependent functions can compile.

I comment the code quite extensively because I did not exactly have an easy time figuring out how to eta-expand these two new features. It was simpler than I first expected, but since the details are quite implicit in the parse tree, it felt necessary to explain what's happening.

Testing

I have added tests to cover the features. Since optional arguments seemed to be an edge case, I used Sherlocode (see link below) to look for optional module arguments, and it seems no code will be broken by these updates. opam uses optional first class module arguments frequently, so I instrumented all of opam with --auto (nearly 60_000 lines), and it all compiled without issue.

The tests include some classic modular explicits code, but I did not fully stress test because I don't have a wealth of examples for this new feature.

The tests pass with dune test (and instrumented opam builds) on OCaml 5.5.0~alpha1 with ppxlib release 0.38.0, and also on OCaml 5.4 with ppxlib release 0.37.0.

Optional module arguments in the ecosystem: https://sherlocode.com/?q=%3F%5Cw%5C*%3A%5C((module

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants