Function (computer programming): Difference between revisions

Content deleted Content added
m copyed.
m Reverted edit by 192.145.175.229 (talk) to last version by Chatul
 
Line 1:
{{Short description|Sequence of program instructions invokable by other software}}
[[nl:Subroutine]]
{{Other uses|Function (disambiguation){{!}}Function}}
{{Use dmy dates|date=April 2022}}
{{anchor|SUBROUTINE_DEFINITION}}
 
In [[computer programming]], a '''function''' (also '''procedure''', '''method''', '''subroutine''', '''routine''', or '''subprogram''') is a '''callable unit'''<ref>{{cite web
In [[computer programming]], a '''subprogram''' is a set of instructions in a [[computer program]] which is separated from other code to reduce [[redundancy]], and called by other subprograms or other parts of the program.
|title=Terminology Glossary
|url=https://pages.nist.gov/ElectionGlossary/
|website=nist.gov
|publisher=NIST
|quote=Callable unit: (Of a software program or logical design) Function, method, operation, subroutine, procedure, or analogous structural unit that appears within a module.
|access-date=9 February 2024}}</ref> of [[software logic]] that has a well-defined [[Interface (computing)|interface]] and [[behavior]] and can be invoked multiple times.
 
Callable units provide a powerful programming tool.<ref name="knuth1">{{cite book |title= The Art of Computer Programming, Volume I: Fundamental Algorithms |author= Donald E. Knuth |year= 1997 |author-link= Donald Knuth |publisher= Addison-Wesley |isbn=0-201-89683-4}}</ref> The primary purpose is to allow for the decomposition of a large and/or complicated problem into chunks that have relatively low [[cognitive load]] and to assign the chunks meaningful names (unless they are anonymous). Judicious application can reduce the cost of developing and maintaining software, while increasing its quality and reliability.<ref name="structprog">{{cite book |author= O.-J. Dahl |author2=E. W. Dijkstra |author3=C. A. R. Hoare |title= Structured Programming |publisher= Academic Press |year= 1972 |isbn= 0-12-200550-3}}</ref>
==Why use subprograms?==
 
Callable units are present at multiple levels of [[abstraction]] in the programming environment. For example, a [[programmer]] may write a function in [[source code]] that is compiled to [[machine code]] that implements similar [[semantics]]. There is a callable unit in the source code and an associated one in the machine code, but they are different kinds of callable units {{endash}} with different implications and features.
The possible motivations for the use of subprograms are numerous:
 
==Terminology==
* reducing redundancy,
* promoting reuse of code,
* decomposing complex problems into small pieces that are simpler,
* improving readability of program code,
* replicating mathematical [[function]]s,
* emulating hardware functionalities,
* introducing some layers within programs,
* hiding or regulating part of the program.
 
