Walter Bright wrote:
Nested functions do closures in a straightforward way, so by leaving off nested functions they were forced to make an ugly syntax <g>. This is why I shake my head in just not understanding the process that led to their design.

That is because nested functions and block closures have different purposes.

Block closures avoid delocalization of code. For example, in Smalltalk, you could write something like the following to calculate the sum of the first 100 integers:

        s := 0.
        1 to: 100 do: [ :i | s := s + i ].


Packaging the 's := s + i' block inside a nested function instead would (aside from unnecessarily having to also pass 's' by reference or by value-result to the function) require you to move back and forth between the piece of code above and the nested function in order to comprehend it. More generally, it allows you to write custom control structures, such as map, fold, and filter to generate more compact an coherent code. This is especially prevalent in functional languages (Scheme, LISP, Haskell, the whole ML family) and Smalltalk or Ruby.

Research seems to indicate [1] that there is indeed a measurable readability benefit to this style of programming.

The benefit of nested functions is something different. In essence, a nested function allows you to share state with the parent function (absent shared state, there is little reason to not make the nested function a top-level function instead). However, nested functions are hidden inside their parent, which means that they are not reusable; on top of that, object-oriented languages already have means to share state between multiple methods (which is sometimes imperfect, but so are nested functions).

So, there are perfectly good reasons to have block closures, but not nested functions. Obviously, there are trade-offs, which may not appeal to everybody, but the design is still a rational one.


                        Reimer Behrends


[1] http://infoscience.epfl.ch/record/138586

Reply via email to