code: function eval$func(params) {
    var self = this;
    if (typeof params.$func == 'string') {
      if (Object.keys(params).length > 1)
        throw new Error('reference to function "' + params.$func + '" has other properties');
      return Promise.resolve(this.getFunc(params.$func));
    }
  
    var valid = this.js.validate(params.$func);
    var argNames, argValidate;
    if (valid) {
      if (params.$name) this.functions[params.$name] = func;
      if (params.$args) {
        argValidate = {};
        argNames = params.$args.map(function (arg) {
          if (typeof arg == 'string') return arg;
          var name = Object.keys(arg)[0];
          argValidate[name] = self.ajv.compile(arg[name]);
          return name;
        });
      }
      return Promise.resolve(func);
    }
    throw new this.ajv.ValidationError(this.js.validate.errors);
  
    function func() {
      var data = argNames ? prepareArguments(arguments) : self.data;
      var script = JSON.parse(JSON.stringify(params.$func));
      return self.js.evaluate(script, data);
    }
  
    function prepareArguments(args) {
      var data = {};
      for (var i=0; i<args.length; i++) {
        data[i] = args[i];
        var argName = argNames[i];
        if (argName) {
          data[argName] = args[i];
          var validate = argValidate[argName];
          if (validate && !validate(args[i]))
            throw new self.ajv.ValidationError(validate.errors);
        }
      }
      return data;
    }
  }
docs: Function definition
  @this   Evaluation
  @param  {Object} params instruction keywords ($func, $name, $args)
  @return {Function} Function that returns synchronous/asynchronous value