package GT
Install
dune-project
Dependency
Authors
Maintainers
Sources
sha256=d379da5902e2f4017122daf4861dd4f822a862025e9a6d215454ced572da13db
sha512=fe5cb5306cf220f293c0f81b57a8de90f932d3145538e0a032f4b90b8b465ba5d9414692c194b6213014ee2cd06ce061df4541533550d89c7f63b071015104ba
Description
Yet another library for generic programming. Provides syntax extensions both for camlp5 and PPX which allow decoration of type declarations with following compile-time code generation. Provides the way for creating plugins (compiled separately from the library) for enchancing supported type transformations.
Strongly reminds the visitors library from François Pottier.
During desing of a library of these kind there many possible
design decision and in many cases we decided to implement
the decision opposite to the one used in visitors.
P.S. Since 2023 development team is no longer associated with JetBrains Research
Published: 26 Mar 2025
README
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 -yor from the main opam repository
opam update
opam install GT -yUsage
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 -dsourceTo 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.mlTo 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
ppxlibcamlp5ocamlgraphfor topological sortingocamlbuildas build system
Compilation
maketo compile whole library.make && make teststo 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_declarationdoesn't introduce new pattern names systematically - For
compareandeqplugins in case of ADT with single constructor we generate unreachable pattern matching pattern that gives a warning.
Improvements:
- Documentation for
src/GT.mlis 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.
Dependencies (11)
-
conf-m4
build -
bisect_ppx
build -
logger-p5
build -
ocamlfind
build - ppx_inline_test_nobase
- ocamlgraph
-
camlp5
>= "8.00.05" -
ppxlib
<= "0.34.0" - dune-configurator
-
dune
>= "3.16" -
ocaml
>= "4.14" & < "5.0.0" | >= "5.3.0" & < "5.4.0"
Conflicts
None