Skip to content

Latest commit

 

History

History
100 lines (74 loc) · 3.2 KB

README.md

File metadata and controls

100 lines (74 loc) · 3.2 KB

defimpl

Motivation

My background is as a Lisp programmer. Objects in my programs model objects in the real world. Real world objects have identity and so do the software objects with which I model them. If I dent a car, a specific car gets dented. To achieve this requires reference rather than value/copy semantics.

Since I find Go's interface versus struct reference distinction confusing and would rather not think about it, I've chosen to define library interfaces that operate on interface objects. Also, I've found that I often wind up refacroring to pass interfaces rather than struct pointers, so why not just always start that way.

Each concrete interface requires at least one implementation though, and those implementations tend to be boilerplate code that is boring and tedious to implement and maintain. I'd like to automatically generate a canonical implementation of each concrete interface based on some direction in the interface's type definition.

Usage

The defimpl binary is a go code preprocessor which reads a source file, and produces a new source file which contains a struct definition to serve as an implementation of each interface definition in the input file, and the methods to support that implementation.

Though Go allows fields in struct definitions to have a tag which various libraies can choose to interpret in some way, this is apparently not allowed for interface method declarations.

Each field (method declaration) in an input interface definition can have comments to inform defimpl of the struct methods to be generated and the struct fields on which they operate. These are comments because interface type definitions do not support tags in the way struct definitions do. These comments employ the same canonical syntax as struct tags so that we can leverage the struct tag parsing code.

If an interface definition contains no defimpl comments of has a comment containing "(ABSTRACT)" then no implementation struct will be defined for it.

For any interface method which is meant to read or modify some field, that method sould have a signature appropriate to its intended use, and a comment of the form

	// defimpl:"verb fieldname"

where "verb" is one of the supported verb types, e.g.: read, set, append, iterate, length; and fieldname is the name of the struct field on which the method operates (performs the verb).

For example, if we have the source file tower.go

// A simple example of using defimpl.
package test

type Tower interface {
	Height() float   // defimpl:"read height"
}

then running

defimple tower.go

would generate the code

// This file was automatically generated by c:/Users/Mark Nahabedian/go/bin/defimpl.exe from c:\Users\Mark Nahabedian\go\src\defimpl\test\tower_example.go.
package test

type TowerImpl struct {
	height float
}

// Height is part of the Tower interface.
func (x *TowerImpl) Height() float {
	return x.height
}

The struct that is defined to implement an interface includes each filed named in a defimpl comment.

Defimpl is extensible. New verbs can be defined. See the verb_*.go files for examples.

The currently supported verbs are briefly described in verbs.txt.