-
Notifications
You must be signed in to change notification settings - Fork 40
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #356 from ejgallego/serlib+readme_gadt
[serlib] [doc] Add some readme with serlib documentation.
- Loading branch information
Showing
1 changed file
with
102 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,105 @@ | ||
## Serlib README | ||
|
||
### Builtins | ||
Welcome to `coq-serlib` README. | ||
|
||
### | ||
`coq-serlib` is a library that declares missing serialization | ||
functions (from/to JSON, sexp), comparison, and hash functions for | ||
most Coq datatypes, allowing users to serialize full ASTs faithfully | ||
for example, and many other interesting use cases. | ||
|
||
`coq-serlib` also includes support for [Coq's extensible syntax]() and | ||
plugins. | ||
|
||
### Builtins and Configuration | ||
|
||
`serlib` provides some builtins and configuration values in the | ||
`Serlib_base` and `Serlib_init` modules. | ||
|
||
### Serializing opaque and private types | ||
|
||
`serlib` uses `ppx_import` to retrieve the original type definitions | ||
from Coq; when these are not available, we provide some helpers in the | ||
`SerType` module. Current helpers are: | ||
|
||
- `Biject`: use when it is convenient to provide an isomorphic type to | ||
the one that is "opaque". | ||
- `Pierce`: use when it is not possible to access the type, you really | ||
want to use a copy + `Obj.magic` | ||
- `Opaque`: when you want to declare the type as non-serializable | ||
|
||
**note**: use of `Obj.magic` is now prohibited, all the type piercings | ||
need to use the `Pierce` functor. | ||
|
||
### Serializing GADTS | ||
|
||
Unfortunately, it is not possible to easily serialize GADTS. For now, | ||
we use a very ugly workaround: we basically copy the original Coq | ||
datatype, in non-GADT version, then we pierce the type as their | ||
representation is isomorphic. | ||
|
||
We will use an example from https://github.com/coq/coq/pull/17667#issuecomment-1714473449 : | ||
|
||
```ocaml | ||
type _ gen_pattern = GPat : Genarg.glob_generic_argument -> [ `uninstantiated ] gen_pattern | ||
``` | ||
|
||
In this case, we could indeed derive a serialization function (try | ||
`[@@deriving of_sexp]` for example), however full serialization is | ||
harder, so we may need to provide an alternative data-type: | ||
|
||
```ocaml | ||
module GenPatternRep : SerType.Pierceable1 = struct | ||
type 'a t = 'a Pattern.gen_pattern | ||
type _ _t = GPat of Genarg.glob_generic_argument | ||
[@@deriving sexp,yojson,hash,compare] | ||
end | ||
module GenPatternSer = SerType.Pierce1(GenPatternRep) | ||
type 'a gen_pattern = GenPatternSer.t [@@deriving sexp,yojson,hash,compare] | ||
``` | ||
|
||
and here you go! The main problem with this approach is that it | ||
requires a manual check for each use of `Pierce` and each Coq | ||
version. Fortunately the numbers of `Pierce`'s so far have been very | ||
low. | ||
|
||
### Pre-release checks | ||
|
||
Due to the above, when updating SerAPI for a new release to OPAM, we | ||
must check that the definitions we are piercing are up to date. | ||
|
||
I perform this check with Emacs + Merlin for OCaml: | ||
|
||
- I do `vc-git-grep` for `Pierce(` and `Pierce1(` | ||
- For each use, I use merlin to jump to the original type | ||
- I compare update these types | ||
|
||
That's painful, but takes like 10 minutes, so for now it is doable a | ||
couple of times a year. To illustrate, these are the current | ||
occurrences to check: | ||
|
||
``` | ||
serlib/plugins/ltac2/ser_tac2expr.ml:module T2E = Serlib.SerType.Pierce(T2ESpec) | ||
serlib/plugins/ltac2/ser_tac2expr.ml:module GT2E = Serlib.SerType.Pierce(GT2ESpec) | ||
serlib/ser_cooking.ml:module B_ = SerType.Pierce(CIP) | ||
serlib/ser_environ.ml: include SerType.Pierce(PierceSpec) | ||
serlib/ser_float64.ml:include SerType.Pierce(PierceSpec) | ||
serlib/ser_impargs.ml:module B_ = SerType.Pierce(ISCPierceSpec) | ||
serlib/ser_names.ml:include SerType.Pierce(MBIdBij) | ||
serlib/ser_names.ml: include SerType.Pierce(PierceSpec) | ||
serlib/ser_names.ml: include SerType.Pierce(PierceSpec) | ||
serlib/ser_numTok.ml: include SerType.Pierce(PierceSpec) | ||
serlib/ser_opaqueproof.ml:module B_ = SerType.Pierce(OP) | ||
serlib/ser_opaqueproof.ml:module C_ = SerType.Pierce(OTSpec) | ||
serlib/ser_rtree.ml:include SerType.Pierce1(RTreePierce) | ||
serlib/ser_sList.ml:include SerType.Pierce1(SL) | ||
serlib/ser_safe_typing.ml:module B_ = SerType.Pierce(PC) | ||
serlib/ser_sorts.ml:include SerType.Pierce(PierceSpec) | ||
serlib/ser_stateid.ml:include SerType.Pierce(SId) | ||
serlib/ser_univ.ml: module PierceImp = SerType.Pierce(PierceSpec) | ||
serlib/ser_univ.ml: include SerType.Pierce(PierceSpec) | ||
serlib/ser_univ.ml: include SerType.Pierce(ACPierceDef) | ||
serlib/ser_vmemitcodes.ml:module B = SerType.Pierce(PierceToPatch) | ||
``` |