Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: use type declarations for template declarations and instantiations #18

Open
myitcv opened this issue May 3, 2017 · 1 comment

Comments

@myitcv
Copy link
Contributor

myitcv commented May 3, 2017

This proposal came about because of the following use case:

import _ "github.com/blah/model"

//go:generate gotemplate "github.com/ncw/gotemplate/set" mySet(*model.Person)

Notice the side effect import of "github.com/blah/model"; model is referenced in the template instantiation

In a local branch of github.com/ncw/gotemplate I've modified the template instantiation code to also add imports referenced in the instantiation to the output file (looks through the *ast.ImportSpecs in the *ast.File that contains the instantiation).

This works, but it's a bit brittle because the instantiation is just a comment... for example in situations where one of the type parameters is a qualified identifier for a package that is not imported (because that package is not referenced anywhere else in the file).

Notice I'm totally ignoring . imports... on the basis they are viewed as bad practice

So this got me thinking, could we instead switch to "special" type declarations as a means of declaring and instantiating templates?

package blah

// Template declarations take the form Template*. Exporting
// these types ensures they will be visible in godoc by default
// which is useful
//
// They must be a func type with no results
//
// The names of the parameters are irrelevant; only the types
// are used
//
type TemplateSet func(a A)
type A int

and then at an instance site:

package bing

import "github.com/mypkgs/blah"

//go:generate gotemplate

// Template instantiations take the form _Template*. The underscore
// ensures the type is _not_ exported (and also that it's sufficiently differentiated
// from other non-exported types in the package)
//
// The name that follows _Template* is irrelevant.. its type must be a func type
// according to the following rules:
//
// The template being instantiated is referenced as the type of the single result 
// of the func type. The name of that result must be provided
// and that name will be used for the template instance
//
// The number of func parameters must match that of the template being instantiated
// and the types of the parameters are replaced position-wise
//
type _Template1 func(s string) (Blah blah.TemplateSet)

Thoughts?

@igrmk
Copy link
Collaborator

igrmk commented Dec 13, 2018

Currently #29 is merged. It applies automatic import fixes like when you run goimports. Also now (starting from Go 1.9) there is a possibility to use type aliases. I think it is a better solution for this particular case because a syntax is still concise and readable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants