                     self._evaluating.removeLast()
                 }
                 let value = try SymbolError.wrap(evaluate, for: symbol)
+                if self._setupComplete, symbols.isEmpty {
+                    if isViewControllerExpression {
+                        try self._viewController?.setValue(value, forExpression: symbol)
+                    } else if isViewExpression {
+                        try self._view?.setValue(value, forExpression: symbol)
+                    }
+                    // Replace getter with cached result
+                    self._getters[symbol] = { value }
+                }
                 cachedValue = value
                 return value
             },
             symbols: expression.symbols
         )
         _getters[symbol] = expression.evaluate
-
-        // Only set constant values once
-        if expression.symbols.isEmpty {
-            do {
-                let value = try expression.evaluate()
-                if isViewControllerExpression {
-                    try _viewController?.setValue(value, forExpression: symbol)
-                } else if isViewExpression {
-                    try _view?.setValue(value, forExpression: symbol)
-                }
-                _getters[symbol] = { value }
-                return // Don't add to expressions arrays for re-evaluations
-            } catch {
-                // Something went wrong
-            }
-        }
 
         // Store expression
         if isViewControllerExpression {

        }
        try completeSetup()
        for symbol in expressions.keys {
            try setUpExpression(for: symbol)
        }

        #if arch(i386) || arch(x86_64)

    private(set) var _originalExpressions: [String: String]
    var _parameters: [String: RuntimeType]

    // Note: Thrown error is always a LayoutError
    private var _setupComplete = false
    private func completeSetup() throws {
        guard !_setupComplete else { return }
