Why must I capture the return value of a pure function call?
← Comparison Patterns · Ref: Q641
EK9 detects when a call with a return value is used as a bare statement and the return value is discarded. For pure functions this is always an error (E11051) because a pure function has no side effects, so calling it without using the result is completely pointless.
DISCARDED OPERATOR RESULT (E11050)
An operator that returns a value, invoked in method-call form as a standalone statement, is rejected: 'a.+(b)' computes a sum and throws it away. (An ordinary non-pure function call such as 'fetchAndLog(42)' compiles as a bare statement - its side effects may be the point - but capturing the result is still the habit to keep.)
DISCARDED PURE RETURN (E11051)
Calling a pure function as a bare statement is especially bad because pure functions have NO side effects. The call does nothing observable. It is dead code.
DISCARDED CONSTRUCTOR (E11055)
Creating an object without capturing the reference:
Sensor(98.6) <- creates and immediately discards
This is always a bug. If you need side effects, use a function.
DISCARDED RESULT OR OPTIONAL (E11052)
Calling a function that returns Result or Optional and ignoring the result defeats the purpose of these types.
CORRECT PATTERN
Always capture the return value of functions that return values:
total <- computeTotal(items) processed <- transform(input) newList <- List() of String
See Q316 for discarded return detection. See Q640 for collection patterns. See Q635 for pure mutation restrictions.
Example
defines module qa.comparison.capturereturn defines constant SUM_THRESHOLD <- 6 defines function <?- Pure function: its return value MUST be captured. Calling this without capturing triggers E11051. -?> computeSum() as pure -> valueA as Integer valueB as Integer <- total as Integer: valueA + valueB <?- Pure function: return value must be captured. -?> formatPrice() as pure -> price as Float <- formatted as String: `Price: ${price}` <?- Pure function with string processing. -?> buildLabel() as pure -> prefix as String suffix as String <- label as String: `${prefix}-${suffix}` <?- Non-pure function with return value. Discarding the result compiles (it is not pure), but capturing it is still good practice. -?> fetchAndLog() -> itemId as Integer <- itemName as String: `item-${itemId}` defines program CaptureReturnDemo() stdout <- Stdout() //Correct: capture the return value total <- computeSum(10, 20) stdout.println(`Sum: ${total}`) //Correct: capture formatted string priceStr <- formatPrice(9.99) stdout.println(priceStr) //Correct: capture and use label <- buildLabel("order", "001") stdout.println(label) //Correct: capture non-pure return itemName <- fetchAndLog(42) stdout.println(`Fetched: ${itemName}`) //Correct: use return value directly in expression doubled <- computeSum(5, 5) * 2 stdout.println(`Doubled: ${doubled}`) //Correct: use in condition if computeSum(3, 4) > SUM_THRESHOLD stdout.println("Sum exceeds threshold")
Common mistakes
E11051 — computeSum is a pure function, so the extra bare call computeSum(1, 2) discards its result and achieves nothing. Capture the result. See ek9 -h E11051 for details.
Incorrect:
total <- computeSum(10, 20) computeSum(1, 2)
Correct:
total <- computeSum(10, 20)
E11051 — formatPrice is a pure function, so the extra bare call formatPrice(1.5) discards its result and achieves nothing. Capture the result. See ek9 -h E11051 for details.
Incorrect:
priceStr <- formatPrice(9.99) formatPrice(1.5)
Correct:
priceStr <- formatPrice(9.99)
Other ways to ask this
- What is E11050 discarded return value?
- What is E11051 discarded pure function return?
- Why does EK9 reject calling a function without capturing its result?
Coming from another language?
Java: return values can always be silently discarded, no warning by default. IntelliJ warns on discarded return from pure-annotated methods (optional). Rust: #[must_use] attribute warns when return value is discarded (opt-in). Go: error return values often silently discarded (common bug source). Kotlin: no enforcement. C++: [[nodiscard]] attribute (C++17, opt-in). EK9: mandatory compiler error E11051 for discarding the result of a pure function, E11050 for a discarded operator result, E11055 for a discarded constructor, E11052 for a discarded Result or Optional.
Keywords: compare, constructor, result, E11050, E11051, E11052, comparison, E11055, discard, side-effect, return, immutable, guard, pure, error, dead, ok, capture, pattern, function