> For long function chains or callbacks that stack up, breaking up the chain into smaller groups and using a well-named variable
> Is the second one marginally less efficient?
> Yes.
No, both versions are just as efficient:
In both versions, the same objects are allocated, stored on the heap, and garbage collected. The difference in efficiency comes down to the compiler.
For the second version, the compiler should observe that each variable is only used immediately after it's declared, and thus treat those objects as "out-of-scope" as if it's a chained function call.
I agree. After compiling it is even quite likely that the compiler does not care you gave a name to a return value (assuming you let it infer the variable type).
What you will see in practice is that the intermediate is explicitly “materialized” (e.g. into a list), because the author wanted to inspect it in the debugger. That will have some cost, mostly in the form of avoidable allocations.
> Is the second one marginally less efficient?
> Yes.
No, both versions are just as efficient:
In both versions, the same objects are allocated, stored on the heap, and garbage collected. The difference in efficiency comes down to the compiler.
For the second version, the compiler should observe that each variable is only used immediately after it's declared, and thus treat those objects as "out-of-scope" as if it's a chained function call.