Some [[programming language]]s, such as [[COBOL]] and [[BASIC]], make a distinction between functions that return a value (typically called "functions") and those that do not (typically called "subprogram", "subroutine", or "procedure"); some, such as [[C (programming language)|C]], [[C++]], and [[Rust (programming language)|Rust]], only use the term "function" irrespective of whether they return a value or not; others, such as [[ALGOL 60]] and [[PL/I]], only use the word ''procedure''. Some [[Object-oriented programming|object-oriented]] languages, such as [[Java (programming language)|Java]] and [[C Sharp (programming language)|C#]], refer to functions inside [[Class (computer programming)|classes]] as "[[Method (computer programming)|method]]s".
Reduction of redundancy is one of the most common reasons: using subprograms, the program can make repeated use of one block of code that would otherwise be duplicated. Redundancy can be deliberately introduced to improve performance (see [[computer programming optimization|optimization]]).
 
==History==
Computer programs tend to be complex - it is hard to understand them all at one time. Therefore programs are now generally written as a number of subprograms. Subprograms are sometimes made to mimic mathematical functions, such as [[sine]] and [[cosine]]. This makes it possible for programmers to write mathematical expressions containing these functions.
 
The idea of a callable unit was initially conceived by [[John Mauchly]] and [[Kathleen Antonelli]] during their work on [[ENIAC]] and recorded in a January 1947 Harvard symposium on "Preparation of Problems for [[EDVAC]]-type Machines."<ref name=mauchly0>{{cite book |first=J.W. |last=Mauchly |chapter=Preparation of Problems for EDVAC-Type Machines |author-link=John Mauchly |editor-first=Brian |editor-last=Randell |title=The Origins of Digital Computers |doi=10.1007/978-3-642-61812-3_31 |publisher=Springer|date=1982|pages=393–397 |isbn=978-3-642-61814-7 |chapter-url=https://archive.org/details/originsofdigital0000rand/page/365}}</ref> [[Maurice Wilkes]], [[David Wheeler (British computer scientist)|David Wheeler]], and [[Stanley Gill]] are generally credited with the formal invention of this concept, which they termed a ''closed sub-routine'',<ref>{{Cite conference |last1 = Wheeler |first1 = D. J. |author-link1 = David Wheeler (computer scientist) |chapter = The use of sub-routines in programmes |doi = 10.1145/609784.609816 |title = Proceedings of the 1952 ACM national meeting (Pittsburgh) on - ACM '52 |pages = 235 |year = 1952 |chapter-url = http://www.laputan.org/pub/papers/wheeler.pdf|doi-access = free }}</ref><ref>{{cite book |last1= Wilkes |first1= M. V. |last2= Wheeler |first2= D. J. |last3= Gill |first3=S. |title= Preparation of Programs for an Electronic Digital Computer |publisher= Addison-Wesley |year= 1951}}</ref> contrasted with an ''open subroutine'' or [[Macro (computer science)|macro]].<ref>{{cite encyclopedia |last=Dainith |first=John |title="open subroutine." A Dictionary of Computing | date=2004 |url=http://www.encyclopedia.com/doc/1O11-opensubroutine.html |encyclopedia=Encyclopedia.com |access-date=January 14, 2013}}</ref> However, [[Alan Turing]] had discussed subroutines in a paper of 1945 on design proposals for the NPL [[Automatic Computing Engine|ACE]], going so far as to invent the concept of a [[Call stack|return address stack]].<ref>{{Citation | last = Turing | first =Alan M. | author-link = Alan Turing | title = Report by Dr. A.M. Turing on proposals for the development of an Automatic Computing Engine (ACE): Submitted to the Executive Committee of the NPL in February 1946 | year = 1945 }} reprinted in {{Cite book | editor-last = Copeland | editor-first = B. J. | editor-link = Jack Copeland | title = Alan Turing's Automatic Computing Engine | ___location = Oxford | publisher = Oxford University Press | publication-date = 2005 | isbn = 0-19-856593-3 | year = 2005 | url-access = registration | url = https://archive.org/details/alanturingsautom0000unse |page=383}}</ref>
Generally, subprograms are defined within computer programs. Often for consistency, built-in routines are called in the exactly the same way as user-defined subprograms. Such inconsistency is sometimes by mistake or deliberatly. Many languages such as [[C programming language]] require all code to belong to each subprogram and a specific one, the <code>main</code> function, is called at the beginning of execution.
 
The idea of a subroutine was worked out after computing machines had already existed for some time. The arithmetic and conditional jump instructions were planned ahead of time and have changed relatively little, but the special instructions used for procedure calls have changed greatly over the years. The earliest computers, such as the [[Manchester Baby]], and some early microprocessors, such as the [[RCA 1802]], did not have a single subroutine call instruction. Subroutines could be implemented, but they required programmers to use the call sequence—a series of instructions—at each [[call site]].
==Structured programming==
 
Subroutines were implemented in [[Konrad Zuse]]'s [[Z4 (computer)|Z4]] in 1945.
Some programming languages, particularly languages following the [[structured programming]] methodology such as [[Pascal programming language|Pascal]], support subprograms embedded in other subprograms.
 
In 1945, [[Alan Turing]] used the terms "bury" and "unbury" as a means of calling and returning from subroutines.<ref name="Turing_1945">{{citation |author-first=Alan Mathison |author-last=Turing |author-link=Alan Mathison Turing |title=Proposals for Development in the Mathematics Division of an Automatic Computing Engine (ACE) |date=1946-03-19 |orig-year=1945}} (NB. Presented on 1946-03-19 before the Executive Committee of the National Physical Laboratory (Great Britain).)</ref><ref name="Carpenter_1977">{{cite journal |title=The other Turing machine |author-last1=Carpenter |author-first1=Brian Edward |author-link1=Brian Carpenter (Internet engineer) |author-last2=Doran |author-first2=Robert William |author-link2=Robert William Doran |date=1977-01-01 |orig-year=October 1975 |doi=10.1093/comjnl/20.3.269 |volume=20 |issue=3 |journal=[[The Computer Journal]] |pages=269–279|doi-access=free }} (11 pages)</ref>
Although uncommon, '''subprogram''' (meaning part of program) is a concise and precise term because other commonly used terms imply a philosophy about programs. '''Subroutine''' is the term most commonly used. It is called so because it has become so common soon after invention of [[assembly language]]s and [[Fortran programming language|Fortran]] to make a common code, that is, a routine take, as routine code. Programmers tend to use this term in any language. '''Procedure''' is the most common term when algorithms are described because in mathematics, an algorithm is seen as generalized steps of computations. Some people prefer to use '''functions''' because in some languages, subprograms appear just like a part of expression or something having a value. Generally, the precise meaning of each term varies between [[programming languages]]. '''Methods''' are special kind of subprogram used in [[object-oriented programming]]. See [[method (computer science)|method]] for detail.
 
In January 1947 John Mauchly presented general notes at 'A Symposium of Large Scale Digital Calculating Machinery'
Typically, the caller waits for subprograms to finish and continues execution only after a subprogram ''returns''. Subroutines are often given [[parameter|parameters]] to refine their behavior or to perform a certain computation with given (variable) values. Values passed to a subprogram are called ''actual parameters'' (or more commonly ''arguments''), and the list of arguments a subprogram expects to be given is known as its list of ''formal parameters'' (or simply "parameters").
under the joint sponsorship of Harvard University and the Bureau of Ordnance, United States Navy. Here he discusses serial and parallel operation suggesting
{{blockquote|...the structure of the machine need not be complicated one bit. It is possible, since all the logical characteristics essential to this procedure are available, to evolve a coding instruction for placing the subroutines in the memory at places known to the machine, and in such a way that they may easily be called into use.{{pb}}In other words, one can designate subroutine A as division and subroutine B as complex multiplication and subroutine C as the evaluation of a standard error of a sequence of numbers, and so on through the list of subroutines needed for a particular problem. ... All these subroutines will then be stored in the machine, and all one needs to do is make a brief reference to them by number, as they are indicated in the coding.<ref name=mauchly0/>}}
 
[[Kathleen Antonelli|Kay McNulty]] had worked closely with John Mauchly on the [[ENIAC]] team and developed an idea for subroutines for the [[ENIAC]] computer she was programming during World War II.<ref name=":0">{{Cite web|url=http://fortune.com/2014/09/18/walter-isaacson-the-women-of-eniac/|title=Walter Isaacson on the Women of ENIAC|last=Isaacson|first=Walter|date=18 September 2014|website=Fortune|language=en|archive-url=https://web.archive.org/web/20181212003245/http://fortune.com/2014/09/18/walter-isaacson-the-women-of-eniac/|archive-date=12 December 2018|access-date=2018-12-14}}</ref> She and the other ENIAC programmers used the subroutines to help calculate missile trajectories.<ref name=":0" />
In most [[imperative programming|imperative programming languages]], subprograms may have so-called [[side-effect (computer science)|side-effects]], that is, they may cause changes that remain after the subprogram has returned. Usually, compilers cannot predict whether a subprogram has a side-effect or not, but can determine if a subprogram calls no other subprograms, or at least no other subprograms that have side-effects. In imperative programming, compilers usually assume every subprogram has a side-effect to avoid complex analysis of exection paths. Because of its side-effects, a subprogram may return different results each time it is called, even if it is called with the same arguments. A simple example is a subprogram that returns a random number each time it is called . Such behavior is invalid in a strict mathematical sense. An exception to this common behaviour is found in [[functional programming|functional programming languages]], where subprograms can have no side effects, and will always return the same result if repeatedly called with the same arguments. [<i>Note that subprograms are referred to as functions in these languages</i>].
 
[[Herman Goldstine|Goldstine]] and [[John von Neumann|von Neumann]] wrote a paper dated 16 August 1948 discussing the use of subroutines.<ref>{{cite tech report |chapter=Part II, Volume I-3, Planning and Coding of Problems for an Electronic Computing Instrument |title=Report on the Mathematical and Logical aspects of an Electronic Computing Instrument |chapter-url=https://www.ias.edu/sites/default/files/library/pdfs/ecp/planningcodingof0103inst.pdf |author1=Herman H. Goldstine |author2=John von Neumann |date=1947}} (see p. 163 of the pdf for the relevant page)</ref>
Subprograms may or may not return a value to their caller. In many [[programming language|language]]s such as [[Pascal programming language|Pascal]], a subprogram that returns a value is called a ''function'' in analogy with the [[mathematical]] sense of the term (see [[denotational semantics]]), while a subprogram that returns no value is called a ''procedure''. In some languages, including [[C programming language|C]] and [[Fortran]], this distinction is not observed. In these langauges, some special [[datatype]], such as C's <code>void</code>, denotes that the function returns no value. A specification of the [[datatype]]s accepted and returned corresponds to specifying a '''___domain''' and '''codomain''' in the mathematical sense. See [[function]].
 
Some very early computers and microprocessors, such as the [[IBM 1620]], the [[Intel 4004]] and [[Intel 8008]], and the [[PIC microcontroller]]s, have a single-instruction subroutine call that uses a dedicated hardware stack to store return addresses—such hardware supports only a few levels of subroutine nesting, but can support recursive subroutines. Machines before the mid-1960s—such as the [[UNIVAC I]], the [[PDP-1]], and the [[IBM 1130]]—typically use a [[calling convention]] which saved the instruction counter in the first memory ___location of the called subroutine. This allows arbitrarily deep levels of subroutine nesting but does not support recursive subroutines. The [[IBM System/360]] had a subroutine call instruction that placed the saved instruction counter value into a general-purpose register; this can be used to support arbitrarily deep subroutine nesting and recursive subroutines. The Burroughs [[B5000]]<ref name=B5000-21005>{{cite book
Sometimes the declaration of a subprogram is distinguished its actual definition. A few languages, notably [[C programming language|C]] and [[C Plus Plus programmin language|C++]] support declarations called prototypes which give the compiler information about a function which has yet to be defined. Some languages require subprograms to be defined or declared before they are called, while some do not.
| title = The Operational Characteristics of the Processors for the Burroughs B5000
| id = 5000-21005
| version = Revision A
| date = 1963
| publisher = [[Burroughs Corporation]]
| url = http://bitsavers.org/pdf/burroughs/LargeSystems/B5000_5500_5700/5000-21005_B5000_operChar_1963.pdf
| access-date = February 8, 2024
}}
</ref> (1961) is one of the first computers to store subroutine return data on a stack.
 
The DEC [[PDP-6]]<ref>{{cite book
In Fortran, a subprogram's local variables are stored in global space. Calling a subprogram is a sequence of storing its return address, jumping to the code of the subprogram, and finally jumping back to its return address. Today, most programming languages use [[stack-based allocation]] to store the return addresses of subprograms. Each time a subprogram is called, a record is kept on a stack (usually the system stack); this record is then deleted when the subprogram returns. This mechanism enables [[recursive]] calling of subprograms. See the next section for more details.
| title = Programmed Data Processor 6 - Handbook
| page = 37
| section = Push-Down Instructions
| section-url = http://bitsavers.org/pdf/dec/pdp6/F-65_PDP-6_Handbook_Aug64.pdf#page=35
| url = http://bitsavers.org/pdf/dec/pdp6/F-65_PDP-6_Handbook_Aug64.pdf
| access-date = February 8, 2024
}}
</ref> (1964) is one of the first accumulator-based machines to have a subroutine call instruction that saved the return address in a stack addressed by an accumulator or index register. The later [[PDP-10]] (1966), [[PDP-11]] (1970) and [[VAX-11]] (1976) lines followed suit; this feature also supports both arbitrarily deep subroutine nesting and recursive subroutines.<ref name="Steele">
[[Guy Lewis Steele Jr.]]
[[AI Memo]] 443.
[http://dspace.mit.edu/bitstream/handle/1721.1/5753/AIM-443.pdf?sequence=2 'Debunking the "Expensive Procedure Call" Myth; or, Procedure call implementations considered harmful"].
Section "C. Why Procedure Calls Have a Bad Reputation".
</ref>
 
===Language support===
== Implementation ==
In the very early assemblers, subroutine support was limited. Subroutines were not explicitly separated from each other or from the main program, and indeed the source code of a subroutine could be interspersed with that of other subprograms. Some assemblers would offer predefined [[macro (computer science)|macros]] to generate the call and return sequences. By the 1960s, assemblers usually had much more sophisticated support for both inline and separately assembled subroutines that could be linked together.
Subprograms can be implemented in two ways: subroutine calling and [[in-line expansion]].
 
One of the first programming languages to support user-written subroutines and functions was [[Fortran#FORTRAN II|FORTRAN II]]. The IBM FORTRAN II compiler was released in 1958. [[ALGOL 58]] and other early programming languages also supported procedural programming.
=== Calling sequence (stack-based) ===
When a subprogram is called, the first step is to allocate memory to hold the return address, local variables, parameters and other bookkeeping stuff required. The space is allocated on the top of the [[stack (computing)|stack]] and, is called a ''[[stack frame]]'' or ''[[activation record]]''. The size of the memory allocated for a particular subprogram can be fixed, but may vary if some of the subprogram's local variables are dynamically sized arrays. In most implementations, the [[stack pointer]] (sp), is decremented, and the frame pointer is set to the starting address of the record. The address of local variables and other stuff can be calculated by adding an offset (determined at [[compile-time]]) to the frame pointer. If the size of the record is fixed, the frame pointer is not needed because the fixed offset from the stack pointer can be used instead. If the size or number of arguments is unknown, formal parameters are placed ''below'' fixed objects such as local variables and fixed size arguments. These operations are preferablly done by the subprogram itself, because if the caller has code to perform them, such code appears each calling point, resulting in a large body of redundant code. After or before this process, the [[program counter]] (pc) is changed to the jump code of the subprogram.
 
===Libraries===
The process of returning from a subprogram is simple. The relevant stack-frame must be deleted, and the program counter must be reset to point to the bit of code from which the subprogram was called.
Even with this cumbersome approach, subroutines proved very useful. They allowed the use of the same code in many different programs. Memory was a very scarce resource on early computers, and subroutines allowed significant savings in the size of programs.
 
Many early computers loaded the program instructions into memory from a [[punched tape|punched paper tape]]. Each subroutine could then be provided by a separate piece of tape, loaded or spliced before or after the main program (or "mainline"<ref>
== Parameter passing ==
{{cite book
The way in which arguments are passed to subprograms is a complex issue. Most of the time, subprograms accept not just one but a list of arguments as is the case in functions in mathematic. The order of the list of arguments corrsponds to that of parameters; that is, the first argument is the first parameter in a subprogram and so on. Formal parameters are often given a datatype. The datatype of an argument corresponding to a formal parameter usually is the same (for example, they are both a simple integer), but can differ as long as they are compatible and the compiler knows how to translate between them.
| last1 = Frank
| first1 = Thomas S.
| title = Introduction to the PDP-11 and Its Assembly Language
| url = https://books.google.com/books?id=YN4mAAAAMAAJ
| series = Prentice-Hall software series
| publisher = Prentice-Hall
| date = 1983
| page = 195
| isbn = 9780134917047
| access-date = 2016-07-06
| quote = We could supply our assembling clerk with copies of the source code for all of our useful subroutines and then when presenting him with a mainline program for assembly, tell him which subroutines will be called in the mainline [...]
}}
</ref>); and the same subroutine tape could then be used by many different programs. A similar approach was used in computers that loaded program instructions from [[punched card]]s. The name ''subroutine library'' originally meant a library, in the literal sense, which kept indexed collections of tapes or decks of cards for collective use.
 
===Return by indirect jump===
The more complex a subprogram's task is, the more the number of parameters tend to be. It makes difficult to remember for human programmers the number, order and type of arguments. '''Named parameters''' is a way to place a name tag to each parameter so that the order of arguments becomes irrelevant. '''Default parameters''' are ones that can be omited in a list of arguments and in that case, values or expressions defined before are used. C++ supports default parameters and [[Ada programming language|Ada]] supports both.
To remove the need for [[self-modifying code]], computer designers eventually provided an ''[[indirect branch|indirect jump]]'' instruction, whose operand, instead of being the [[return statement|return address]] itself, was the ___location of a variable or [[processor register]] containing the return address.
 
On those computers, instead of modifying the function's return jump, the calling program would store the return address in a variable so that when the function completed, it would execute an indirect jump that would direct execution to the ___location given by the predefined variable.
In many [[operating system]]s [[API]]s, a composite datatype is used instead of a list of parameters because C, which is typically used in such system programming, does not support named parameters or default parameters above. Advocates of [[object-oriented programming]] recommend to decompose such a complex subprogram into classes or objects with small methods.
 
===Jump to subroutine===
[<i>TODO: Add information about out, in and out/in modifiers</i>]
Another advance was the ''jump to subroutine'' instruction, which combined the saving of the return address with the calling jump, thereby minimizing [[computational overhead|overhead]] significantly.
 
In the IBM [[System/360]], for example, the branch instructions BAL or BALR, designed for procedure calling, would save the return address in a processor register specified in the instruction, by convention register 14. To return, the subroutine had only to execute an indirect branch instruction (BR) through that register. If the subroutine needed that register for some other purpose (such as calling another subroutine), it would save the register's contents to a private memory ___location or a register [[stack (data structure)|stack]].
=== Call by reference, call by value and call by name ===
Parameters can be passed to subprograms in several ways:
 
In systems such as the [[HP 2100]], the JSB instruction would perform a similar task, except that the return address was stored in the memory ___location that was the target of the branch. Execution of the procedure would actually begin at the next memory ___location. In the HP 2100 assembly language, one would write, for example
In the '''call-by-reference''' mechanism, the caller passes a [[pointer]] to each argument instead of passing a copy of it. When a subprogram which has been called-by-reference modifies one of its parameters, the object changes from the caller's perspective as well. Call-by-reference can be simulated in some call-by-value languages (for example, in C, one can pass a pointer to an object as an argument, instead of a copy of the object itself).
 
<syntaxhighlight lang="text">
In the '''call-by-value''' mechanism, a copy of each argument is passed to the subprogram, which prevents changes to the arguments outside the subprogram. In [[Visual Basic]], the ByVal modifier states parameters are passed by value.
...
JSB MYSUB (Calls subroutine MYSUB.)
BB ... (Will return here after MYSUB is done.)
</syntaxhighlight>
 
to call a subroutine called MYSUB from the main program. The subroutine would be coded as
[<i>TODO: Add information about call-by-name</i>]
 
<syntaxhighlight lang="text">
== Polymorphism ==
MYSUB NOP (Storage for MYSUB's return address.)
See [[polymorphism (computer science)|polymorphism]] for what it is.
AA ... (Start of MYSUB's body.)
...
JMP MYSUB,I (Returns to the calling program.)
</syntaxhighlight>
 
The JSB instruction placed the address of the NEXT instruction (namely, BB) into the ___location specified as its operand (namely, MYSUB), and then branched to the NEXT ___location after that (namely, AA = MYSUB + 1). The subroutine could then return to the main program by executing the indirect jump JMP MYSUB, I which branched to the ___location stored at ___location MYSUB.
Subprograms more or less support polymorphic behaviors with overloading and overriding. Overloading is a way to provide several subprograms that differ in terms of datatype of arguments and that of return-value. What differentiates them is called ''signature''. This kind of polymorphism is especially called '''parametric polymorphism'''. Overriding, in turn, is to replace subprograms with other ones, mostly method for a subclass. When combined with [[late binding]] this is the basic means of achieving the [[polymorphism (computer science)|polymorphism]] of an object oriented design in an object-oriented programming language besides overloading. They both are usually considered a fundamental aspect of [[object-oriented programming]] and many sophisticated languages such as Ada and [[functional language]]s supports this.
 
Compilers for Fortran and other languages could easily make use of these instructions when available. This approach supported multiple levels of calls; however, since the return address, parameters, and return values of a subroutine were assigned fixed memory locations, it did not allow for recursive calls.
== Examples and common subprograms ==
* [[hash function]]
* [[Block cipher]]
* [[Application Programming Interface]] (API)
 
Incidentally, a similar method was used by [[Lotus 1-2-3]], in the early 1980s, to discover the recalculation dependencies in a spreadsheet. Namely, a ___location was reserved in each cell to store the ''return'' address. Since [[circular reference]]s are not allowed for natural recalculation order, this allows a tree walk without reserving space for a stack in memory, which was very limited on small computers such as the [[IBM PC]].
Wrapper functions (or commonly just wrapper) are subprograms that simply call another one. They are used to change the order or datatype of arguments or bridge a gap between new and old versions by old ones (referred to as deprecated) just calling new ones. Win16 APIs in 32-bit Windows operating systems that only call win32 apis are example. The functionality of them is sometimes similar to [[adapter pattern]].
<!--
Mention the [[link register]] of the IBM 360
-->
 
===Call See also stack===
Most modern implementations of a function call use a [[call stack]], a special case of the [[stack (data structure)|stack data structure]], to implement function calls and returns. Each procedure call creates a new entry, called a ''stack frame'', at the top of the stack; when the procedure returns, its stack frame is deleted from the stack, and its space may be used for other procedure calls. Each stack frame contains the ''private data'' of the corresponding call, which typically includes the procedure's parameters and internal variables, and the return address.
* [[reentrant]] (lit. entrace again) - a subprogram that can be called again
 
* [[Putpixel]] - Common name for a subroutine that should a value in a computer's video RAM, that should later be displayed as a pixel on a computer's screen.
The call sequence can be implemented by a sequence of ordinary instructions (an approach still used in [[reduced instruction set computing]] (RISC) and [[very long instruction word]] (VLIW) architectures), but many traditional machines designed since the late 1960s have included special instructions for that purpose.<!--Example needed, preferably from the first computers/compilers to use this scheme-->
* [[parameter]] - duplicate discussion about parameters
 
* [[closure]] - a subprogram that can be handled as a variable
The call stack is usually implemented as a contiguous area of memory. It is an arbitrary design choice whether the bottom of the stack is the lowest or highest address within this area, so that the stack may grow forwards or backwards in memory; however, many architectures chose the latter.{{Citation needed|date=November 2008}}
 
Some designs, notably some [[Forth (programming language)|Forth]] implementations, used two separate stacks, one mainly for control information (like return addresses and loop counters) and the other for data. The former was, or worked like, a call stack and was only indirectly accessible to the programmer through other language constructs while the latter was more directly accessible.
 
When stack-based procedure calls were first introduced, an important motivation was to save precious memory.{{Citation needed|date=November 2008}} With this scheme, the compiler does not have to reserve separate space in memory for the private data (parameters, return address, and local variables) of each procedure. At any moment, the stack contains only the private data of the calls that are currently ''active'' (namely, which have been called but haven't returned yet). Because of the ways in which programs were usually assembled from libraries, it was (and still is) not uncommon to find programs that include thousands of functions, of which only a handful are active at any given moment.{{Citation needed|date=November 2008}} For such programs, the call stack mechanism could save significant amounts of memory. Indeed, the call stack mechanism can be viewed as the earliest and simplest method for [[garbage collection (computer science)|automatic memory management]].<!-- mention somewhere that some linkers in the 1970s would analyze the call graph and allocate the call frames statically but in overlapping memory locations whenever possible.-->
 
However, another advantage of the call stack method is that it allows [[recursion (computer science)|recursive function calls]], since each nested call to the same procedure gets a separate instance of its private data.<!--To mention: (0) current stack frame pointer/register (1) stack machines (B6500), (2) recursion in Algol and LISP, (3) each thread requires a separate stack (4) return value on the stack (4) spaghetti stacks for multi-threaded programs and persistent local variables (5) effect of call stack on virtual memory (6) multiple stacks for different kinds of data, e.g. return address-->
 
In a [[thread (computer science)|multi-threaded]] environment, there is generally more than one stack.<ref name="ButtlarFarrellNichols1996">{{cite book | first1 = Dick |last1=Buttlar | first2 = Jacqueline |last2=Farrell | first3 = Bradford |last3=Nichols | date=1996 | title = PThreads Programming: A POSIX Standard for Better Multiprocessing | publisher = "O'Reilly Media, Inc." | pages =2–5 | isbn = 978-1-4493-6475-5 | oclc = 1036778036 | url = https://books.google.com/books?id=vjgEEAAAQBAJ&pg=PA2}}</ref> An environment that fully supports [[coroutine]]s or [[lazy evaluation]] may use data structures other than stacks to store their activation records.
 
====Delayed stacking {{anchor|Leaf procedure}}{{anchor|Leaf function}}====
 
One disadvantage of the call stack mechanism is the increased cost of a procedure call and its matching return.{{ clarify | date = November 2015 | reason = increased relative to what?}} The extra cost includes incrementing and decrementing the stack pointer (and, in some architectures, checking for [[stack overflow]]), and accessing the local variables and parameters by frame-relative addresses, instead of absolute addresses. The cost may be realized in increased execution time, or increased processor complexity, or both.
 
This overhead is most obvious and objectionable in ''leaf procedures'' or ''[[leaf function]]s'', which return without making any procedure calls themselves.<ref>{{cite web|url=http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka13785.html |title=ARM Information Center |publisher=Infocenter.arm.com |access-date=2013-09-29}}</ref><ref>{{cite web |title=x64 stack usage |url=https://docs.microsoft.com/en-us/cpp/build/stack-usage |website=Microsoft Docs |publisher=Microsoft |access-date=5 August 2019}}</ref><ref>{{cite web|url=http://msdn.microsoft.com/en-us/library/67fa79wz%28v=VS.90%29.aspx |title=Function Types |publisher=Msdn.microsoft.com |access-date=2013-09-29}}</ref> To reduce that overhead, many modern compilers try to delay the use of a call stack until it is really needed.{{Citation needed|date=June 2011}} For example, the call of a procedure ''P'' may store the return address and parameters of the called procedure in certain processor registers, and transfer control to the procedure's body by a simple jump. If the procedure ''P'' returns without making any other call, the call stack is not used at all. If ''P'' needs to call another procedure ''Q'', it will then use the call stack to save the contents of any registers (such as the return address) that will be needed after ''Q'' returns.<!-- Mention caller-saves vs. callee-saves?-->
<!---If the procedure or function itself uses stack handling commands, outside of the prologue and epilogue, e.g. to store intermediate calculation values, the programmer needs to keep track of the number of 'push' and 'pop' instructions so as not to corrupt the original return address.-->
<!--Major cleanup needed from this point on-->
 
== Features ==
{{uncited section|date=August 2025}}
 
In general, a callable unit is a list of instructions that, starting at the first instruction, executes sequentially except as directed via its internal logic. It can be invoked (called) many times during the [[Execution (computing)|execution]] of a program. Execution continues at the next instruction after the call instruction when it [[Return statement|returns]] control.
 
== Implementations ==
 
The features of [[implementation]]s of callable units evolved over time and varies by context.
This section describes features of the various common implementations.
 
=== General characteristics ===
 
Most modern programming languages provide features to define and call functions, including [[syntax (programming languages)|syntax]] for accessing such features, including:
 
* Delimit the implementation of a function from the rest of the program
* Assign an [[identifier]], name, to a function
* Define [[formal parameters]] with a name and [[data type]] for each
* Assign a [[data type]] to the return value, if any
* Specify a return value in the function body
* Call a function
* Provide [[actual parameters]] that correspond to a called function's formal parameters
* [[return statement|Return]] control to the caller at the point of call
* Consume the return value in the caller
* Dispose of the values returned by a call
* Provide a private [[scope (computer science)|naming scope]] for variables
* Identify variables outside the function that are accessible within it
* Propagate an [[exception handling|exceptional condition]] out of a function and to handle it in the calling context
* Package functions into a container such as [[modular programming|module]], [[library (computing)|library]], [[object (computer science)|object]], or [[class (computer programming)|class]]
 
=== Naming ===
 
Some languages, such as [[Pascal (programming language)|Pascal]], [[Fortran]], [[Ada (programming language)|Ada]] and many [[Dialect (computing)|dialects]] of [[BASIC]], use a different name for a callable unit that returns a value (''function'' or ''subprogram'') vs. one that does not (''subroutine'' or ''procedure'').
Other languages, such as [[C (programming language)|C]], [[C++]], [[C Sharp (programming language)|C#]] and [[Lisp (programming language)|Lisp]], use only one name for a callable unit, ''function''. The C-family languages use the keyword <code>void</code> to indicate no return value.
 
=== Call syntax ===
 
If declared to return a value, a call can be embedded in an [[expression (programming)|expression]] in order to consume the return value. For example, a square root callable unit might be called like <code>y = sqrt(x)</code>.
 
A callable unit that does not return a value is called as a stand-alone [[statement (computer science)|statement]] like <code>print("hello")</code>. This syntax can also be used for a callable unit that returns a value, but the return value will be ignored.
 
Some older languages require a keyword for calls that do not consume a return value, like <code>CALL print("hello")</code>.
 
=== Parameters ===
 
Most implementations, especially in modern languages, support [[parameter (computer science)|parameters]] which the callable declares as ''formal parameters''. A caller passes ''actual parameters'', a.k.a. ''arguments'', to match. Different programming languages provide different conventions for passing arguments.
 
{| class="wikitable"
|-
! Convention !! Description !! Used in
|-
| [[Call by value|by value]] || A copy of the argument is passed || Default in most Algol-like languages after [[Algol 60]], such as Pascal, Delphi, Simula, CPL, PL/M, Modula, Oberon, Ada, and many others including C, C++ and Java
|-
| [[Call by reference|by reference]] || A reference to the argument is passed; typically its address || Selectable in most Algol-like languages after [[Algol 60]], such as Algol 68, Pascal, Delphi, Simula, CPL, PL/M, Modula, Oberon, Ada, and many others including C++, Fortran, PL/I
|-
| [[Call by result|by result]] || The value computed during the call is copied to the argument on return || Ada OUT parameters
|-
| [[Call by value-result|by value-result]] || A copy of the argument is passed in and the value computed during the call is copied to the argument on return || Algol, [[Swift (programming language)|Swift]] in-out parameters
|-
| [[Call by name|by name]] || Like a macro &ndash; replace the parameters with the unevaluated argument expressions, then evaluate the argument in the context of the caller every time that the callable uses the parameter || Algol, [[Scala (programming language)|Scala]]
|-
| by constant value || Like by-value except that the parameter is treated as a constant || PL/I NONASSIGNABLE parameters, Ada IN parameters
|}
 
=== Return value ===
 
In some languages, such as BASIC, a callable has different syntax (i.e. keyword) for a callable that returns a value vs. one that does not.
In other languages, the syntax is the same regardless.
In some of these languages an extra keyword is used to declare no return value; for example <code>void</code> in C, C++ and C#.
In some languages, such as Python, the difference is whether the body contains a return statement with a value, and a particular callable may return with or without a value based on control flow.
 
=== Side effects ===
 
In many contexts, a callable may have [[side-effect (computer science)|side effect]] behavior such as modifying passed or global data, reading from or writing to a [[peripheral device]], accessing a [[computer file|file]], halting the program or the machine, or temporarily pausing program execution.
 
Side effects are considered undesirable by [[Robert C. Martin]], who is known for promoting design principles. Martin argues that side effects can result in [[sequential coupling|temporal coupling]] or order dependencies.<ref name="clean code">{{cite book |last1=Martin |first1=Robert C. |title=Clean Code: A Handbook of Agile Software Craftsmanship |date=Aug 1, 2008 |publisher=[[Pearson PLC|Pearson]] |isbn=9780132350884 |edition=1 |url=https://www.oreilly.com/library/view/clean-code-a/9780136083238/ |access-date=19 May 2024}}</ref>
 
In strictly [[functional programming]] languages such as [[Haskell (programming language)|Haskell]], a function can have no [[Side effect (computer science)|side effects]], which means it cannot change the state of the program. Functions always return the same result for the same input. Such languages typically only support functions that return a value, since there is no value in a function that has neither return value nor side effect.
 
{{Anchor|LVRR}} <!--what is this?-->
 
=== Local variables ===
 
Most contexts support ''local variables'' {{endash}} [[virtual memory|memory]] owned by a callable to hold intermediate values. These variables are typically stored in the call's ''activation record'' on the [[call stack]] along with other information such as the [[return address (computing)|return address]].
 
=== Nested call {{endash}} recursion ===
 
If supported by the language, a callable may call itself, causing its execution to suspend while another ''nested'' execution of the same callable executes. [[Recursion (computer science)|Recursion]] is a useful means to simplify some complex algorithms and break down complex problems. Recursive languages provide a new copy of local variables on each call. If the programmer desires the recursive callable to use the same variables instead of using locals, they typically declare them in a shared context such static or global.
 
Languages going back to [[ALGOL]], [[PL/I]] and [[C (programming language)|C]] and modern languages, almost invariably use a call stack, usually supported by the instruction sets to provide an activation record for each call. That way, a nested call can modify its local variables without affecting any of the suspended calls variables.
 
Recursion allows direct implementation of functionality defined by [[mathematical induction]] and recursive [[divide and conquer algorithm]]s. Here is an example of a recursive function in C/C++ to find [[Fibonacci sequence|Fibonacci numbers]]:
 
<syntaxhighlight lang="c">
int Fib(int n) {
if (n <= 1) {
return n;
}
return Fib(n - 1) + Fib(n - 2);
}
</syntaxhighlight>
 
Early languages like [[Fortran]] did not initially support recursion because only one set of variables and return address were allocated for each callable.<ref name="BöckenhauerKommUnger2018">{{cite book |last=Verhoeff |first=Tom |chapter=A Master Class on Recursion| editor-first1 = Hans-Joachim |editor-last1 = Böckenhauer | editor-first2 = Dennis |editor-last2=Komm | editor-first3 = Walter |editor-last3=Unger | date = 2018 | title = Adventures Between Lower Bounds and Higher Altitudes: Essays Dedicated to Juraj Hromkovič on the Occasion of His 60th Birthday | publisher = Springer | pages =616 | isbn = 978-3-319-98355-4 | oclc = 1050567095 | chapter-url = https://books.google.com/books?id=Z_5sDwAAQBAJ&pg=PA616}}</ref> Early computer instruction sets made storing return addresses and variables on a stack difficult. Machines with [[index registers]] or [[general-purpose registers]], e.g., [[CDC 6000 series]], [[PDP-6]], [[GE 635]], [[System/360]], [[UNIVAC 1100 series]], could use one of those registers as a [[stack pointer]].
 
=== Nested scope ===
 
{{main|Nested function}}
 
Some languages, e.g., [[Ada (programming language)|Ada]], [[Pascal (programming language)|Pascal]], [[PL/I]], [[Python (programming language)|Python]], support declaring and defining a function inside, e.g., a function body, such that the name of the inner is only visible within the body of the outer.
 
A simple example in Pascal:<syntaxhighlight lang="pascal">function E(x: real): real;
function F(y: real): real;
begin
F := x + y
end;
begin
E := F(3) + F(4)
end;</syntaxhighlight>The function <code>F</code> is nested within <code>E</code>. Note that <code>E</code>'s parameter <code>x</code> is also visible in <code>F</code> (as <code>F</code> is a part of <code>E</code>) while both <code>x</code> and <code>y</code> are invisible outside <code>E</code> and <code>F</code> respectively.
 
=== Reentrancy ===
 
If a callable can be executed properly even when another execution of the same callable is already in progress, that callable is said to be ''[[reentrant (subroutine)|reentrant]]''. A reentrant callable is also useful in [[thread (computer science)|multi-threaded]] situations since multiple threads can call the same callable without fear of interfering with each other. In the [[IBM]] [[CICS]] [[transaction processing system]], ''quasi-reentrant'' was a slightly less restrictive, but similar, requirement for application programs that were shared by many threads.
 
=== Overloading ===
 
{{main|Function overloading}}
 
Some languages support ''overloading'' {{endash}} allow multiple callables with the same name in the same scope, but operating on different types of input. Consider the square root function applied to real number, complex number and matrix input. The algorithm for each type of input is different, and the return value may have a different type. By writing three separate callables with the same name. i.e. ''sqrt'', the resulting code may be easier to write and to maintain since each one has a name that is relatively easy to understand and to remember instead of giving longer and more complicated names like ''sqrt_real'', ''sqrt_complex'', ''qrt_matrix''.
 
Overloading is supported in many languages that support [[strong typing]]. Often the compiler selects the overload to call based on the type of the input arguments or it fails if the input arguments do not select an overload. Older and weakly-typed languages generally do not support overloading.
 
Here is an example of overloading in [[C++]], two functions <code>Area</code> that accept different types:
 
<syntaxhighlight lang="cpp">
// returns the area of a rectangle defined by height and width
double Area(double h, double w) { return h * w; }
 
// returns the area of a circle defined by radius
double Area(double r) { return r * r * 3.14; }
 
int main() {
double rectangle_area = Area(3, 4);
double circle_area = Area(5);
}
</syntaxhighlight>
 
PL/I has the <code>GENERIC</code> attribute to define a generic name for a set of entry references called with different types of arguments. Example:
<pre>
DECLARE gen_name GENERIC(
name WHEN(FIXED BINARY),
flame WHEN(FLOAT),
pathname OTHERWISE);</pre>
Multiple argument definitions may be specified for each entry. A call to "gen_name" will result in a call to "name" when the argument is FIXED BINARY, "flame" when FLOAT", etc. If the argument matches none of the choices "pathname" will be called.
 
=== Closure ===
 
{{main|Closure (computer science)}}
 
A ''[[closure (computer science)|closure]]'' is a callable plus values of some of its variables captured from the environment in which it was created. Closures were a notable feature of the Lisp programming language, introduced by [[John McCarthy (computer scientist)|John McCarthy]]. Depending on the implementation, closures can serve as a mechanism for side-effects.
 
=== Exception reporting ===
 
Besides its [[happy path]] behavior, a callable may need to inform the caller about an [[Exception (computer science)|exceptional]] condition that occurred during its execution.
 
Most modern languages support exceptions which allows for exceptional control flow that pops the call stack until an exception handler is found to handle the condition.
 
Languages that do not support exceptions can use the return value to indicate success or failure of a call. Another approach is to use a well-known ___location like a global variable for success indication. A callable writes the value and the caller reads it after a call.
 
In the [[IBM System/360]], where return code was expected from a subroutine, the return value was often designed to be a multiple of 4—so that it could be used as a direct [[branch table]] index into a branch table often located immediately after the call instruction to avoid extra conditional tests, further improving efficiency. In the [[System/360]] [[assembly language]], one would write, for example:
 
<syntaxhighlight lang="text">
BAL 14, SUBRTN01 go to a subroutine, storing return address in R14
B TABLE(15) use returned value in reg 15 to index the branch table,
* branching to the appropriate branch instr.
TABLE B OK return code =00 GOOD }
B BAD return code =04 Invalid input } Branch table
B ERROR return code =08 Unexpected condition }
</syntaxhighlight>
 
=== Call overhead ===
 
A call has runtime [[computational overhead|overhead]], which may include but is not limited to:
 
* Allocating and reclaiming call stack storage
* Saving and restoring processor registers
* Copying input variables
* Copying values after the call into the caller's context
* Automatic testing of the return code
* Handling of exceptions
* Dispatching such as for a virtual method in an object-oriented language
 
Various techniques are employed to minimize the runtime cost of calls.
 
==== Compiler optimization ====
 
Some optimizations for minimizing call overhead may seem straight forward, but cannot be used if the callable has side effects. For example, in the expression <code>(f(x)-1)/(f(x)+1)</code>, the function <code>f</code> cannot be called only once with its value used two times since the two calls may return different results. Moreover, in the few languages which define the order of evaluation of the division operator's operands, the value of <code>x</code> must be fetched again before the second call, since the first call may have changed it. Determining whether a callable has a side effect is difficult {{endash}} indeed, [[undecidable problem|undecidable]] by virtue of [[Rice's theorem]]. So, while this optimization is safe in a purely functional programming language, a compiler for a language not limited to functional typically assumes the worst case, that every callable may have side effects.
 
==== Inlining ====
 
[[inline expansion|Inlining]] eliminates calls for particular callables. The compiler replaces each call with the compiled code of the callable. Not only does this avoid the call overhead, but it also allows the [[compiler]] to [[code optimization|optimize]] code of the caller more effectively by taking into account the context and arguments at that call. Inlining, however, usually increases the compiled code size, except when only called once or the body is very short, like one line.
 
=== Sharing ===
 
Callables can be defined within a program, or separately in a [[Library (computing)|library]] that can be used by multiple programs.
 
=== Inter-operability ===
 
A [[compiler]] translates call and return statements into machine instructions according to a well-defined [[calling convention]]. For code compiled by the same or a compatible compiler, functions can be compiled separately from the programs that call them. The instruction sequences corresponding to call and return statements are called the procedure's [[function prologue|prologue and epilogue]].
 
=== Built-in functions ===
 
{{Anchor|Built-in function}}
{{main|Intrinsic function}}
A ''built-in function'', or ''builtin function'', or ''intrinsic function'', is a function for which the compiler generates code at [[compile time]] or provides in a way other than for other functions.<ref>{{cite web |title=Built-in functions |url=https://www.ibm.com/docs/en/zos/2.2.0?topic=lf-built-in-functions |website=ibm.com | date=9 March 2017 |access-date=December 25, 2023}}</ref> A built-in function does not need to be defined like other functions since it is ''built in'' to the programming language.<ref>{{cite book |title=Study Material Python |date=April 2023 |page=87 |url=https://books.google.com/books?id=d0nhEAAAQBAJ&pg=PA87 |access-date=December 25, 2023}}</ref>
 
== Programming ==
 
=== Trade-offs ===
 
==== Advantages ====
 
Advantages of breaking a program into functions include:
 
* [[Decomposition (computer science)|Decomposing]] a complex programming task into simpler steps: this is one of the two main tools of [[structured programming]], along with [[data structure]]s
* Reducing [[duplicate code]] within a program
* Enabling [[Code reuse|reuse of code]] across multiple programs
* Dividing a large programming task among various programmers or various stages of a project
* [[Information hiding|Hiding implementation details]] from users of the function
* Improving readability of code by replacing a block of code with a function call where a [https://books.google.com/books?id=_i6bDeoCQzsC&pg=PA39&dq=descriptive+function+name descriptive] function name serves to describe the block of code. This makes the calling code concise and readable even if the function is not meant to be reused.
* Improving [[Traceability#Software|traceability]] (i.e. most languages offer ways to obtain the call trace which includes the names of the involved functions and perhaps even more information such as file names and line numbers); by not decomposing the code into functions, debugging would be severely impaired
 
==== Disadvantages ====
 
Compared to using in-line code, invoking a function imposes some [[computational overhead]] in the call mechanism.{{Citation needed|date=February 2021}}
 
A function typically requires standard [[housekeeping (computing)|housekeeping]] code – both at the entry to, and exit from, the function ([[function prologue|function prologue and epilogue]] – usually saving [[general purpose register]]s and return address as a minimum).
 
=== Conventions ===
 
Many programming conventions have been developed regarding callables.
 
With respect to naming, many developers name a callable with a phrase starting with a [[verb]] when it does a certain task, with an [[adjective]] when it makes an inquiry, and with a [[noun]] when it is used to substitute variables.
 
Some programmers suggest that a callable should perform exactly one task, and if it performs more than one task, it should be split up into multiple callables. They argue that callables are key components in [[software maintenance]], and their roles in the program must remain distinct.
 
Proponents of [[modular programming]] advocate that each callable should have minimal dependency on the rest of the [[codebase]]. For example, the use of [[global variable]]s is generally deemed unwise, because it adds coupling between all callables that use the global variables. If such coupling is not necessary, they advise to [[code refactoring|refactor]] callables to accept passed [[parameter (computer programming)|parameters]] instead.
 
== Examples ==
 
=== Early BASIC ===
 
Early BASIC variants require each line to have a unique number ([[line number]]) that orders the lines for execution, provides no separation of the code that is callable, no mechanism for passing arguments or to return a value and all variables are global. It provides the command <code>GOSUB</code> where ''sub'' is short for ''sub procedure'', ''subprocedure'' or ''subroutine''. Control jumps to the specified line number and then continues on the next line on return.
 
<syntaxhighlight lang="BASIC">
10 REM A BASIC PROGRAM
20 GOSUB 100
30 GOTO 20
100 INPUT “GIVE ME A NUMBER”; N
110 PRINT “THE SQUARE ROOT OF”; N;
120 PRINT “IS”; SQRT(N)
130 RETURN
</syntaxhighlight>
 
This code repeatedly asks the user to enter a number and reports the square root of the value. Lines 100-130 are the callable.
 
===Small Basic===
 
In [[Microsoft Small Basic]], targeted to the student first learning how to program in a text-based language, a callable unit is called a ''subroutine''.
The <code>Sub</code> keyword denotes the start of a subroutine and is followed by a name identifier. Subsequent lines are the body which ends with the <code>EndSub</code> keyword.
<ref>{{cite web |title=Small Basic |url=https://smallbasic-publicwebsite.azurewebsites.net/ |website=Small Basic |access-date=8 February 2024}}</ref>
 
<syntaxhighlight lang="vbnet">
Sub SayHello
TextWindow.WriteLine("Hello!")
EndSub
</syntaxhighlight>
 
This can be called as <code>SayHello()</code>.
<ref>{{cite web |title=Small Basic Getting Started Guide: Chapter 9: Subroutines |date=17 January 2024 |url=https://social.technet.microsoft.com/wiki/contents/articles/16077.small-basic-getting-started-guide-chapter-9-subroutines.aspx |publisher=Microsoft }}</ref>
 
===Visual Basic===
 
In later versions of [[Visual Basic]] (VB), including the [[Visual Basic (.NET)|latest product line]] and [[Visual Basic (classic)|VB6]], the term ''procedure'' is used for the callable unit concept. The keyword <code>Sub</code> is used to return no value and <code>Function</code> to return a value. When used in the context of a class, a procedure is a method.
<ref>{{cite web |title=Procedures in Visual Basic |url=https://learn.microsoft.com/en-us/dotnet/visual-basic/programming-guide/language-features/procedures/ |website=Microsoft Learn |date=15 September 2021 |access-date=8 February 2024}}</ref>
 
Each parameter has a [[data type]] that can be specified, but if not, defaults to <code>Object</code> for later versions based on [[.NET]] and [[variant type|variant]] for [[Visual Basic 6|VB6]].<ref>{{cite web |title=Dim statement (Visual Basic) |url=https://learn.microsoft.com/en-us/dotnet/visual-basic/language-reference/statements/dim-statement |website=Microsoft Learn |date=15 September 2021 |access-date=8 February 2024}}</ref>
 
VB supports parameter passing conventions [[call by value|by value]] and [[call by reference|by reference]] via the keywords <code>ByVal</code> and <code>ByRef</code>, respectively.
Unless <code>ByRef</code> is specified, an argument is passed <code>ByVal</code>. Therefore, <code>ByVal</code> is rarely explicitly specified.
 
For a simple type like a number these conventions are relatively clear. Passing <code>ByRef</code> allows the procedure to modify the passed variable whereas passing <code>ByVal</code> does not. For an object, semantics can confuse programmers since an object is always treated as a reference. Passing an object <code>ByVal</code> copies the reference; not the state of the object. The called procedure can modify the state of the object via its methods yet cannot modify the object reference of the actual parameter.
 
<syntaxhighlight lang="vbnet">
Sub DoSomething()
' Some Code Here
End Sub
</syntaxhighlight>
 
The does not return a value and has to be called stand-alone, like <code>DoSomething</code>
 
<syntaxhighlight lang="vbnet">
Function GiveMeFive() as Integer
GiveMeFive= 5
End Function
</syntaxhighlight>
 
This returns the value 5, and a call can be part of an expression like <code>y = x + GiveMeFive()</code>
 
<syntaxhighlight lang="vbnet">
Sub AddTwo(ByRef intValue as Integer)
intValue = intValue + 2
End Sub
</syntaxhighlight>
 
This has a side-effect {{endash}} modifies the variable passed by reference and could be called for variable <code>v</code> like <code>AddTwo(v)</code>. Giving v is 5 before the call, it will be 7 after.
 
===C and C++===
 
In [[C (programming language)|C]] and [[C++]], a callable unit is called a ''function''.
A function definition starts with the name of the type of value that it returns or <code>void</code> to indicate that it does not return a value. This is followed by the function name, formal arguments in parentheses, and body lines in braces.
 
In [[C++]], a function declared in a [[class (computer programming)|class]] (as non-static) is called a ''member function'' or ''method''. A function outside of a class can be called a ''free function'' to distinguish it from a member function.
<ref>{{cite web|title=what is meant by a free function|url=https://stackoverflow.com/questions/4861914/what-is-the-meaning-of-the-term-free-function-in-c}}</ref>
 
<syntaxhighlight lang="c">
void doSomething() {
/* some code */
}
</syntaxhighlight>
 
This function does not return a value and is always called stand-alone, like <code>doSomething()</code>
 
<syntaxhighlight lang="c">
int giveMeFive() {
return 5;
}
</syntaxhighlight>
 
This function returns the integer value 5. The call can be stand-alone or in an expression like <code>y = x + giveMeFive()</code>
 
<syntaxhighlight lang="c">
void addTwo(int *pi) {
*pi += 2;
}
</syntaxhighlight>
 
This function has a side-effect {{endash}} modifies the value passed by address to the input value plus 2. It could be called for variable <code>v</code> as <code>addTwo(&v)</code> where the ampersand (&) tells the compiler to pass the address of a variable. Giving v is 5 before the call, it will be 7 after.
 
<syntaxhighlight lang="c">
void addTwo(int& i) {
i += 2;
}
</syntaxhighlight>
 
This function requires C++ {{endash}} would not compile as C. It has the same behavior as the preceding example but passes the actual parameter by reference rather than passing its address. A call such as <code>addTwo(v)</code> does not include an ampersand since the compiler handles passing by reference without syntax in the call.
 
===PL/I===
 
In [[PL/I]] a called procedure may be passed a ''[[Data descriptor|descriptor]]'' providing information about the argument, such as string lengths and array bounds. This allows the procedure to be more general and eliminates the need for the programmer to pass such information. By default PL/I passes arguments by reference. A (trivial) function to change the sign of each element of a two-dimensional array might look like:
<pre>
change_sign: procedure(array);
declare array(*,*) float;
array = -array;
end change_sign;
</pre>
 
This could be called with various arrays as follows:
<pre>
/* first array bounds from -5 to +10 and 3 to 9 */
declare array1 (-5:10, 3:9)float;
/* second array bounds from 1 to 16 and 1 to 16 */
declare array2 (16,16) float;
call change_sign(array1);
call change_sign(array2);
</pre>
 
===Python===
 
In [[Python (programming language)|Python]], the keyword <code>def</code> denotes the start of a function definition. The statements of the function body follow as indented on subsequent lines and end at the line that is indented the same as the first line or end of file.<ref>{{Cite web|url=https://docs.python.org/3.9/tutorial/controlflow.html#defining-functions|title=4. More Control Flow Tools — Python 3.9.7 documentation}}</ref>
 
<syntaxhighlight lang="python">
def format_greeting(name):
return "Welcome " + name
def greet_martin():
print(format_greeting("Martin"))
</syntaxhighlight>
 
The first function returns greeting text that includes the name passed by the caller. The second function calls the first and is called like <code>greet_martin()</code> to write "Welcome Martin" to the console.
 
===Prolog===
 
In the procedural interpretation of [[logic programming|logic programs]], logical implications behave as goal-reduction procedures. A [[Rule-based system|rule]] (or [[Clause (logic)|clause]]) of the form:
 
:<code>A :- B</code>
 
which has the logical reading:
 
:<code>A if B</code>
 
behaves as a procedure that reduces goals that [[Unification (computer science)|unify]] with <code>A</code> to subgoals that are instances of<code>B</code>.
 
Consider, for example, the Prolog program:
 
<syntaxhighlight lang="prolog">
mother_child(elizabeth, charles).
father_child(charles, william).
father_child(charles, harry).
parent_child(X, Y) :- mother_child(X, Y).
parent_child(X, Y) :- father_child(X, Y).
</syntaxhighlight>
 
Notice that the motherhood function, <syntaxhighlight lang="prolog" inline> X = mother(Y)</syntaxhighlight> is represented by a relation, as in a [[relational database]]. However, ''relations'' in Prolog ''function'' as callable units.
 
For example, the procedure call <syntaxhighlight lang="prolog" inline>?- parent_child(X, charles)</syntaxhighlight> produces the output <syntaxhighlight lang="prolog" inline>X = elizabeth</syntaxhighlight>. But the same procedure can be called with other input-output patterns. For example:
 
<syntaxhighlight lang="prolog">
?- parent_child(elizabeth, Y).
Y = charles.
 
?- parent_child(X, Y).
X = elizabeth,
Y = charles.
 
X = charles,
Y = harry.
 
X = charles,
Y = william.
 
?- parent_child(william, harry).
no.
 
?- parent_child(elizabeth, charles).
yes.
</syntaxhighlight>
 
==See also==
{{Wiktionary|subroutine | function}}
 
* [[Asynchronous procedure call]], a subprogram that is called after its parameters are set by other activities
* [[Command–query separation]] (CQS)
* [[Compound operation (computer programming)|Compound operation]]
* [[Coroutine]]s, subprograms that call each other as if both were the main programs
* [[Evaluation strategy]]
* [[Event handler]], a subprogram that is called in response to an input event or [[interrupt]]
* [[Function (mathematics)]]
* [[Functional programming]]
* [[Fused operation]]
* [[Generator (computer programming)]]
* [[Intrinsic function]]
* [[Lambda function (computer programming)]], a function that is not bound to an identifier
* [[Logic programming]]
* [[Modular programming]]
* [[Operator overloading]]
* [[Protected procedure]]
* [[Transclusion]]
 
==References==
{{Reflist}}
 
{{Authority control}}
 
[[Category:Source code]]
[[Category:Articles with example C code]]
[[Category:Holism]]
[[Category:Programming constructs]]
[[Category:Subroutines| ]]