Search code examples
information-hidingnested-function

What are nested functions? What are they for?


I've never used nested functions, but have seen references to them in several languages (as well as nested classes, which I assume are related).

  • What is a nested function?
  • Why?!?
  • What can you do with a nested function that you cannot do any other way?
  • What can you do with a nested function this is difficult or inelegant without nested functions?

I assume nested functions are simply an artifact of treating everything as an object, and if objects can contain other objects then it follows.

Do nested functions have scope (in general, I suppose languages differ on this) just as variables inside a function have scope?

Please add the language you are referencing if you're not certain that your answer is language agnostic.

-Adam


Solution

  • One popular use of nested functions is closures. In a lexically scoped language with first-class functions it's possible to use functions to store data. A simple example in Scheme is a counter:

    (define (make-counter)
      (let ((count 0))                ; used to store the count
        (define (counter)             ; this is the counter we're creating
          (set! count (+ count 1))    ; increment the count
          count)                      ; return the new count
        counter))                     ; return the new counter function
    
    (define mycounter (make-counter)) ; create a counter called mycounter
    
    (mycounter)                       ; returns 1
    
    (mycounter)                       ; returns 2
    

    In this example, we nest the function counter inside the function make-counter, and by returning this internal function we are able to access the data available to counter when it was defined. This information is private to this instance of mycounter - if we were to create another counter, it would use a different spot to store the internal count. Continuing from the previous example:

    (define mycounter2 (make-counter))
    
    (mycounter2)                      ; returns 1
    
    (mycounter)                       ; returns 3