nested function definition
   HOME

TheInfoList



OR:

In
computer programming Computer programming is the process of performing a particular computation (or more generally, accomplishing a specific computing result), usually by designing and building an executable computer program. Programming involves tasks such as anal ...
, a nested function (or nested procedure or subroutine) is a
function Function or functionality may refer to: Computing * Function key, a type of key on computer keyboards * Function model, a structured representation of processes in a system * Function object or functor or functionoid, a concept of object-oriente ...
which is defined within another function, the ''enclosing function''. Due to simple recursive
scope Scope or scopes may refer to: People with the surname * Jamie Scope (born 1986), English footballer * John T. Scopes (1900–1970), central figure in the Scopes Trial regarding the teaching of evolution Arts, media, and entertainment * Cinema ...
rules, a nested function is itself invisible outside of its immediately enclosing function, but can see (access) all local
objects Object may refer to: General meanings * Object (philosophy), a thing, being, or concept ** Object (abstract), an object which does not exist at any particular time or place ** Physical object, an identifiable collection of matter * Goal, an ai ...
(data, functions, types, etc.) of its immediately enclosing function as well as of any function(s) which, in turn, encloses that function. The nesting is theoretically possible to unlimited depth, although only a few levels are normally used in practical programs. Nested functions are used in many approaches to
structured programming Structured programming is a programming paradigm aimed at improving the clarity, quality, and development time of a computer program by making extensive use of the structured control flow constructs of selection ( if/then/else) and repetition ( ...
, including early ones, such as
ALGOL ALGOL (; short for "Algorithmic Language") is a family of imperative computer programming languages originally developed in 1958. ALGOL heavily influenced many other languages and was the standard method for algorithm description used by the ...
,
Simula 67 Simula is the name of two simulation programming languages, Simula I and Simula 67, developed in the 1960s at the Norwegian Computing Center in Oslo, by Ole-Johan Dahl and Kristen Nygaard. Syntactically, it is an approximate superset of ALG ...
and
Pascal Pascal, Pascal's or PASCAL may refer to: People and fictional characters * Pascal (given name), including a list of people with the name * Pascal (surname), including a list of people and fictional characters with the name ** Blaise Pascal, Frenc ...
, and also in many modern dynamic languages and
functional language In computer science, functional programming is a programming paradigm where programs are constructed by applying and composing functions. It is a declarative programming paradigm in which function definitions are trees of expressions that ...
s. However, they are traditionally not supported in the (originally simple) C-family of languages.


Effects

Nested functions assumes
function scope In computer programming, the scope of a name binding (an association of a name to an entity, such as a variable) is the part of a program where the name binding is valid; that is, where the name can be used to refer to the entity. In other parts ...
or
block scope In computer programming, the scope of a name binding (an association of a name to an entity, such as a variable) is the part of a program where the name binding is valid; that is, where the name can be used to refer to the entity. In other parts ...
. The scope of a nested function is inside the enclosing function, i.e. inside one of the constituent blocks of that function, which means that it is invisible outside that block and also outside the enclosing function. A nested function can access other local functions, variables, constants, types, classes, etc. that are in the same scope, or in any enclosing scope, without explicit parameter passing, which greatly simplifies passing data into and out of the nested function. This is typically allowed for both reading and writing. Nested functions may in certain situations (and languages) lead to the creation of a closure. If it is possible for the nested function to
escape Escape or Escaping may refer to: Computing * Escape character, in computing and telecommunication, a character which signifies that what follows takes an alternative interpretation ** Escape sequence, a series of characters used to trigger some s ...
the enclosing function, for example if functions are
first class object In programming language design, a first-class citizen (also type, object, entity, or value) in a given programming language is an entity which supports all the operations generally available to other entities. These operations typically include b ...
s and a nested function is passed to another function or returned from the enclosing function, then a closure is created and calls to this function can access the environment of the original function. The frame of the immediately enclosing function must continue to be alive until the last referencing closure dies and non-local
automatic variable __NOTOC__ In computer programming, an automatic variable is a local variable which is allocated and deallocated automatically when program flow enters and leaves the variable's scope. The scope is the lexical context, particularly the function or ...
s referenced in closures can therefore not be stack allocated. This is known as the
funarg problem In computer science, the funarg problem ''(function argument problem)'' refers to the difficulty in implementing first-class functions (functions as first-class objects) in programming language implementations so as to use stack-based memory all ...
and is a key reason why nested functions was not implemented in some simpler languages as it significantly complicates code generation and analysis, especially when functions are nested to various levels, sharing different parts of their environment.


Examples

An example using Pascal syntax (with
ALGOL ALGOL (; short for "Algorithmic Language") is a family of imperative computer programming languages originally developed in 1958. ALGOL heavily influenced many other languages and was the standard method for algorithm description used by the ...
, Modula 2,
Oberon Oberon () is a king of the fairies in medieval and Renaissance literature. He is best known as a character in William Shakespeare's play ''A Midsummer Night's Dream'', in which he is King of the Fairies and spouse of Titania, Queen of the Fairi ...
,
Ada Ada may refer to: Places Africa * Ada Foah, a town in Ghana * Ada (Ghana parliament constituency) * Ada, Osun, a town in Nigeria Asia * Ada, Urmia, a village in West Azerbaijan Province, Iran * Ada, Karaman, a village in Karaman Province, T ...
, etc. similar): function E(x: real): real; function F(y: real): real; begin F := x + y end; begin E := F(3) + F(4) end; The function F is nested within E. Note that E's parameter x is visible also in F (as F is a part of E) while both x and y are invisible outside E and F respectively. Similarly, in Standard ML: fun e (x : real) = let fun f y = x+y in f 3 + f 4 end; One way to write the same example in
Haskell Haskell () is a general-purpose, statically-typed, purely functional programming language with type inference and lazy evaluation. Designed for teaching, research and industrial applications, Haskell has pioneered a number of programming lan ...
syntax: e :: Float -> Float e x = f 3 + f 4 where f y = x + y The same example in GNU C syntax (C extended with nested functions): float E(float x)


Quicksort

A more realistic example is this implementation of
quicksort Quicksort is an efficient, general-purpose sorting algorithm. Quicksort was developed by British computer scientist Tony Hoare in 1959 and published in 1961, it is still a commonly used algorithm for sorting. Overall, it is slightly faster than ...
: void sort(int *items, int size) Another example is the following implementation of the Hoare partition based quicksort using
C++11 C11, C.XI, C-11 or C.11 may refer to: Transport * C-11 Fleetster, a 1920s American light transport aircraft for use of the United States Assistant Secretary of War * Fokker C.XI, a 1935 Dutch reconnaissance seaplane * LET C-11, a license-build ...
lambda expression syntax: template auto Sort(RandomAccessIterator Begin, RandomAccessIterator End)->void


Purpose

Lexically nested function definitions are a form of
information hiding In computer science, information hiding is the principle of segregation of the ''design decisions'' in a computer program that are most likely to change, thus protecting other parts of the program from extensive modification if the design decisio ...
and are useful for dividing procedural tasks into subtasks which are only meaningful locally. This avoids cluttering other parts of the program with functions and variables that are unrelated to those parts. They are typically used as helper functions or as recursive functions inside another function (as in the quicksort example above). This has the structural benefit of organizing the code, avoids polluting the scope, and also allows functions to share state easily. As nested function can access local variables of the enclosing function, sharing of state is possible without passing parameters to the nested function or use a
global variable In computer programming, a global variable is a variable with global scope, meaning that it is visible (hence accessible) throughout the program, unless shadowed. The set of all global variables is known as the ''global environment'' or ''global s ...
, simplifying code. In languages with nested functions, functions may normally also contain local
constants Constant or The Constant may refer to: Mathematics * Constant (mathematics), a non-varying value * Mathematical constant, a special number that arises naturally in mathematics, such as or Other concepts * Control variable or scientific const ...
, and
types Type may refer to: Science and technology Computing * Typing, producing text via a keyboard, typewriter, etc. * Data type In computer science and computer programming, a data type (or simply type) is a set of possible values and a set of allo ...
(in addition to local variables,
parameter A parameter (), generally, is any characteristic that can help in defining or classifying a particular system (meaning an event, project, object, situation, etc.). That is, a parameter is an element of a system that is useful, or critical, when ...
s, and functions), encapsulated and hidden in the same nested manner, at any level of depth. This may further enhance the code structuring possibilities.


Other uses


Control flow

Nested functions can also be used for unstructured
control flow In computer science, control flow (or flow of control) is the order in which individual statements, instructions or function calls of an imperative program are executed or evaluated. The emphasis on explicit control flow distinguishes an '' ...
, by using the return statement for general unstructured control flow. This can be used for finer-grained control than is possible with other built-in features of the language – for example, it can allow early termination of a for loop if break is not available, or early termination of a nested
for loop In computer science a for-loop or for loop is a control flow statement for specifying iteration. Specifically, a for loop functions by running a section of code repeatedly until a certain condition has been satisfied. For-loops have two par ...
if a multi-level break or exceptions are not available.


Higher-order functions

As in most languages functions are valid return types, it is possible to create a nested function that accesses a set of parameters from the outer function and have that function be the outer function's return value. Thus it is possible to return a function that is set to fulfill a certain task with little or no further parameters given to it, which can increase performance quite significantly.Higher-Order Functions and Lambdas - Kotlin Programming Language
/ref>


Alternatives

The main alternative to nested functions in languages that lack support for them is to place all relevant functions and variables in a separate module (file) and expose only the top-level
wrapper function A wrapper function is a function (another word for a ''subroutine'') in a software library or a computer program whose main purpose is to call a second subroutine or a system call with little or no additional computation. Wrapper functions are u ...
publicly. In C this will generally be done by using static functions for encapsulation and
static variable In computer programming, a static variable is a variable that has been allocated "statically", meaning that its lifetime (or "extent") is the entire run of the program. This is in contrast to shorter-lived automatic variables, whose storage is ...
s for communication.Question 20.24: Why doesn't C have nested functions?
comp.lang.c FAQ
This achieves encapsulation and sharing of state, though not the logical organization given by lexical nesting of functions, and comes at the cost of having a separate file. It is also not possible in more than a single level. Another alternative is to share state between the functions through function parameters, most often passing references as arguments to avoid the cost of copying. In C this is generally implemented by a pointer to a structure containing the context. This significantly increases the complexity of the function calls. In PHP and other languages the
anonymous function In computer programming, an anonymous function (function literal, lambda abstraction, lambda function, lambda expression or block) is a function definition that is not bound to an identifier. Anonymous functions are often arguments being passed t ...
is the only alternative: the nested function is declared not as usual function, but by reference, as a local variable. To use local variables in the anonymous function, use closure.


Languages

Well known languages supporting lexically nested functions include: *
ALGOL ALGOL (; short for "Algorithmic Language") is a family of imperative computer programming languages originally developed in 1958. ALGOL heavily influenced many other languages and was the standard method for algorithm description used by the ...
-based languages such as
ALGOL 68 ALGOL 68 (short for ''Algorithmic Language 1968'') is an imperative programming language that was conceived as a successor to the ALGOL 60 programming language, designed with the goal of a much wider scope of application and more rigorously d ...
,
Simula Simula is the name of two simulation programming languages, Simula I and Simula 67, developed in the 1960s at the Norwegian Computing Center in Oslo, by Ole-Johan Dahl and Kristen Nygaard. Syntactically, it is an approximate superset of ALGO ...
,
Pascal Pascal, Pascal's or PASCAL may refer to: People and fictional characters * Pascal (given name), including a list of people with the name * Pascal (surname), including a list of people and fictional characters with the name ** Blaise Pascal, Frenc ...
,
Modula-2 Modula-2 is a structured, procedural programming language developed between 1977 and 1985/8 by Niklaus Wirth at ETH Zurich. It was created as the language for the operating system and application software of the Lilith personal workstation. It ...
,
Modula-3 Modula-3 is a programming language conceived as a successor to an upgraded version of Modula-2 known as Modula-2+. While it has been influential in research circles (influencing the designs of languages such as Java, C#, and Python) it has not ...
,
Oberon Oberon () is a king of the fairies in medieval and Renaissance literature. He is best known as a character in William Shakespeare's play ''A Midsummer Night's Dream'', in which he is King of the Fairies and spouse of Titania, Queen of the Fairi ...
,
Seed7 Seed7 is an extensible general-purpose programming language designed by Thomas Mertes. It is syntactically similar to Pascal and Ada. Along with many other features, it provides an extension mechanism. Daniel Zingaro"Modern Extensible Languages" ...
and
Ada Ada may refer to: Places Africa * Ada Foah, a town in Ghana * Ada (Ghana parliament constituency) * Ada, Osun, a town in Nigeria Asia * Ada, Urmia, a village in West Azerbaijan Province, Iran * Ada, Karaman, a village in Karaman Province, T ...
*Modern versions of
Lisp A lisp is a speech impairment in which a person misarticulates sibilants (, , , , , , , ). These misarticulations often result in unclear speech. Types * A frontal lisp occurs when the tongue is placed anterior to the target. Interdental lispin ...
(with lexical scope) such as
Scheme A scheme is a systematic plan for the implementation of a certain idea. Scheme or schemer may refer to: Arts and entertainment * ''The Scheme'' (TV series), a BBC Scotland documentary series * The Scheme (band), an English pop band * ''The Schem ...
, and
Common Lisp Common Lisp (CL) is a dialect of the Lisp programming language, published in ANSI standard document ''ANSI INCITS 226-1994 (S20018)'' (formerly ''X3.226-1994 (R1999)''). The Common Lisp HyperSpec, a hyperlinked HTML version, has been derived fr ...
*
ECMAScript ECMAScript (; ES) is a JavaScript standard intended to ensure the interoperability of web pages across different browsers. It is standardized by Ecma International in the documenECMA-262 ECMAScript is commonly used for client-side scripti ...
(
JavaScript JavaScript (), often abbreviated as JS, is a programming language that is one of the core technologies of the World Wide Web, alongside HTML and CSS. As of 2022, 98% of websites use JavaScript on the client side for webpage behavior, of ...
and
ActionScript ActionScript is an object-oriented programming language originally developed by Macromedia Inc. (later acquired by Adobe). It is influenced by HyperTalk, the scripting language for HyperCard. It is now an implementation of ECMAScript (meaning ...
) *
Dart Dart or DART may refer to: * Dart, the equipment in the game of darts Arts, entertainment and media * Dart (comics), an Image Comics superhero * Dart, a character from ''G.I. Joe'' * Dart, a ''Thomas & Friends'' railway engine character * Da ...
* Kotlin (local functions) * Scala (nested functions) *Various degrees of support in scripting languages such as
Ruby A ruby is a pinkish red to blood-red colored gemstone, a variety of the mineral corundum ( aluminium oxide). Ruby is one of the most popular traditional jewelry gems and is very durable. Other varieties of gem-quality corundum are called ...
, Python,
Lua Lua or LUA may refer to: Science and technology * Lua (programming language) * Latvia University of Agriculture * Last universal ancestor, in evolution Ethnicity and language * Lua people, of Laos * Lawa people, of Thailand sometimes referred t ...
, PHP and
Perl Perl is a family of two high-level, general-purpose, interpreted, dynamic programming languages. "Perl" refers to Perl 5, but from 2000 to 2019 it also referred to its redesigned "sister language", Perl 6, before the latter's name was offic ...
* GCC supports nested functions in C, as a language extension. * C#, starting with C# 7.0 *The D language, a C-related language with nested functions. * Fortran, starting with Fortran-90, supports ''a single level'' of nested (''CONTAINed'') subroutines and functions. *
MATLAB MATLAB (an abbreviation of "MATrix LABoratory") is a proprietary multi-paradigm programming language and numeric computing environment developed by MathWorks. MATLAB allows matrix manipulations, plotting of functions and data, implementat ...
(full support) *
Wolfram Language The Wolfram Language ( ) is a general multi-paradigm programming language developed by Wolfram Research. It emphasizes symbolic computation, functional programming, and rule-based programming and can employ arbitrary structures and data. It ...


Functional languages

In most
functional programming In computer science, functional programming is a programming paradigm where programs are constructed by applying and composing functions. It is a declarative programming paradigm in which function definitions are trees of expressions tha ...
languages, such as Scheme, nested functions are a common way of implementing
algorithm In mathematics and computer science, an algorithm () is a finite sequence of rigorous instructions, typically used to solve a class of specific problems or to perform a computation. Algorithms are used as specifications for performing ...
s with loops in them. A simple (
tail The tail is the section at the rear end of certain kinds of animals’ bodies; in general, the term refers to a distinct, flexible appendage to the torso. It is the part of the body that corresponds roughly to the sacrum and coccyx in mammal ...
)
recursive Recursion (adjective: ''recursive'') occurs when a thing is defined in terms of itself or of its type. Recursion is used in a variety of disciplines ranging from linguistics to logic. The most common application of recursion is in mathematics ...
inner function is created, which behaves as the algorithm's main loop, while the outer function performs startup actions that only need to be done once. In more complex cases, a number of mutually recursive functions may be created as inner functions.


Some languages without direct support

Certain languages do not have straightforward syntactic and semantic support to implement nested functions. Nevertheless, for some of them the idea of nested functions can be simulated with some degree of difficulty through the use of other language constructs. The following languages can approximate nested functions through the respective strategies: *
C++ C++ (pronounced "C plus plus") is a high-level general-purpose programming language created by Danish computer scientist Bjarne Stroustrup as an extension of the C programming language, or "C with Classes". The language has expanded significan ...
**before C++11: allows definition of classes within classes, providing the ability to use class methods in a way similar to nested functions in one level (see Function object in C++). **since C++11: by using lambda expressions as the quicksort example above. * Eiffel explicitly disallows nesting of routines. This is to keep the language simple, and also allows the convention of using a special variable, Result, to denote the result of a (value-returning) function. *
Visual Basic Visual Basic is a name for a family of programming languages from Microsoft. It may refer to: * Visual Basic .NET (now simply referred to as "Visual Basic"), the current version of Visual Basic launched in 2002 which runs on .NET * Visual Basic ( ...
, by using anonymous methods or lambda expressions. *
Java Java (; id, Jawa, ; jv, ꦗꦮ; su, ) is one of the Greater Sunda Islands in Indonesia. It is bordered by the Indian Ocean to the south and the Java Sea to the north. With a population of 151.6 million people, Java is the world's mo ...
, by using lambda expressions (see Anonymous functions in Java) (since Java 8) or through a workaround that consists in an anonymous class containing a single method. A named class declared local to a method may also be used.


Implementation

Implementation of nested functions can be more involved than it may appear, as a reference to a nested function that references non-local variables creates a closure. For this reason nested functions are not supported in some languages such as C, C++ or Java as this makes compilers more difficult to implement. However, some compilers do support them, as a compiler specific extension. A well known example of this is the GNU C implementation of C which shares code with compilers for languages such as Pascal, Ada and Modula.


Access of non-local objects

''There are several ways to implement nested procedures in a lexically scoped language, but the classic way is as follows:'' :Any non-local object, X, is reached via access-links in the activation frames on the machine stack. The caller, C, assists the called procedure, P, by pushing a ''direct'' link to the ''latest'' activation of P's immediate lexical encapsulation, (P), prior to the call itself. P may then quickly find the right activation for a certain X by following a ''fixed number'' (P.depth – X.depth) of links (normally a small number). :The caller creates this direct link by (itself) following C.depth – P.depth + 1 older links, leading up to the latest activation of (P), and then ''temporarily'' bridging over these with a direct link to that activation; the link later disappears together with P, whereby the older links beneath it may come into use again. :Note that P is visible for, and may therefore be called by, C if (P) = C / (C) / ((C)) / etc. This original method is faster than it may seem, but it is nevertheless often optimized in practical modern compilers (using ''displays'' or similar techniques). Another way to implement nested functions that is used by some compilers is to convert ("lift") nested functions into non-nested functions (where extra, hidden, parameters replace the access links) using a process known as
lambda lifting Lambda lifting is a meta-process that restructures a computer program so that functions are defined independently of each other in a global scope. An individual "lift" transforms a local function into a global function. It is a two step process ...
during an intermediate stage in the compilation.


Functions as values

In order for local functions with lexically scoped nonlocals to be passed as results, the language runtime code must also implicitly pass the environment (data) that the function sees inside its encapsulating function, so that it is reachable also when the current activation of the enclosing function no longer exists. This means that the environment must be stored in another memory area than (the subsequently reclaimed parts of) a chronologically based execution stack, which, in turn, implies some sort of freely
dynamic memory allocation Memory management is a form of resource management applied to computer memory. The essential requirement of memory management is to provide ways to dynamically allocate portions of memory to programs at their request, and free it for reuse when ...
. Many older Algol based languages (or dialects thereof) does therefore not allow local functions that access nonlocals to be passed as return values, or do they not allow functions as return values at all, although passing of such functions as arguments may still be possible.


No-execute stacks

At least one implementation of nested functions cause a loss of No-execute stacks (NX stack). GCC's nested function implementation calls nested functions through a jump instruction put in the machine stack at runtime. This requires the stack to be executable. No execute stacks and nested functions are mutually exclusive under GCC. If a nested function is used in the development of a program, then the NX Stack is silently lost. GCC offers the -Wtrampoline warning to alert of the condition. Software engineered using Secure Development Lifecycle often do not allow the use of nested functions in this particular compiler (GCC) due to the loss of NX Stacks.


See also

*
Call stack In computer science, a call stack is a stack data structure that stores information about the active subroutines of a computer program. This kind of stack is also known as an execution stack, program stack, control stack, run-time stack, or mac ...
*
Closure (computer science) In programming languages, a closure, also lexical closure or function closure, is a technique for implementing lexically scoped name binding in a language with first-class functions. Operationally, a closure is a record storing a function t ...
* Inner class *
Nesting (computing) In computing science and informatics, nestinghttps://study.com/academy/lesson/nesting-loops-statements-in-c-programming.html, title=Nesting Loops & Statements in C Programming is where information is organized in layers, or where objects contain ...


Notes


References

* {{refend


External links


comp.lang.c FAQ: Nested Functions


FreePascal documentation. Source code Subroutines