This fgg
package is a minimal and basic prototype of Featherweight Go and
Featherweight Generic Go, as presented in:
Featherweight Go
Robert Griesemer, Raymond Hu, Wen Kokke, Julien Lange, Ian Lance Taylor,
Bernardo Toninho, Philip Wadler and Nobuko Yoshida
https://arxiv.org/abs/2005.11710
Currently, many aspects of the code are quite primitive, mainly for the convenience of quick experimentation alongside the above paper. For example, types/functions/variables are not well named, except for some correspondence with the formal definitions. The tool is also not particularly user-friendly:
;
), all need to be written out explicitly;We plan to improve some of this in the near future. Contact Raymond Hu for issues related to this repository.
See this Go blog post for information about the generics design draft by the Go team, and links to their generic-to-ordinary Go translation tool (including an online playground) based on that draft.
fgg
tool supports a few features (within its fragment of Go)
that their translation tool does not. These include type parameters for
methods (for now, the latter has type parameters for types and functions
only), nomono (monomorphisability) checking, and covariant method receiver
bounds.Featherweight-go-gen is
tool that enumerates FGG programs and integrates with fgg
for
testing.
This package includes:
Package organisation:
Makefile
-- install, and for running tests and examples.main.go
-- main file.fg
-- FG AST, typing and evaluation.fgg
-- FGG AST, typing, evaluation, nomono check, and monomorphisation.examples
examples/fg
-- FG examples.examples/fg/oopsla20
-- The FG examples from the paper (i.e., Figs. 1,
2 and 7).examples/fgg
-- FGG examples.examples/fgg/oopsla20
-- The FGG examples from the paper (i.e., Figs.
3--6).parser
-- FG/FGG parsers (generated using ANTLR).
parser/FG.g4
-- FG ANTLR grammar.parser/FGG.g4
-- FGG ANTLR grammar.Use the main branch for the latest working version.
Syntax. The best source would be the formal grammars in the paper, or else see the above ANTLR grammars.
We assume a standard Go set up. That is:
$GOPATH
;src
directory in the workspace.You will also need the ANTLR v4 runtime for Go; e.g., see "Installing ANTLR v4" in this tutorial.
Clone the fgg
repo into the src
directory of your Go workspace, i.e.,
$GOPATH/src
. It should end up located at src/github.com/rhu1/fgg
. You can
also use go get
-- this should fetch ANTLR for you, but will report that it
cannot find the parser packages (that's fine, we generate them in the next step).
Next, either copy over the pre-generated parser files and install by
make install-pregen-parser
or generate the parsers yourself using ANTLR and install by
antlr4
command; e.g., java -jar [antlr-4.7.1-complete.jar]
)antlr4 -Dlanguage=Go -o parser/fg parser/FG.g4
antlr4 -Dlanguage=Go -o parser/fgg parser/FGG.g4
Finally, do:
make install
To test the install -- inside the github.com/rhu1/fgg
directory, this command
should work:
go run github.com/rhu1/fgg -eval=-1 -v examples/fg/oopsla20/fig1/functions.go
Afer installing, you can also use the resulting fgg
binary directly instead
of go run
.
This package has been tested using Go version 1.11.5+ on:
Two points:
FG and FGG always need explicit ;
separators between type/method
decls, field decls, etc., even across new lines. E.g., in FG
package main;
type A struct {};
type B struct {
f1 A;
f2 A
};
type IA interface {
m1() B;
m2() B
};
func (x0 B) foo() B { return x0 };
func main() { _ = B{A{}, A{}}.foo() }
A rule of thumb is, write all FG/FGG code as if you were writing Go without line breaks.
FGG does not support any syntactic sugar -- this means empty type declarations and type argument lists must always be written out in full. E.g., the FGG equivalent to the above is:
package main;
type A(type ) struct {};
type B(type ) struct {
f1 A();
f2 A()
};
type IA(type ) interface {
m1(type )() B();
m2(type )() B()
};
func (x0 B(type )) foo(type )() B() { return x0 };
func main() { _ = B(){A(){}, A(){}}.foo()() }
This package implements the grammars defined in the paper. E.g., a basic FGG program has the form:
package main;
/* Type and method decls -- semicolon separated */
func main () { _ = /* main has this specific form */ }
For testing purposes, the package supports this additional form:
package main;
import "fmt"; // Only fmt is allowed
/* Type and method decls -- semicolon separated */
func main () { fmt.Printf("%#v", /* This specific Printf, and only in main */ ) }
Notes:
This package additionally supports interface embedding for both FG and
FGG. E.g.,
type A(type a Any()) interface { B(a) } // Any, B are interfaces
The var
declarations used for readability in some of the examples in the paper are not supported.
Warning: Type checking and nomono errors raise a panic -- basic error messages can be found at the top of the stack trace.
The following commands can be run from the github.com/rhu1/fgg
directory.
FG type check and evaluate, with verbose printing.
go run github.com/rhu1/fgg -eval=-1 -v examples/fg/oopsla20/fig1/functions.go
-eval
is the number of steps to execute. -1
means
run to termination (either a value, or a panic due to a failed type
assertion.)-eval
includes a dynamic type preservation check (an error raises a panic).FGG type check and evaluate, with verbose printing. (Note the -fgg
flag.)
go run github.com/rhu1/fgg -fgg -eval=-1 -v examples/fgg/oopsla20/fig4/functions.fgg
FGG type check, nonomo check and monomorphisation, with verbose printing.
go run github.com/rhu1/fgg -fgg -monomc=-- -v examples/fgg/oopsla20/fig4/functions.fgg
-monomc
is a file location for the FG output. --
means print the output.Simulate FGG against its FG monomorphisation, with verbose printing.
go run github.com/rhu1/fgg -test-monom -v examples/fgg/oopsla20/fig4/functions.fgg
Makefile
tests.The following commands assume make install
, and that the resulting fgg
binary is on the $PATH
.
Running from the github.com/rhu1/fgg
directory:
make test-monom-against-go
fgg
;go
;fgg
and go
.make simulate-monom
make test-all