 
       storedValues
 
+  _cachedValueFunction: (name, calcFunction) ->
+    runner = this
+    ops = new Operations name
+    ->
+      if runner.slots[name] is Invalid
+        runner.slots[name] = try
+            ops._valueCheck calcFunction.apply runner.sheet, []
+          catch e
+            ops._error e
+
+      runner.slots[name]
 
   _userFunctionSubject: (name) -> @userFunctionSubjects[name]
   _unknownUserFunctionSubject: (name) -> (@userFunctionSubjects[name] = @_newUserFunctionSubject(name, new CalculationError(name, "Unknown name: " + name)))

    @inputStreams = {}
    @inputCompleteSubject = new Rx.Subject()
    @bufferedValueChanges = bufferedValueChangeStream @valueChanges, @inputCompleteSubject

    @sheet = _.assign {}, @providedFunctions, {
      operations: new Operations("a function", @_inputItem)
      stored: {}
      storedUpToDate: {}
    }


# TODO  rationalise this zoo of add...Functions

        if not subj.hasObservers()
          delete @userFunctionSubjects[subjName]
          delete @userFunctionImpls[subjName]
      delete @slots[functionName]
      @sheet[functionName] = unknownNameFunction(functionName)
      @_recalculate()

