RETURN With a Value: ABAP's Smallest Quality-of-Life Fix
Every modern language has return x. You write the keyword, you write the value, the method exits, the caller gets the result. One statement, one intent.
ABAP didn't have this until 2023.
How it used to work
ABAP methods have four kinds of parameters: IMPORTING, EXPORTING, CHANGING, and RETURNING. The RETURNING parameter is the closest thing to a classic return value. You declare it as RETURNING VALUE(r), and the caller can use the method in expressions, chain calls, inline declarations. Standard stuff.
But the way you actually set that return value was always a bit off. You had to treat r like any other variable: assign to it somewhere in the method body, then separately hit RETURN to exit. Two unrelated statements doing one logical thing.
METHOD get_name.
r_name = 'Alice'.
RETURN.
ENDMETHOD.
Or more commonly, you'd skip the explicit RETURN entirely and let the method fall through to ENDMETHOD, which implicitly returns the current value of r_name. That works, but it means the return value is set on line 12 and the method exits on line 40, with no visible connection between the two. If the method has early exits, conditional branches, or just a bit of length to it, tracking which value actually gets returned becomes a reading exercise.
METHOD calculate_discount.
IF iv_type = 'VIP'.
rv_discount = 20.
RETURN.
ENDIF.
IF iv_type = 'STANDARD'.
rv_discount = 5.
RETURN.
ENDIF.
rv_discount = 0.
ENDMETHOD.
This is fine. It works. But every single one of those early exits is two lines doing one thing: set the value, then leave.
What changed
ABAP 7.58 (Release 2023) added the option to place an expression after RETURN. The statement
RETURN expr.
is equivalent to
r = expr.
RETURN.
The same method now looks like this:
METHOD calculate_discount.
IF iv_type = 'VIP'.
RETURN 20.
ENDIF.
IF iv_type = 'STANDARD'.
RETURN 5.
ENDIF.
RETURN 0.
ENDMETHOD.
One line per exit instead of two. The intent is immediately visible: this method returns 20, 5, or 0. No scanning for where rv_discount gets assigned, no checking if something else modifies it between the assignment and the RETURN.
Expressions, not just literals
The value after RETURN is a general expression position. Anything you could assign to the return parameter, you can put after RETURN. Constructor expressions, method calls, calculations, string expressions.
METHOD get_squares.
RETURN VALUE #( FOR i = 1 UNTIL i > iv_limit
( num = i square = ipow( base = i exp = 2 ) ) ).
ENDMETHOD.
This builds and returns a table in a single statement. Without RETURN expr, this would be:
METHOD get_squares.
rt_result = VALUE #( FOR i = 1 UNTIL i > iv_limit
( num = i square = ipow( base = i exp = 2 ) ) ).
ENDMETHOD.
Not a dramatic difference in this case, since the method just falls through. But once you combine it with early exits or TRY/CATCH blocks, the single-statement form gets noticeably cleaner:
METHOD get_squares.
TRY.
RETURN VALUE #( FOR i = 1 UNTIL i > iv_limit
( num = i square = ipow( base = i exp = 2 ) ) ).
CATCH cx_sy_arithmetic_error.
RETURN VALUE #( ).
ENDTRY.
ENDMETHOD.
Both the happy path and the error path state what they return, right where they return it. The TRY/CATCH reads almost like a pattern match.
A small thing
This is not a feature that changes how you architect ABAP applications. Nobody is going to rewrite their codebase because of it. It's one of those changes where the diff is tiny but the reading experience improves in a way that accumulates across hundreds of methods.
The pattern of "assign to return parameter, then hit RETURN" was never wrong. It was just noisier than it needed to be. Two statements, one intent. Now it's one statement, one intent.
Every other language with a return value figured this out decades ago. ABAP got there in 2023. Late, but welcome.