How to add a new function
===

What you should take into account
---

1. Each function (that behaves differently) must be in a separate file
2. Functions should be stored in `expr/functions/$function_name$` directory.
3. Function-specific tests should be also stored in `expr/functions/$function_name$`
4. Function type should be called exactly the same as package
5. Function type must implement `interfaces.Function`. There is helper `interfaces.FunctionBase` that implements basic `SetEvaluator` and `GetEvaluator` functions
6. There is a way to auto-generate `Description` method from graphite-web's output: `scripts/json_to_go_struct.sh`. Script is very hackish, but works most of the time.
7. Each function must have valid description, type, name, etc. Ideally description should contain examples, but that's not a strict requirement
8. All functions and it's aliases must be registered in `func init()`.
9. To create new `expr/functions/glue.go` you can do `cd expr/functions/; go generate > glue.go.new; mv glue.go.new glue.go`. This will automatically add all necessary imports.

How functions works
===

`expr/metadata`
---
Contains all metadata as a static global variables.

`func RegisterFunction(name string, function interfaces.Function)` - registers function in metadata

`FunctionMD` - contains metadata about all known functions

`FunctionDescriptions map[string]*types.FunctionDescription` - contains descriptions of all known functions

`FunctionDescriptionsGrouped map[string]map[string]*types.FunctionDescription` - contains descriptions of all known functions, grouped by function group

`expr/expr.go`
---

Contains `EvalExpr` - main expression parser

`EvalExpr` always uses `metadata.FunctionMD` to get list of known functions.

Functions registered by importing `expr/functions/glue.go`

`expr/functions/$FUNCTION_NAME$/function.go`
---

Contains actual function body.

You must define following structs and functions:

* `type $function_name$ struct` - it must statisfy `interfaces.Function`
* `func GetOrder() interfaces.Order` - must return either `interfaces.Any` or `interfaces.Last` - this will define order in which functions will be initialized. Currently the only known case when you might want to return `interfaces.Last` is when you redefine other functions.
* `func New(configFile string) []interfaces.FunctioMetadata` - this function will be called by `expr/functions/glue.go` during initialization. It must return metadata filled for all functions and their aliases. It will also receive config file name if user specify any. It's up to function's developer how to parse it (or if it's needed). Currently the only case where carbonapi uses that - proxy unknown functions to graphite-web where it's specified where to find graphite-web instances.


`expr/functions/glue.go`
---

Autogenerated by `expr/functions/gen.go`. Calls `New(configFileName)` for each and every function. If user specified custom config, it will be passed to `New()` method.
