get (name) {
    const decorators = []
    let opName = name
    // while we don't already have this operator
    while (!this.operators.has(opName)) {
      // try splitting on the decorator symbol (:)
      const firstDecoratorIndex = opName.indexOf(':')
      if (firstDecoratorIndex > 0) {
        // if there is a decorator, and it's a valid decorator
        const decoratorName = opName.slice(0, firstDecoratorIndex)
        const decorator = this.decorators.get(decoratorName)
        if (!decorator) {
          debug('operatorMap::get invalid decorator', { name: decoratorName })
          return null
        }
        // we're going to apply this later, use unshift since we'll apply in reverse order
        decorators.unshift(decorator)
        // continue looking for a known operator with the rest of the name
        opName = opName.slice(firstDecoratorIndex + 1)
      } else {
        debug('operatorMap::get no operator', { name: opName })
        return null
      }
    }

    let op = this.operators.get(opName)
    // apply all the decorators
    for (let i = 0; i < decorators.length; i++) {
      op = decorators[i].decorate(op)
      // create an entry for the decorated operation so we don't need
      // to do this again
      this.operators.set(op.name, op)
    }
    // return the operation
    return op
  }
Get the Operator, or null applies decorators as needed
@param {string} name - the name of the operator including any decorators
@returns an operator or null