No, return exiting the enclosing function scope from a block is the special case that's there to resolve an edge case.
Blocks should be nothing special. They're anonymous functions that capture the environment mutably. The only new part is all the special bits added to handle the weird edge cases that they're trying to pretend don't exist.
I disagree that it's just there to handle edge cases. It's a useful generalization.
I think the "Building an intuition" section of my blog post[1] makes a good case for that.
When dealing with loops, you have 3 nested constructs interacting: a wrapping function, a loop statement and the loop's body; and you have 3 keywords to choose where the flow of the code goes.
return returns from the wrapping function
break leaves the loop statement
next / continue leaves loop's body
When dealing with blocks or anonymous functions, it's instead 3 nested "functions" that are interacting: a wrapping function, a called function and an anonymous functions (or block).
Ruby's blocks, let you use the same 3 keywords to choose where the flow of the code goes.
return returns from the wrapping function (ex: my_func)
break returns from the called function (ex: each, map)
next returns from the block
Quite consistent. But since we are talking about functions instead of statements (loop), return values are also involved. Allowing both break and next to provide a return value fits well in that model and is quite useful. The 3 keywords are basically return, but they have different targets.
> No, return exiting the enclosing function scope from a block is the special case that's there to resolve an edge case.
What is the edge case? It seems to be there so that Ruby enumeration methods can provide the behavior expected of looping statements (which is kind of necessary if you want the looping statements to just be semantic sugar for enumeration methods so that they can work correctly with any enumerable.)
Blocks should be nothing special. They're anonymous functions that capture the environment mutably. The only new part is all the special bits added to handle the weird edge cases that they're trying to pretend don't exist.