         _evaluating.removeAll()
         _getters.removeAll()
         _cachedExpressions.removeAll()
+        _valueClearers.removeAll()
         for child in children {
             child.cleanUp()
         }

                    return expression
                }
            } else {
                let evaluate = expression.evaluate
                expression = LayoutExpression(
                    evaluate: { [unowned self] in
                        if self._evaluating.last == symbol,
                            let value = self.value(forVariableOrConstant: symbol) {
                            // If an expression directly references itself it may be shadowing
                            // a constant or variable, so check for that first before throwing
                            return value
                        }
                        guard !self._evaluating.contains(symbol) else {
                            throw SymbolError("Circular reference for \(symbol)", for: symbol)
                        }
                        self._evaluating.append(symbol)

        return view.isHidden
    }

    // TODO: should this be public?
    public var frame: CGRect {
        return attempt {
            CGRect(
                x: try CGFloat(doubleValue(forSymbol: "left")),
                y: try CGFloat(doubleValue(forSymbol: "top")),
                width: try CGFloat(doubleValue(forSymbol: "width")),
                height: try CGFloat(doubleValue(forSymbol: "height"))
            )
        } ?? .zero
    }

    private func inferContentSize() throws -> CGSize {
