Runtime & concurrency
Reveal answer and reasoning
Prefer a parameterized computation when callers can supply the needed data explicitly, and keep the cached structure separate from each invocation's values. If a snapshot is required, define whether it copies scalars, containers, or the full relevant object graph rather than assuming a constant node deep-clones references. Document evaluation timing and retained lifetime for any state that remains captured.
Test a changed caller value after construction, a changed mutable object property, repeated invocations with different explicit inputs, and cleanup of retained request state. For a real query provider, test its actual translation and parameter extraction separately from the local interpreter. The wrong design caches a tree that closes over the first request, then calls it immutable because nobody replaces its nodes.
That can preserve stale dependencies or retain a large request graph even when the expression structure itself never changes.
What a strong answer covers
- Separate cached structure from per-call inputs.
- Define snapshot depth and retained ownership.
- Test actual provider evaluation timing when relevant.
Common pitfall
Caching a closure over request state and calling the resulting structure a complete immutable snapshot.
Follow-up questions
- Can a ConstantExpression still hold mutable shared state?
- What should an expression cache key represent?
Self-review
Choose what to revisit. These marks are your own assessment and are separate from lesson completion.