Nepedia
Back to Discover
Advanced Reader
💻

Function (computer programming)

technology Maturity 7-9 Next article →

In computer programming, a function is a callable unit of software logic. It possesses a well-formed interface and specific behavior. This means it follows set rules for how it receives information and how it acts. A function can be invoked or called multiple times throughout a program. This concept is a powerful tool for developers. It allows for the decomposition of large, complicated problems into smaller chunks. These chunks have a lower cognitive load, meaning they are easier for a human to understand. Programmers can then assign these chunks meaningful names. Using functions judiciously can reduce the cost of developing and maintaining software. It also increases the overall quality and reliability of the code.

Terminology for these units varies depending on the programming language used. Some languages, such as COBOL and BASIC, distinguish between functions and other types. In these languages, a "function" typically returns a value to the caller. Other units that do not return a value are called subprograms, subroutines, or procedures. However, languages like C, C++, and Rust use the term "function" for both types. Other languages, such as ALGOL 60 and PL/I, exclusively use the word "procedure." In object-oriented languages like Java and C#, functions located inside classes are called "methods."

The history of callable units involves several key figures and eras. The concept was initially conceived by John Mauchly and Kathleen Antonelli. They worked on the ENIAC computer and recorded their ideas during a 1947 Harvard symposium. Kay McNulty, working closely with Mauchly, developed subroutine ideas for the ENIAC. These subroutines helped the team calculate missile trajectories during World War II. Maurice Wilkes, David Wheeler, and Stanley Gill are credited with the formal invention of the "closed subroutine." This was contrasted with the "open subroutine" or "macro." Additionally, Alan Turing discussed subroutines in a 1945 paper regarding the NPL ACE. He even invented the concept of a return address stack.

Early computing hardware lacked the specialized instructions we see today. The Manchester Baby and the RCA 1802 microprocessor did not have a single subroutine call instruction. Programmers had to manually write a call sequence of instructions every time. In 1945, Konrad Zuse implemented a single subroutine in the Z4 using a tape. As technology advanced, hardware began to support these calls more efficiently. Machines before the mid-1960s, like the UNIVAC I, often used a calling convention that saved the instruction counter in the first memory location of the subroutine. This allowed for deep nesting but did not support recursive subroutines. The Burroughs B5000, released in 1961, was one of the first to use a stack for return data.

Modern implementations of function calls almost always use a call stack. A stack is a specific type of data structure. Each procedure call creates a new entry at the top of the stack called a stack frame. When the procedure returns, its stack frame is deleted. This space can then be reused for other calls. Each stack frame contains the private data for that specific call. This data typically includes the procedure's parameters, internal variables, and the return address. The return address is the location in the code where the computer must go once the function finishes.

Hardware designers created various methods to manage these jumps and returns. One method is the indirect jump instruction. Instead of using a fixed address, the operand is a variable or register containing the return address. This helped remove the need for self-modifying code. Another advancement was the jump to subroutine instruction. This combined the saving of the return address with the calling jump. This minimized the overhead, which is the extra work required to run the command. Different architectures handled this in unique ways. For example, the IBM System/360 used a branch instruction called BAL or BALR. These instructions saved the return address into a processor register, usually register 14.

Functions also provided a way to manage scarce resources. In the early days, memory was a very limited resource. Subroutines allowed programmers to reuse the same code in many different programs. This saved significant amounts of memory. On early computers, instructions were often loaded from punched paper tapes. A subroutine could be provided on its own separate piece of tape. These collections were known as subroutine libraries. This allowed a single subroutine tape to be used by many different programs. This concept of a library helped organize the growing complexity of computer science.

740 words

Where will your curiosity go next?

Keep exploring at your chosen reading level.

More to explore

What is Nepedia?

A free, ad-free encyclopedia for children. Every article is written at five reading levels, so the same page works for a five-year-old and a fifteen-year-old — use the level switcher above to see this one change. No account needed to read.