Aboriginal Generics: the future is here!

Inspired by this gem of an idea (click the image to go to the original comment):

Installation

go get github.com/vasilevp/aboriginal/cmd/aboriginal

Example Usage

command line

aboriginal -i ᐸinput_fileᐳ -o ᐸoutput_fileᐳ

You can omit both -i and -o, in which case STDIN/STDOUT will be used.

go:generate example

Create main.go with the following contents:

//go:generate aboriginal -i main.go -o main.gen.go

package main

import "fmt"

type T interface{} // template argument placeholder

type OptionalᐸTᐳ struct {
	Value T
	Valid bool
}

func main() {
	optInt := Optionalᐸintᐳ{
		Value: 42,
		Valid: true,
	}

	fmt.Printf("%T %+v\n", optInt, optInt)

	optFloat := Optionalᐸfloat64ᐳ{
		Value: 42.42,
		Valid: true,
	}

	fmt.Printf("%T %+v\n", optFloat, optFloat)
}

Then run it by calling

go generate && go run *.go

You should get the following output:

main.Optionalᐸintᐳ {Value:42 Valid:true}
main.Optionalᐸfloat64ᐳ {Value:42.42 Valid:true}

How does it work?

The algorithm is fairly simple:

  1. Parse the source file
  2. Remember all struct declarations of the form XᐸTᐳ
  3. For any reference to XᐸYᐳ, where Y is an arbitrary type, generate an implementation of XᐸTᐳ, replacing T with Y for all member types (verbatim)
  4. Additionally, if there are any known methods defined for XᐸTᐳ, generate implementations for those as well, replacing XᐸTᐳ with XᐸYᐳ in receiver type
  5. Run imports.Process() (the core of goimports) on the resulting file to fix any unused imports (necessary since all imports are copied verbatim from the original file)

TODO

  • Implement basic generic generation
  • Implement generic methods support
  • Implement proper import handling (sort of works)
  • Implement generic functions

Disclaimer

This project is a joke. Please, for the love of go, don’t use in production.

GitHub

https://github.com/vasilevp/aboriginal