package GT
Install
Dune Dependency
Authors
Maintainers
Sources
sha256=d379da5902e2f4017122daf4861dd4f822a862025e9a6d215454ced572da13db
sha512=fe5cb5306cf220f293c0f81b57a8de90f932d3145538e0a032f4b90b8b465ba5d9414692c194b6213014ee2cd06ce061df4541533550d89c7f63b071015104ba
doc/README.html
Datatype-generic object-oriented transformations for OCaml (a.k.a. GT)
This library implements a framework for datatype-generic programming in Objective Caml language.
The key feature of the approach in question is object-oriented representation of transformations performed over regular algebraic datatypes. Our implementation supports polymorphic variants; in particular, a transformation for a "joined" polymorphic variant type can be acquired via inheritance from the transformations for its counterparts.
See also
Installation
opam pin add GT https://github.com/PLTools/GT.git -y
or from the main opam repository
opam update
opam install GT -y
Usage
As PPX
Use findlib package GT.ppx
in combination with ppxlib
. See ppxlib
's manual for full guidance. In short do
# #use "topfind";;
# #require "GT";;
# #require "GT.ppx_all";;
../GT/ppx_all: added to search path
../GT/ppx_all/./ppx.exe --as-ppx: activated
# type 'a list = Nil | Cons of 'a * 'a list [@@deriving gt ~options:{fmt; show}];;
type 'a list = Nil | Cons of 'a * 'a list
class virtual ['ia, 'a, 'sa, 'inh, 'extra, 'syn] list_t :
object
method virtual c_Cons : 'inh -> 'extra -> 'a -> 'a list -> 'syn
method virtual c_Nil : 'inh -> 'extra -> 'syn
end
val gcata_list :
('a, 'typ0__003_, 'b, 'c, 'typ0__003_ list, 'd) #list_t ->
'c -> 'typ0__003_ list -> 'd = <fun>
class ['a, 'b] show_list_t :
(unit -> 'a -> string) ->
(unit -> 'a list -> string) ->
object
constraint 'b = 'a list
method c_Cons : unit -> 'a list -> 'a -> 'a list -> string
method c_Nil : unit -> 'a list -> string
end
class ['a, 'b] fmt_list_t :
(Format.formatter -> 'a -> unit) ->
(Format.formatter -> 'a list -> unit) ->
object
constraint 'b = 'a list
method c_Cons : Format.formatter -> 'a list -> 'a -> 'a list -> unit
method c_Nil : Format.formatter -> 'a list -> unit
end
val fmt_list :
(Format.formatter -> 'a -> unit) -> Format.formatter -> 'a list -> unit =
<fun>
val list :
(('a, 'b, 'c, 'd, 'b list, 'e) #list_t -> 'd -> 'b list -> 'e,
< fmt : (Format.formatter -> 'f -> unit) ->
Format.formatter -> 'f list -> unit;
show : ('g -> string) -> 'g list -> string >,
(('h -> 'i list -> 'j) -> ('k, 'i, 'l, 'h, 'i list, 'j) #list_t) ->
'h -> 'i list -> 'j)
GT.t = {GT.gcata = <fun>; plugins = <obj>; fix = <fun>}
val show_list : ('a -> string) -> 'a list -> string = <fun>
As Camlp5 syntax extension
Use findlib package GT.syntax.all
to enable extension and all built-in plugins. To compile and see the generated code use the following command:
ocamlfind opt -syntax camlp5o -package GT.syntax.all regression/test081llist.ml -dsource
To preprocess only the code in this library (for example, a test) use the following shell command:
dune exec camlp5/pp5+gt+plugins+o.exe regression/test005.ml
To use camlp5 (>= 7.12) syntax extension in toplevel try (after installation) this:
# #use "topfind.camlp5";;
# #camlp5o;;
# #require "GT.syntax";;
# #require "GT.syntax.all";;
# @type t = GT.int with gmap,show;; (* for example *)
Directory structure
- The framework for generation is in
common/
. The generic plugin for adding new transformations is incommon/plugin.ml
. - All built-in plugins live in
plugins/
and depend on the stuff incommon/
. - Camlp5-specific preprocessing plugin lives in
camlp5/
. Depend on stuff incommon/
. - PPX-specific preprocessing plugin lives in
ppx/
. Depends on stuff incommon/
. - Built-in plugins that represent transformations live in
plugins/
. Depends oncommon/
. - A library for built-in types and transformations for types from Pervasives live in
src/
. Depends on syntax extension fromcamlp5/
and plugins fromplugins/
.
Dependencies
ppxlib
camlp5
ocamlgraph
for topological sortingocamlbuild
as build system
Compilation
make
to compile whole library.make && make tests
to compile regression tests too.
In case some of the tests do not compile use following commands to see generated code:
- with camlp5 use
dune exec camlp5/pp5+gt+plugins+o.exe regression/test817logic.ml
- with PPX use
dune exec ppx/pp_gt.exe regression/test801mutal.ml
To build documentation set the environment variable GT_WITH_DOCS
and run opam install odoc --yes && dune build @doc
. The generated HTML files will be located at _build/default/_doc/_html/index.html
.
In the following section we describe our approach in a nutshell by a typical example.
Limitations
Known to be not supported or not taken to account:
- non-regular recursive types
- GADTs
TODO
Can be a bug:
- Method
on_record_declaration
doesn't introduce new pattern names systematically - For
compare
andeq
plugins in case of ADT with single constructor we generate unreachable pattern matching pattern that gives a warning.
Improvements:
- Documentation for
src/GT.ml
is not generated (possible because of a macro). - Better signature for
method virtual on_record_constr
. - Custom transformation functions for type parameters has become broken after introducing combinatorial interface for type abbreviations.
- Allow
[@@named "..."]
attribute to provide a custom name for non-latin constructors (like lists). - Sometimes we need override class definition for a plugin. It should be possible to specify new custom class inside the attribute.
References
- Dmitry Kosarev, Dmitry Boulytchev. Generic Programming with Combinators and Objects // submitted to ML workshop 2018
- Dmitry Boulytchev. Code Reuse with Object-Encoded Transformers // A talk at the International Symposium on Trends in Functional Programming, 2014.
- Dmitry Boulytchev. Code Reuse with Transformation Objects // unpublished.
- Dmitry Boulytchev. Combinators and Type-Driven Transformers in Objective Caml // submitted to the Science of Computer Programming.