func AddTagFn(tagname string, fn interface{}) error {
	return globalTags.AddTagFn(tagname, fn)
}
AddTagFn adds fn as a converter function for tagname tags to the global
TagMap. fn must have the signature func(T) (U, error), where T is the
expected input type and U is the output type. See Decoder.AddTagFn for
examples.
package edn
import (
	"encoding/base64"
	"errors"
	"math/big"
	"reflect"
	"sync"
	"time"
)
var (
	ErrNotFunc         = errors.New("Value is not a function")
	ErrMismatchArities = errors.New("Function does not have single argument in, two argument out")
	ErrNotConcrete     = errors.New("Value is not a concrete non-function type")
	ErrTagOverwritten  = errors.New("Previous tag implementation was overwritten")
)
var globalTags TagMap
type TagMap struct {
	sync.RWMutex
	m map[string]reflect.Value
}
var errorType = reflect.TypeOf((*error)(nil)).Elem()
func (tm *TagMap) AddTagFn(tagname string, fn interface{}) error {
	rfn := reflect.ValueOf(fn)
	rtyp := rfn.Type()
	if rtyp.Kind() != reflect.Func {
		return ErrNotFunc
	}
	if rtyp.NumIn() != 1 || rtyp.NumOut() != 2 || !rtyp.Out(1).Implements(errorType) {
		return ErrMismatchArities
	}
	return tm.addVal(tagname, rfn)
}
func (tm *TagMap) MustAddTagFn(tagname string, fn interface{}) {
	if err := tm.AddTagFn(tagname, fn); err != nil {
		panic(err)
	}
}
func (tm *TagMap) addVal(name string, val reflect.Value) error {
	tm.Lock()
	if tm.m == nil {
		tm.m = map[string]reflect.Value{}
	}
	_, ok := tm.m[name]
	tm.m[name] = val
	tm.Unlock()
	if ok {
		return ErrTagOverwritten
	} else {
		return nil
	}
}