Git Product home page Git Product logo

stencil's Introduction

Stencil - Simple code templating for Go

Stencil generates specialized versions of Go packages by replacing types. This is a prototype of this proposal. It will have bugs and only supports a subset of the features in the proposal.

Given a package with an interface A, stencil can generate a new package with all uses of A replaced by int (or any other type). The generated package is stored in the closest vendor directory of the repo. If no such directory exists, one is created.

Installation

Download stencil using

go get -u github.com/sridharv/stencil

Install with

go install github.com/sridharv/stencil/cmd/stencil

Usage

Detailed documentation is at GoDoc

Example Walkthrough

Install stencil as shown above. Then create a package to act as a stencil. Let's create a generic Sum method.

Create $GOPATH/src/example/stencil/math/math.go (or a package of your choice) containing

package math

func Sum(n...float64) float64 {
    var r float64
    for _, v := range n {
        r += v
    }
    return r
}

Now use it to compute the sum of ints by using stencil to replace float64 with int.

Create $GOPATH/src/example/usestencil/main.go (or another package of your choice) containing

package main

//go:generate stencil
import (
    "fmt"
    int_math "example/stencil/math/float64/int"
)

// PrintIntSum prints the sum of all elements of v to stdout.
func main() {
    ints := []int{1, 2, 3, 4, 5}
    fmt.Println("Sum of", v, "=", int_math.Sum(ints...))
}

Now run

 # Or the path to the main package you created
 cd $GOPATH/src/example/usestencil/ 

and then

go generate

Take a look at $GOPATH/src/example/usestencil/. It will have a vendor directory with a specialised version of example/stencil/math. You can now build and run the example with

go run main.go

Libraries

A few useful packages that lend themselves to being used with stencil.

  • github.com/sridharv/stencil/std/num - Max, Min and Sum for numbers. GoDoc
  • github.com/sridharv/stencil/std/slice - Slice utilities. GoDoc

License

Stencil is available under the Apache License. See the LICENSE file for details.

Contributing

Pull requests are always welcome! Please ensure any changes you send have an accompanying test case.

stencil's People

Contributors

sridharv avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

stencil's Issues

Proposal: Stencil - Simple code templating for Go

The Proposal

  • The generic unit is a package.
  • Specialise a package by substituting one type for another.
  • Import statements define type substitutions. example/num/float64/float32 is example/num with float64 replaced by float32.
  • Generate specialised versions of the packages in a vendor directory.
  • Use the closest vendor directory. If none exist create one.
  • Perform type substitutions with a tool that scans files for these import statements.
  • Use the tool as a format-on-save command in the editor, or run it with go generate.
  • The tool uses type inference to automatically add missing imports with type substitutions.
  • Refer to source packages as stencils. Refer to specialised versions as stencilled packages. The words “generics” and “templating” evoke a large feature set. This proposal aims to fill a smaller gap.

Pros

  • It is simple.
  • Works with existing Go tooling and workflows.
  • Using Go 1.6 vendor support provides simple import paths
  • Generated code can be committed.
  • Annotations or extra runtime dependencies are not required.
  • Any Go package can potentially be used as a stencil.
  • Type specialisation information is present in the code and not in command line tool invocations.

Cons

  • Types in a package cannot be used in import paths in the same package.
  • Import paths containing pointer, array, map and channel types are not file-system friendly.
  • Types from generated code cannot be used as part of exported types or methods in other packages, due to how vendoring works.
  • Existing Go packages may not support simple type substitution. Type asserts can lead to compile errors when substituting a concrete type for an interface.
  • Zero values will need special handling, as they will differ by type.
  • Transitive stencilling may be needed in the case of package dependencies.

More design work is needed to address the cons.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.