Function prototype: Difference between revisions

From Rosetta Code
Content added Content deleted
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(32 intermediate revisions by 19 users not shown)
Line 1: Line 1:
{{task}}
{{task}}
{{omit from|6502 Assembly}}
{{omit from|68000 Assembly}}
{{omit from|Z80 Assembly}}
Some languages provide the facility to declare functions and subroutines through the use of [[wp:Function prototype|function prototyping]].
Some languages provide the facility to declare functions and subroutines through the use of [[wp:Function prototype|function prototyping]].


Line 25: Line 28:
* For a main program, specifications are only necessary if a function call appears in the source before the function definition.
* For a main program, specifications are only necessary if a function call appears in the source before the function definition.
* For a package, specifications must appear as part of the specification(.ads) file, and do not appear in the body file(.adb) (The file extensions apply to Gnat Ada and may not apply to all compilers).
* For a package, specifications must appear as part of the specification(.ads) file, and do not appear in the body file(.adb) (The file extensions apply to Gnat Ada and may not apply to all compilers).
<lang Ada>function noargs return Integer;
<syntaxhighlight lang="ada">function noargs return Integer;
function twoargs (a, b : Integer) return Integer;
function twoargs (a, b : Integer) return Integer;
-- varargs do not exist
-- varargs do not exist
function optionalargs (a, b : Integer := 0) return Integer;
function optionalargs (a, b : Integer := 0) return Integer;
-- all parameters are always named, only calling by name differs
-- all parameters are always named, only calling by name differs
procedure dostuff (a : Integer);</lang>
procedure dostuff (a : Integer);</syntaxhighlight>
Other Prototyping: Since pointers are not generic in Ada, a type must be defined before one can have a pointer to that type, thus for making linked-list type semantics another trivial prototyping exists:
Other Prototyping: Since pointers are not generic in Ada, a type must be defined before one can have a pointer to that type, thus for making linked-list type semantics another trivial prototyping exists:
<lang Ada>type Box; -- tell Ada a box exists (undefined yet)
<syntaxhighlight lang="ada">type Box; -- tell Ada a box exists (undefined yet)
type accBox is access Box; -- define a pointer to a box
type accBox is access Box; -- define a pointer to a box
type Box is record -- later define what a box is
type Box is record -- later define what a box is
next : accBox; -- including that a box holds access to other boxes
next : accBox; -- including that a box holds access to other boxes
end record;</lang>
end record;</syntaxhighlight>
Example of a package specification (i.e. prototype):
Example of a package specification (i.e. prototype):
<lang Ada>package Stack is
<syntaxhighlight lang="ada">package Stack is
procedure Push(Object:Integer);
procedure Push(Object:Integer);
function Pull return Integer;
function Pull return Integer;
end Stack;</lang>
end Stack;</syntaxhighlight>


Example of a package body:
Example of a package body:
<lang Ada>package body Stack is
<syntaxhighlight lang="ada">package body Stack is


procedure Push(Object:Integer) is
procedure Push(Object:Integer) is
Line 56: Line 59:
end;
end;


end Stack;</lang>
end Stack;</syntaxhighlight>


To use the package and function:
To use the package and function:
<lang Ada>with Stack;
<syntaxhighlight lang="ada">with Stack;
procedure Main is
procedure Main is
N:integer:=5;
N:integer:=5;
Line 66: Line 69:
...
...
N := Pull;
N := Pull;
end Main;</lang>
end Main;</syntaxhighlight>

=={{header|Aime}}==
<syntaxhighlight lang="aime">integer f0(void); # No arguments
void f1(integer, real); # Two arguments
real f2(...); # Varargs
void f3(integer, ...); # Varargs

void f4(integer &, text &); # Two arguments (integer and string), pass by reference
integer f5(integer, integer (*)(integer));
# Two arguments: integer and function returning integer and taking one integer argument
integer f6(integer a, real b); # Parameters names are allowed
record f7(void); # Function returning an associative array</syntaxhighlight>


=={{header|ALGOL 68}}==
=={{header|ALGOL 68}}==
Line 72: Line 87:
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-2.8 algol68g-2.8].}}
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-2.8 algol68g-2.8].}}
{{works with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d]}}
{{works with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d]}}
'''File: Function_prototype.a68'''<lang algol68>#!/usr/bin/a68g --script #
'''File: Function_prototype.a68'''<syntaxhighlight lang="algol68">#!/usr/bin/a68g --script #
# -*- coding: utf-8 -*- #
# -*- coding: utf-8 -*- #


Line 108: Line 123:
END COMMENT
END COMMENT


SKIP</lang>
SKIP</syntaxhighlight>


=={{header|Aime}}==
=={{header|Amazing Hopper}}==
<lang aime>integer f0(void); # No arguments
void f1(integer, real); # Two arguments
real f2(...); # Varargs
void f3(integer, ...); # Varargs


Function prototypes are included in a #PROTO declaration in the header, at the beginning of a HOPPER source file, before the functional code (MAIN :). This is enforced by the HOPPER compiler, to declare pseudo functions.
void f4(integer &, text &); # Two arguments (integer and string), pass by reference

integer f5(integer, integer (*)(integer));
<syntaxhighlight lang="amazing hopper">
# Two arguments: integer and function returning integer and taking one integer argument
#!/usr/bin/hopper
integer f6(integer a, real b); # Parameters names are allowed

record f7(void); # Function returning an associative array</lang>
// Archivo Hopper
#include <hopper.h>

#context-free noargs /* Declare a pseudo-function with no argument */
#synon noargs no arguments
#context multiargs /* Declare a pseudo-function with multi arguments */
#proto twoargs(_X_,_Y_) /* Declare a pseudo-function with two arguments. #PROTO need arguments */

main:
no arguments
_two args(2,2) // pseudo-function #proto need "_" sufix
println
{1,2,3,"hola mundo!","\n"}, multiargs
exit(0)

.locals

multiargs:
_PARAMS_={},pushall(_PARAMS_)
[1:3]get(_PARAMS_),stats(SUMMATORY),println
{"Mensaje: "}[4:5]get(_PARAMS_),println
clear(_PARAMS_)
back

twoargs(a,b)
{a}mulby(b)
back

// This function is as useful a s an ashtray on a motorcycle:
no args:
{0}minus(0),kill
back

{0}return
</syntaxhighlight>


=={{header|C}}==
=={{header|C}}==
Line 126: Line 172:
Function prototypes are typically included in a header file at the beginning of a source file prior to functional code. However, this is not enforced by a compiler.
Function prototypes are typically included in a header file at the beginning of a source file prior to functional code. However, this is not enforced by a compiler.


<lang c>int noargs(void); /* Declare a function with no argument that returns an integer */
<syntaxhighlight lang="c">int noargs(void); /* Declare a function with no argument that returns an integer */
int twoargs(int a,int b); /* Declare a function with two arguments that returns an integer */
int twoargs(int a,int b); /* Declare a function with two arguments that returns an integer */
int twoargs(int ,int); /* Parameter names are optional in a prototype definition */
int twoargs(int ,int); /* Parameter names are optional in a prototype definition */
int anyargs(); /* An empty parameter list can be used to declare a function that accepts varargs */
int anyargs(); /* An empty parameter list can be used to declare a function that accepts varargs */
int atleastoneargs(int, ...); /* One mandatory integer argument followed by varargs */</lang>
int atleastoneargs(int, ...); /* One mandatory integer argument followed by varargs */</syntaxhighlight>


=={{header|C sharp}}==
=={{header|C sharp|C#}}==
'''Abstract methods'''<br/>
'''Abstract methods'''<br/>
Interfaces and abstract classes can define abstract methods that must be implemented by subclasses.
Interfaces and abstract classes can define abstract methods that must be implemented by subclasses.
<lang csharp>using System;
<syntaxhighlight lang="csharp">using System;
abstract class Printer
abstract class Printer
{
{
Line 146: Line 192:
Console.WriteLine("Hello world!");
Console.WriteLine("Hello world!");
}
}
}</lang>
}</syntaxhighlight>
'''Delegates'''<br/>
'''Delegates'''<br/>
A delegate is similar to a function pointer. They are multicast: multiple methods can be attached to them.
A delegate is similar to a function pointer. They are multicast: multiple methods can be attached to them.
<lang csharp>using System;
<syntaxhighlight lang="csharp">using System;
public delegate int IntFunction(int a, int b);
public delegate int IntFunction(int a, int b);


Line 170: Line 216:
Console.WriteLine(func(2, 3)); //prints 5. Both functions are called, but only the last result is kept.
Console.WriteLine(func(2, 3)); //prints 5. Both functions are called, but only the last result is kept.
}
}
}</lang>
}</syntaxhighlight>
'''Partial methods'''<br/>
'''Partial methods'''<br/>
A partial type is a type that is defined in multiple files.<br/>
A partial type is a type that is defined in multiple files.<br/>
Line 178: Line 224:
- The method must return void.<br/>
- The method must return void.<br/>
- No access modifiers are allowed. Partial methods are implicitly private.
- No access modifiers are allowed. Partial methods are implicitly private.
<lang csharp>//file1.cs
<syntaxhighlight lang="csharp">//file1.cs
public partial class Program
public partial class Program
{
{
Line 197: Line 243:
p.Print(); //If the implementation above is not written, the compiler will remove this line.
p.Print(); //If the implementation above is not written, the compiler will remove this line.
}
}
}</lang>
}</syntaxhighlight>


=={{header|C++}}==
=={{header|C++}}==
Function declaration in C++ differs from that in C in some aspect.
Function declaration in C++ differs from that in C in some aspect.


<lang cpp>int noargs(); // Declare a function with no arguments that returns an integer
<syntaxhighlight lang="cpp">int noargs(); // Declare a function with no arguments that returns an integer
int twoargs(int a,int b); // Declare a function with two arguments that returns an integer
int twoargs(int a,int b); // Declare a function with two arguments that returns an integer
int twoargs(int ,int); // Parameter names are optional in a prototype definition
int twoargs(int ,int); // Parameter names are optional in a prototype definition
Line 209: Line 255:
template<typename T> T declval(T); //A function template
template<typename T> T declval(T); //A function template
template<typename ...T> tuple<T...> make_tuple(T...); //Function template using parameter pack (since c++11)
template<typename ...T> tuple<T...> make_tuple(T...); //Function template using parameter pack (since c++11)
</syntaxhighlight>
</lang>


=={{header|Clojure}}==
=={{header|Clojure}}==
If you want to make forward declarations, you can use declare.
If you want to make forward declarations, you can use declare.
<lang clojure>(declare foo)</lang>
<syntaxhighlight lang="clojure">(declare foo)</syntaxhighlight>


=={{header|COBOL}}==
=={{header|COBOL}}==
Line 219: Line 265:
Prototypes were introduced in COBOL 2002. In the following examples, <code>PROGRAM-ID</code> and <code>PROGRAM</code> can be replaced with the equivalents for functions and methods. However, in method prototypes the <code>PROTOTYPE</code> clause is not used.
Prototypes were introduced in COBOL 2002. In the following examples, <code>PROGRAM-ID</code> and <code>PROGRAM</code> can be replaced with the equivalents for functions and methods. However, in method prototypes the <code>PROTOTYPE</code> clause is not used.


<lang cobol> *> A subprogram taking no arguments and returning nothing.
<syntaxhighlight lang="cobol"> *> A subprogram taking no arguments and returning nothing.
PROGRAM-ID. no-args PROTOTYPE.
PROGRAM-ID. no-args PROTOTYPE.
END PROGRAM no-args.
END PROGRAM no-args.
Line 257: Line 303:
01 ret PIC S9(9) USAGE COMP-5.
01 ret PIC S9(9) USAGE COMP-5.
PROCEDURE DIVISION USING arg RETURNING ret.
PROCEDURE DIVISION USING arg RETURNING ret.
END PROGRAM foreign-func.</lang>
END PROGRAM foreign-func.</syntaxhighlight>


=={{header|Common Lisp}}==
=={{header|Common Lisp}}==
In Common Lisp, function prototypes can be used with <code>(declaim (inline func-name))</code> function arguments are taken when the function is defined. In addition, the argument types aren't needed.
In Common Lisp, function prototypes can be used with <code>(declaim (inline func-name))</code> function arguments are taken when the function is defined. In addition, the argument types aren't needed.


Caveat -- This works with specific implementations of CL. This was tested in SBCL.
<lang lisp>

<syntaxhighlight lang="lisp">
(declaim (inline no-args))
(declaim (inline no-args))
(declaim (inline one-arg))
(declaim (inline one-arg))
Line 293: Line 341:


(optional-args 1.0 "example") ;=> "1.0 example"
(optional-args 1.0 "example") ;=> "1.0 example"
</syntaxhighlight>


[http://clhs.lisp.se/Body/m_declai.htm More about <code>declaim</code> here]
</lang>


=={{header|D}}==
=={{header|D}}==
Beside function prototypes similar to the ones available in C (plus templates, D-style varargs), you can define class method prototypes in abstract classes and interfaces. The exact rules for this are best explained by the [//http://dlang.org/interface.html documentation]
Beside function prototypes similar to the ones available in C (plus templates, D-style varargs), you can define class method prototypes in abstract classes and interfaces. The exact rules for this are best explained by the [//http://dlang.org/interface.html documentation]
<syntaxhighlight lang="d">
<lang d>/// Declare a function with no arguments that returns an integer.
/// Declare a function with no arguments that returns an integer.
int noArgs();
int noArgs();


/// Declare a function with no arguments that returns an integer.
/// Declare a function with two arguments that returns an integer.
int twoArgs(int a, int b);
int twoArgs(int a, int b);


Line 344: Line 394:
}
}


void main() {}</lang>
void main() {}</syntaxhighlight>

=={{header|Delphi}}==
{{libheader| System.SysUtils}}
In Delphi, prototype function is named Class/Record Helper. For now, is not possible has more then one helper active in a same object, if two or more was declareted, just the present in the last Unit declareted will be active, the others will be ignored. In case two or more helpers was declareted in same Unit, just the last helper declareted will be active. Can not inherit record helpers, but class helper can be.<br>
Patten: " identifierName = record helper for TypeIdentifierName"<br>
See [http://docwiki.embarcadero.com/RADStudio/Sydney/en/Class_and_Record_Helpers_(Delphi) Documentation] for more details.<br>

<syntaxhighlight lang="delphi">
program Function_prototype;

{$APPTYPE CONSOLE}

uses
System.SysUtils;

type
TIntArray = TArray<Integer>;

TIntArrayHelper = record helper for TIntArray
const
DEFAULT_VALUE = -1;
// A prototype declaration for a function that does not require arguments
function ToString(): string;

// A prototype declaration for a function that requires two arguments
procedure Insert(Index: Integer; value: Integer);

// A prototype declaration for a function that utilizes varargs
// varargs is not available, but a equivalent is array of const
procedure From(Args: array of const);

//A prototype declaration for a function that utilizes optional arguments
procedure Delete(Index: Integer; Count: Integer = 1);

//A prototype declaration for a function that utilizes named parameters
// Named parameters is not supported in Delphi

//Example of prototype declarations for subroutines or procedures
//(if these differ from functions)
procedure Sqr; //Procedure return nothing
function Averange: double; //Function return a value
end;

{ TIntHelper }

function TIntArrayHelper.Averange: double;
begin
Result := 0;
for var e in self do
Result := Result + e;
Result := Result / Length(self);
end;

procedure TIntArrayHelper.Delete(Index, Count: Integer);
begin
System.Delete(self, Index, Count);
end;

procedure TIntArrayHelper.From(Args: array of const);
var
I, Count: Integer;
begin
Count := Length(Args);
SetLength(self, Count);

if Count = 0 then
exit;
for I := 0 to High(Args) do
with Args[I] do
case VType of
vtInteger:
self[I] := VInteger;
vtBoolean:
self[I] := ord(VBoolean);
vtChar, vtWideChar:
self[I] := StrToIntDef(string(VChar), DEFAULT_VALUE);
vtExtended:
self[I] := Round(VExtended^);
vtString:
self[I] := StrToIntDef(VString^, DEFAULT_VALUE);
vtPChar:
self[I] := StrToIntDef(VPChar, DEFAULT_VALUE);
vtObject:
self[I] := cardinal(VObject);
vtClass:
self[I] := cardinal(VClass);
vtAnsiString:
self[I] := StrToIntDef(string(VAnsiString), DEFAULT_VALUE);
vtCurrency:
self[I] := Round(VCurrency^);
vtVariant:
self[I] := Integer(VVariant^);
vtInt64:
self[I] := Integer(VInt64^);
vtUnicodeString:
self[I] := StrToIntDef(string(VUnicodeString), DEFAULT_VALUE);
end;
end;

procedure TIntArrayHelper.Insert(Index, value: Integer);
begin
system.Insert([value], self, Index);
end;

procedure TIntArrayHelper.Sqr;
begin
for var I := 0 to High(self) do
Self[I] := Self[I] * Self[I];
end;

function TIntArrayHelper.ToString: string;
begin
Result := '[';
for var e in self do
Result := Result + e.ToString + ', ';
Result := Result + ']';
end;

begin
var val: TArray<Integer>;
val.From([1, '2', PI]);
val.Insert(0, -1); // insert -1 at position 0
writeln(' Array: ', val.ToString, ' ');
writeln(' Averange: ', val.Averange: 3: 2);
val.Sqr;
writeln(' Sqr: ', val.ToString);
Readln;

end.</syntaxhighlight>
{{out}}
<pre> Array: [-1, 1, 2, 3, ]
Averange: 1.25
Sqr: [1, 1, 4, 9, ]</pre>

Class helper example, with inherited helpers:<br>
Patten: " identifierName = class helper (ancestor list*) for TypeIdentifierName"<br>
Ancertor list is optional, and only will be used if this helper will inhret a parent helper.

{{libheader| System.SysUtils}}
{{libheader| System.Classes}}
<syntaxhighlight lang="delphi">
program Function_prototype_class;

{$APPTYPE CONSOLE}

uses
System.SysUtils,
System.Classes;

type
TStringListHelper1 = class helper for TStringList
constructor Create(FileName: TFileName); overload;
end;

TStringListHelper2 = class helper (TStringListHelper1) for TStringList
procedure SaveAndFree(FileName: TFileName);
end;

TStringListHelper3 = class helper (TStringListHelper2) for TStringList
procedure AddDateTime;
end;

{ TStringListHelper1 }

constructor TStringListHelper1.Create(FileName: TFileName);
begin
inherited Create;
if FileExists(FileName) then
LoadFromFile(FileName);
end;

{ TStringListHelper2 }

procedure TStringListHelper2.SaveAndFree(FileName: TFileName);
begin
SaveToFile(FileName);
Free;
end;

{ TStringListHelper3 }

procedure TStringListHelper3.AddDateTime;
begin
self.Add(DateToStr(now));
end;

begin
with TStringList.Create('d:\Text.txt') do
begin
AddDateTime;
SaveAndFree('d:\Text_done.txt');
end;
readln;
end.</syntaxhighlight>

=={{header|Diego}}==
<syntaxhighlight lang="diego">// A prototype declaration for a function that does not require arguments

begin_funct(foo); // function as a 'method' with no arguments, no return type
end_funct(foo);

// or

with_funct(foo); // function as a 'method' with no arguments, no return type

// A prototype declaration for a function that requires two arguments

begin_funct(goo)_arg({string}, str1, str2); // two arguments, no return type
end_funct[]; // derived name of function using [], like 'this'

with_funct(goo)_arg({str}, str1, str2); // two arguments, no return type
with_funct(hoo)_param({integer}, i, j); // 'param' posit can be used instead of 'arg'

// A prototype declaration for a function that utilizes varargs

begin_funct(voo)_arg({int}, [vararg], v); // variable number of arguments, no return type, 'int' can be used instead of 'integer'
end_funct[];

begin_funct({int}, voo)_arg({int}, ..., v); // variable number of arguments, with return type
add_var({int}, sum)_v(0);
forall_var(v)_calc([sum]+=[v]);
[voo]_ret([sum]);
end_funct[];

// A prototype declaration for a function that utilizes optional arguments
begin_funct({int}, ooo)_arg(o)_value(1); // optional argument with default value and return type integer
with_funct(ooo)_return([o]); // Can be shortened to [ooo]_ret([0]);
end_funct[];

begin_funct({int}, oxo)_arg(o,u,v)_opt(u)_value(1); // optional argument of second argument with default value and return type integer
[ooo]_ret(1); // the execution has to name arguments or missing in comma-separated list of arguments
end_funct[];

// A prototype declaration for a function that utilizes named parameters

begin_funct({int}, poo)_param({int}, a, b, c); // to enforce named parameters '_param' posit can be used.
[poo]_ret([a]+[b]+[c]);
end_funct[];

exec_funct(poo)_param(a)_value(1)_param(b, c)_value(2, 3) ? me_msg()_funct(poo); ;

begin_funct({int}, poo)_arg({int}, a, b, c); // named parameters can still be used with '_arg' posit.
[poo]_ret([a]+[b]+[c]);
end_funct[];

me_msg()_funct(poo)_arg(a)_value(1)_value(2, 3); // Callee has to figure out unnamed arguments by extraction
// 'exec_' verb is implied before '_funct' action

// Example of prototype declarations for subroutines or procedures (if these differ from functions)

begin_instruct(foo); // instructions are 'methods', no arguments, no return type
end_instruct[foo]; // explicit end of itself

// or

with_instruct(foo); // instructions are 'methods', no arguments, no return type

begin_funct(yoo)_arg(robotMoniker)_param(b); // A '_funct' can be used as a subroutine when missing the '{}' return datatype
// a mix of '_arg' and '_param' posits can be used
with_robot[robotMoniker]_var(sq)_calc([b]^2); // create a variable called 'sq' on robot 'robotMoniker'
end_funct(yoo);

begin_instruct(woo)_arg(robotType)_param(b); // An '_instuct' is only used for subroutines and return datatypes are not accepted
with_robot()_type[robotType]_var(sq)_calc([b]^2); // create a variable called 'sq' on all robots of type 'robotType'
end_funct(woo);

// An explanation and example of any special forms of prototyping not covered by the above

begin_funct({double}, voo)_arg({int}, [numArgs], v); // variable-defined number of arguments, with return type
add_var({int}, sum)_v(0);
add_var({double}, average)_v(0);
for_var(v)_until[numArgs]_calc([sum]+=[v]); // the number of arguments [numArgs] does not have to be number of arguments of v
[voo]_ret([sum]/[numArgs]);
end_funct[];

begin_funct({int}, [numArgsOut], voo)_arg({int}, [numArgsIn], v); // variable-defined number of arguments, with variable-defined number of return types
add_var({int}, sum)_v(0);
add_var({double}, average)_v(0);
for_var(v)_until[numArgsOut]_calc([sum]+=[v]);
[voo]_ret([sum]/[numArgsOut]);
end_funct[];</syntaxhighlight>

=={{header|F Sharp|F#}}==
In F#, prototypes are called signatures. Signature files are used to bulk annotate the accessibility of the things within them. If something is in an implementation file but not in the signature file, it is assumed to be private to that file. If it is in the signature file without the <code>internal</code> accessibility modifier, then it is assumed to public, otherwise it is internal to the assembly. For more details, see the [http://msdn.microsoft.com/en-us/library/dd233196.aspx documentation]. Below is an example of the signatures produced for the functions specified in the task (without any accessibility modifiers):
<syntaxhighlight lang="fsharp">// A function taking and returning nothing (unit).
val noArgs : unit -> unit
// A function taking two integers, and returning an integer.
val twoArgs : int -> int -> int
// A function taking a ParamPack array of ints, and returning an int. The ParamPack
// attribute is not included in the signature.
val varArgs : int [] -> int
// A function taking an int and a ParamPack array of ints, and returning an
// object of the same type.
val atLeastOnArg : int -> int [] -> int
// A function taking an int Option, and returning an int.
val optionalArg : Option<int> -> int

// Named arguments and the other form of optional arguments are only available on
// methods.
type methodClass =
class
// A method taking an int named x, and returning an int.
member NamedArg : x:int -> int
// A method taking two optional ints in a tuple, and returning an int. The
//optional arguments must be tupled.
member OptionalArgs : ?x:int * ?y:int -> int
end</syntaxhighlight>


=={{header|FreeBASIC}}==
=={{header|FreeBASIC}}==
<lang freebasic>' FB 1.05.0 Win64
<syntaxhighlight lang="freebasic">' FB 1.05.0 Win64


' The position regarding prototypes is broadly similar to that of the C language in that functions,
' The position regarding prototypes is broadly similar to that of the C language in that functions,
Line 383: Line 741:
Private:
Private:
i As Integer
i As Integer
End Type</lang>
End Type</syntaxhighlight>

=={{header|F Sharp|F#}}==
In F#, prototypes are called signatures. Signature files are used to bulk annotate the accessibility of the things within them. If something is in an implementation file but not in the signature file, it is assumed to be private to that file. If it is in the signature file without the <code>internal</code> accessibility modifier, then it is assumed to public, otherwise it is internal to the assembly. For more details, see the [http://msdn.microsoft.com/en-us/library/dd233196.aspx documentation]. Below is an example of the signatures produced for the functions specified in the task (without any accessibility modifiers):
<lang fsharp>// A function taking and returning nothing (unit).
val noArgs : unit -> unit
// A function taking two integers, and returning an integer.
val twoArgs : int -> int -> int
// A function taking a ParamPack array of ints, and returning an int. The ParamPack
// attribute is not included in the signature.
val varArgs : int [] -> int
// A function taking an int and a ParamPack array of ints, and returning an
// object of the same type.
val atLeastOnArg : int -> int [] -> int
// A function taking an int Option, and returning an int.
val optionalArg : Option<int> -> int

// Named arguments and the other form of optional arguments are only available on
// methods.
type methodClass =
class
// A method taking an int named x, and returning an int.
member NamedArg : x:int -> int
// A method taking two optional ints in a tuple, and returning an int. The
//optional arguments must be tupled.
member OptionalArgs : ?x:int * ?y:int -> int
end</lang>


=={{header|Go}}==
=={{header|Go}}==
Line 415: Line 747:


Function declarations whether with a body or without must be "top level" declarations, that is, after the package clause and outside of any other function. Examples of function delarations without bodies are,
Function declarations whether with a body or without must be "top level" declarations, that is, after the package clause and outside of any other function. Examples of function delarations without bodies are,
<lang go>func a() // function with no arguments
<syntaxhighlight lang="go">func a() // function with no arguments
func b(x, y int) // function with two arguments
func b(x, y int) // function with two arguments
func c(...int) // varargs are called "variadic parameters" in Go.</lang>
func c(...int) // varargs are called "variadic parameters" in Go.</syntaxhighlight>
Go does not directly support optional or named parameters and does not have any concept of procedures or subroutines as distinct from functions.
Go does not directly support optional or named parameters and does not have any concept of procedures or subroutines as distinct from functions.


Otherwise, Go does have the concept of a function signature which includes parameters and return values. Go is strongly typed and functions are first class objects so function signatures are used in a variety of ways. These might be considered distinct from the concept of function prototype.
Otherwise, Go does have the concept of a function signature which includes parameters and return values. Go is strongly typed and functions are first class objects so function signatures are used in a variety of ways. These might be considered distinct from the concept of function prototype.


=={{header| haskell }}==
=={{header|Haskell}}==
A function can be declared without giving it's prototype in Haskell. The haskell compiler has got type inference
A function can be declared without giving it's prototype in Haskell. The haskell compiler has got type inference
whereby it can infer the return type and type of variable given to function. You can still hardcode the prototype
whereby it can infer the return type and type of variable given to function. You can still hardcode the prototype
which specifies the datatype of variables and return type. For ex. Consider a function add which takes two
which specifies the datatype of variables and return type. For ex. Consider a function add which takes two
integers and returns their sum. It can be prototyped and declared as :
integers and returns their sum. It can be prototyped and declared as :
<lang haskell>
<syntaxhighlight lang="haskell">
add :: Int -> Int -> Int
add :: Int -> Int -> Int
add x y = x+y
add x y = x+y
</syntaxhighlight>
</lang>


Actually all functions in haskell are functions with just one arguments. Haskell will treat above function as a
Actually all functions in haskell are functions with just one arguments. Haskell will treat above function as a
Line 436: Line 768:
is such that it takes an int and returns an int.
is such that it takes an int and returns an int.
Similarly for any function add which takes 3 integers and adds them the actual prototype will be as follows:
Similarly for any function add which takes 3 integers and adds them the actual prototype will be as follows:
<lang haskell>
<syntaxhighlight lang="haskell">
add :: Int->(Int ->(Int->Int))
add :: Int->(Int ->(Int->Int))
</syntaxhighlight>
</lang>
The one that does not require arguements could just be:
The one that does not require arguements could just be:
<lang haskell>
<syntaxhighlight lang="haskell">
printThis = putStrLn("This is being printed.")
printThis = putStrLn("This is being printed.")
</syntaxhighlight>
</lang>
But haskell would rather consider the function to be of return type IO() in this case.
But haskell would rather consider the function to be of return type IO() in this case.


Two arguments:
Two arguments:
<lang haskell>
<syntaxhighlight lang="haskell">
add :: Int -> Int -> Int
add :: Int -> Int -> Int
add x y = x+y
add x y = x+y
</syntaxhighlight>
</lang>


The same thing can be done using the lambda function as :
The same thing can be done using the lambda function as :
<lang haskell>
<syntaxhighlight lang="haskell">
add :: Int -> Int -> Int
add :: Int -> Int -> Int
add = \x->\y -> x+y
add = \x->\y -> x+y
</syntaxhighlight>
</lang>


Two arguments with unnamed parameters:
Two arguments with unnamed parameters:
<lang haskell>
<syntaxhighlight lang="haskell">
doThis :: Int-> Int-> String
doThis :: Int-> Int-> String
doThis _ _ = "Function with unnamed parameters"
doThis _ _ = "Function with unnamed parameters"
</syntaxhighlight>
</lang>


Function with var args requires creation of type class as per the requirement.
Function with var args requires creation of type class as per the requirement.
Line 467: Line 799:
=={{header|J}}==
=={{header|J}}==
J assumes an unknown name is a verb of infinite rank. Rank determines the frames on which the verb executes. As the demonstration shows, changing the rank, assigning the rank before the verb is used in other definitions affects the result. We could, of course, play other games by changing the unknown name from verb to another part of speech.
J assumes an unknown name is a verb of infinite rank. Rank determines the frames on which the verb executes. As the demonstration shows, changing the rank, assigning the rank before the verb is used in other definitions affects the result. We could, of course, play other games by changing the unknown name from verb to another part of speech.
<lang J> NB. j assumes an unknown name f is a verb of infinite rank
<syntaxhighlight lang="j"> NB. j assumes an unknown name f is a verb of infinite rank
NB. f has infinite ranks
NB. f has infinite ranks
f b. 0
f b. 0
Line 526: Line 858:
0 2 4 6 8
0 2 4 6 8
0 3 6 9 12
0 3 6 9 12
0 4 8 12 16</lang>
0 4 8 12 16</syntaxhighlight>
=={{header|Java}}==
The order of declarations in Java is unimportant, so forward declaration of functions is neither needed nor supported.
The only place where function prototypes are needed is in abstract classes or interfaces, where implementation will be provided by the derived or implementing class.
<syntaxhighlight lang="java">
public final class FunctionPrototype {
public static void main(String[] aArgs) {
Rectangle rectangle = new Rectangle(10.0, 20.0);
System.out.println("Area = " + rectangle.area());
Calculator calculator = new Calculator();
System.out.println("Sum = " + calculator.sum(2, 2));
calculator.version();
}

private static class Rectangle implements Shape {
public Rectangle(double aWidth, double aLength) {
width = aWidth; length = aLength;
}
@Override
public double area() {
return length * width;
}
private final double width, length;
}
private static class Calculator extends Arithmetic {
public Calculator() {
// Statements to create the graphical
// representation of the calculator
}
@Override
public int sum(int aOne, int aTwo) {
return aOne + aTwo;
}
@Override
public void version() {
System.out.println("0.0.1");
}
}

}

interface Shape {
public double area();
}

abstract class Arithmetic {
public abstract int sum(int aOne, int aTwo);
public abstract void version();
}
</syntaxhighlight>
{{ out }}
<pre>
Area = 200.0
Sum = 4
0.0.1
</pre>


=={{header|JavaScript}}==
=={{header|JavaScript}}==
=== ES5 ===
=== ES5 ===
JavaScript functions may also be used to define prototype objects
JavaScript functions may also be used to define prototype objects
<syntaxhighlight lang="javascript">
<lang JavaScript>
// A prototype declaration for a function that does not require arguments
// A prototype declaration for a function that does not require arguments
function List() {}
function List() {}
Line 569: Line 967:
l.length; // 2
l.length; // 2


</syntaxhighlight>
</lang>


=== ES6 ===
=== ES6 ===
Class Declarations are used to define prototype objects
Class Declarations are used to define prototype objects
<syntaxhighlight lang="javascript">
<lang JavaScript>
// A prototype declaration for a function that does not require arguments
// A prototype declaration for a function that does not require arguments
class List {
class List {
Line 611: Line 1,009:
l.pop(); // 15
l.pop(); // 15
l.length; // 2
l.length; // 2
</syntaxhighlight>
</lang>

=={{header|jq}}==
jq does not have "function prototypes" in the strict sense, so this entry focuses on jq function signatures
as specified in function definitions.

jq does not limit the number of formal parameters of a function and supports multi-arity functions, but each allowed
"restriction" to a particular arity must be specified explicitly.

Although jq does not support varargs functions, their effect can be
achieved by using an array-valued argument in conjunction with
"destructuring", as illustrated below.

Note also that:
* any restrictions on the allowed values of the parameters must be specified programmatically and are only checked at run-time;
* function definitions may be included within function definitions;
* recursive and mutually recursive functions are allowed, but calls to a function can only occur within the scope of its definition.
* a function of a particular arity can be defined more than once, with lexical scoping rules determining how each invocation will be handled.

In the following examples, only `def` and `as` are jq keywords, and .... is used to indicate ellipsis.

<syntaxhighlight lang=jq>
def Func: # no arguments

def Func(a;b): # two arguments

def Vararg(v):
v as [$a1, $a2] .... # if v is an array, then $a1 will be the first item specified by v, or else null, and so on

def Vararg(a; v):
v as [$a1, $a2] .... # if v is an array, then $a1 will be the first item specified by v, or else null, and so on
</syntaxhighlight>

=={{header|Julia}}==
Julia does not need or use function prototypes in general. Generic functions are further specialized as to argument type and return type during just-in-time compilation if required. However, when interacting with other languages such a C which use function prototypes, Julia can prototype its functions for passing its functions to external languages with the @cfunction macro:

<syntaxhighlight lang="julia">julia > function mycompare(a, b)::Cint
(a < b) ? -1 : ((a > b) ? +1 : 0)
end
mycompare (generic function with 1 method)
</syntaxhighlight>

Using @cfunction to create a prototype for passing this to C's quicksort:

<syntaxhighlight lang="julia">julia> mycompare_c = @cfunction(mycompare, Cint, (Ref{Cdouble}, Ref{Cdouble}))
</syntaxhighlight>


=={{header|Kotlin}}==
=={{header|Kotlin}}==
Line 619: Line 1,062:


Here's an example of this. Note that since Kotlin allows arguments to be passed either by name or position for all functions, there is no separate prototype for this situation. Moreover, since arguments may be passed by name, it is strongly recommended (but not obligatory) that the parameter names for overriding members should be the same as for the functions they override. The compiler will issue a warning if this recommendation is not followed.
Here's an example of this. Note that since Kotlin allows arguments to be passed either by name or position for all functions, there is no separate prototype for this situation. Moreover, since arguments may be passed by name, it is strongly recommended (but not obligatory) that the parameter names for overriding members should be the same as for the functions they override. The compiler will issue a warning if this recommendation is not followed.
<lang scala>// version 1.0.6
<syntaxhighlight lang="scala">// version 1.0.6


interface MyInterface {
interface MyInterface {
Line 653: Line 1,096:
println(d.roo())
println(d.roo())
println(d.poo)
println(d.poo)
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 664: Line 1,107:


=={{header|Lua}}==
=={{header|Lua}}==
<lang Lua>function Func() -- Does not require arguments
<syntaxhighlight lang="lua">function Func() -- Does not require arguments
return 1
return 1
end
end
Line 678: Line 1,121:
function Func(a,...) -- One argument followed by varargs
function Func(a,...) -- One argument followed by varargs
return a,{...} -- Returns both arguments, varargs as table
return a,{...} -- Returns both arguments, varargs as table
end</lang>
end</syntaxhighlight>


=={{header|Luck}}==
=={{header|Luck}}==
<lang Luck>function noargs(): int = ? ;;
<syntaxhighlight lang="luck">function noargs(): int = ? ;;
function twoargs(x:int, y:int): int = ? ;;
function twoargs(x:int, y:int): int = ? ;;


Line 688: Line 1,131:


function anyargs(xs: ...): int = ? ;;
function anyargs(xs: ...): int = ? ;;
function plusargs(x:int, xs: ...): int = ? ;;</lang>
function plusargs(x:int, xs: ...): int = ? ;;</syntaxhighlight>



=={{header|M2000 Interpreter}}==
=={{header|M2000 Interpreter}}==
Line 697: Line 1,139:
Example of change an inner module using another module with same signature. Module MyBeta {Read x : ... } or Module MyBeta (x) { ... } or Module MyBeta(x) { } is the same.
Example of change an inner module using another module with same signature. Module MyBeta {Read x : ... } or Module MyBeta (x) { ... } or Module MyBeta(x) { } is the same.


<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module Check {
Module Check {
Module MyBeta (a) {
Module MyBeta (a) {
Line 711: Line 1,153:
}
}
Check
Check
</syntaxhighlight>
</lang>


Signatures needed for Event object. An event object get a list of functions, called as modules, and call every function with same signature. We can provide arguments by reference too. We can define simple functions (without visibility except local and global), or group functions (static groups) with visibility local, global and group level, or we can define local scope functions.
Signatures needed for Event object. An event object get a list of functions, called as modules, and call every function with same signature. We can provide arguments by reference too. We can define simple functions (without visibility except local and global), or group functions (static groups) with visibility local, global and group level, or we can define local scope functions.
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module Check {,
Module Check {,
\\ make an event object
\\ make an event object
Line 760: Line 1,202:
}
}
Check
Check
</syntaxhighlight>
</lang>


Using a function for local call (module visibility)
Using a function for local call (module visibility)


<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module Check {,
Module Check {,
\\ make an event object
\\ make an event object
Line 816: Line 1,258:
}
}
Check
Check
</syntaxhighlight>
</lang>


Using a Function in a Group (Groups are the User objects in M2000)
Using a Function in a Group (Groups are the User objects in M2000)


<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module Check {,
Module Check {,
\\ make an event object
\\ make an event object
Line 871: Line 1,313:
}
}
Check
Check
</syntaxhighlight>
</lang>



=={{header|Nim}}==
=={{header|Nim}}==
Procedure declarations can be used if a proc is to be used before its definition.
Procedure declarations can be used if a proc is to be used before its definition.
<lang nim># Procedure declarations. All are named
<syntaxhighlight lang="nim"># Procedure declarations. All are named
proc noargs(): int
proc noargs(): int
proc twoargs(a, b: int): int
proc twoargs(a, b: int): int
Line 892: Line 1,333:
proc twoargs(a, b: int): int = echo "twoargs"
proc twoargs(a, b: int): int = echo "twoargs"
proc anyargs(x: varargs[int]): int = echo "anyargs"
proc anyargs(x: varargs[int]): int = echo "anyargs"
proc optargs(a: int, b = 10): int = echo "optargs"</lang>
proc optargs(a: int, b = 10): int = echo "optargs"</syntaxhighlight>

=={{header|OCaml}}==

<syntaxhighlight lang="ocaml">(* Usually prototype declarations are put in an interface file,
a file with .mli filename extension *)

(* A prototype declaration for a function that does not require arguments *)
val no_arg : unit -> unit

(* A prototype declaration for a function that requires two arguments *)
val two_args : int -> int -> unit

(* A prototype declaration for a function that utilizes optional arguments *)
val opt_arg : ?param:int -> unit -> unit
(* in this case we add a unit parameter in order to omit the argument,
because ocaml supports partial application *)

(* A prototype declaration for a function that utilizes named parameters *)
val named_arg : param1:int -> param2:int -> unit

(* An explanation and example of any special forms of prototyping not covered by the above *)

(* A prototype declaration for a function that requires a function argument *)
val fun_arg : (int -> int) -> unit

(* A prototype declaration for a function with polymorphic argument *)
val poly_arg : 'a -> unit</syntaxhighlight>


=={{header|Oforth}}==
=={{header|Oforth}}==


Oforth can only forward declare methods (see Mutual Recursion task). A method can be declared without any class implementation :
Oforth can only forward declare methods (see Mutual Recursion task). A method can be declared without any class implementation :
<lang Oforth>Method new: myMethod</lang>
<syntaxhighlight lang="oforth">Method new: myMethod</syntaxhighlight>


This creates a new method object with name myMethod (or does nothing if this object already exists). It says nothing about method implementations (number of parameters, return value, ...).
This creates a new method object with name myMethod (or does nothing if this object already exists). It says nothing about method implementations (number of parameters, return value, ...).
Line 913: Line 1,381:


Ol functions is a first-class functions with dynamic arguments translation so no function prototypes is required.
Ol functions is a first-class functions with dynamic arguments translation so no function prototypes is required.

=={{header|OxygenBasic}}==
<syntaxhighlight lang="text">
'DECLARE FUNCTION' ABBREVIATED TO '!'

! f() ' a procedure with no params
! f(int a) ' with 1 int param
! f(int *a) ' with 1 int pointer param
! f(int a, int b, inc c) ' with 3 int params
! f(int a,b,c) ' compaction with 3 int params
! f(string s, int a,b) ' with 1 string and 2 int params
! f() as string ' function returning a string
! f(string s) as string ' with 1 string param
! *f(string s) as string ' as a function pointer: @f=address
! f(string s, optional i) ' with opptional param
! f(string s = "Hello") ' optional param with default value
! f(int n, ...) ' 1 specific param and varargs
! f(...) ' any params or none

'TRADITIONAL BASIC DECLARATIONS
declare sub f( s as string, i as long, j as long) ' byref by default
declare function f( byref s as string, byval i as long, byval j as long) as string

'C-STYLE DECLARATIONS
void f(string *s, long i, long j)
string f(string *s, long i, long j)



'BLOCK DIRECTIVES FOR FUNCTION PROTOTYPES:

extern ' shareable stdcall functions

extern lib "xyz.dll" ' for accessing functions in xyz Dynamic Link Library

extern export ' functions to be exported if this is a DLL

extern virtual ' for accssing interfaces and other virtual classes

end extern ' revert to internal function mode

</syntaxhighlight>


=={{header|PARI/GP}}==
=={{header|PARI/GP}}==
Line 919: Line 1,429:
PARI uses C prototypes. Additionally, gp2c parser codes are essentially function prototypes. They must be placed in the file called by gp2c, not in a file included by it, and they must appear as a <code>GP;</code> comment. For a function
PARI uses C prototypes. Additionally, gp2c parser codes are essentially function prototypes. They must be placed in the file called by gp2c, not in a file included by it, and they must appear as a <code>GP;</code> comment. For a function


<lang c>long
<syntaxhighlight lang="c">long
foo(GEN a, GEN b)</lang>
foo(GEN a, GEN b)</syntaxhighlight>
which takes two (required) <code>t_INT</code> arguments, returns a small integer (a [[C]] long) and appears as <code>bar</code> to the gp interpreter, the following command would be used:
which takes two (required) <code>t_INT</code> arguments, returns a small integer (a [[C]] long) and appears as <code>bar</code> to the gp interpreter, the following command would be used:
<lang c>/*
<syntaxhighlight lang="c">/*
GP;install("foo","LGG","bar","./filename.gp.so");
GP;install("foo","LGG","bar","./filename.gp.so");
*/</lang>
*/</syntaxhighlight>


If its arguments were optional it could be coded as
If its arguments were optional it could be coded as
<lang c>/*
<syntaxhighlight lang="c">/*
GP;install("foo","LDGDG","bar","./filename.gp.so");
GP;install("foo","LDGDG","bar","./filename.gp.so");
*/</lang>
*/</syntaxhighlight>
although other parser codes are possible; this one sends <code>NULL</code> if the arguments are omitted.
although other parser codes are possible; this one sends <code>NULL</code> if the arguments are omitted.


A code like
A code like
<lang c>/*
<syntaxhighlight lang="c">/*
GP;install("foo","s*","bar","./filename.gp.so");
GP;install("foo","s*","bar","./filename.gp.so");
*/</lang>
*/</syntaxhighlight>
can be used to take a variable (0 or more) number of arguments. Note that the return type in this case is implicitly <code>GEN</code>
can be used to take a variable (0 or more) number of arguments. Note that the return type in this case is implicitly <code>GEN</code>


Line 944: Line 1,454:
The perl scripting language allows prototypes to be checked during JIT compilation. Prototypes should be placed before subroutine definitions, declarations, or anonymous subroutines. The sigil [[Special characters#Perl|special symbols]] act as argument type placeholders.
The perl scripting language allows prototypes to be checked during JIT compilation. Prototypes should be placed before subroutine definitions, declarations, or anonymous subroutines. The sigil [[Special characters#Perl|special symbols]] act as argument type placeholders.


<lang perl>sub noargs(); # Declare a function with no arguments
<syntaxhighlight lang="perl">sub noargs(); # Declare a function with no arguments
sub twoargs($$); # Declare a function with two scalar arguments. The two sigils act as argument type placeholders
sub twoargs($$); # Declare a function with two scalar arguments. The two sigils act as argument type placeholders
sub noargs :prototype(); # Using the :attribute syntax instead
sub noargs :prototype(); # Using the :attribute syntax instead
sub twoargs :prototype($$);</lang>
sub twoargs :prototype($$);</syntaxhighlight>


=={{header|Perl 6}}==
=={{header|Phix}}==
{{libheader|Phix/basics}}
There is no restriction on placement of prototype declarations. (Actually, we call them "stub declarations".) In fact, stub declarations are rarely needed in Perl 6 because post-declaration of functions is allowed, and normal [http://design.perl6.org/S06.html#Subroutines_and_other_code_objects function declarations] do not bend the syntax the way they sometimes do in Perl 5.
Use explicit forward definitions. Optional, unless (for instance) you want to use named parameters in a forward call.<br>
Should be identical to the actual definition, but preceded by "forward" and with no body.
<!--<syntaxhighlight lang="phix">-->
<span style="color: #008080;">forward</span> <span style="color: #008080;">function</span> <span style="color: #000000;">noargs</span><span style="color: #0000FF;">()</span> <span style="color: #000080;font-style:italic;">-- Declare a function with no arguments</span>
<span style="color: #008080;">forward</span> <span style="color: #008080;">procedure</span> <span style="color: #000000;">twoargs</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- Declare a procedure with two arguments</span>
<span style="color: #008080;">forward</span> <span style="color: #008080;">procedure</span> <span style="color: #000000;">twoargs</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000080;font-style:italic;">/*b*/</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- Parameter names are optional in forward (and actual) definitions</span>
<span style="color: #008080;">forward</span> <span style="color: #008080;">function</span> <span style="color: #000000;">anyargs</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- varargs are [best/often] handled as a (single) sequence in Phix</span>
<span style="color: #008080;">forward</span> <span style="color: #008080;">function</span> <span style="color: #000000;">atleastonearg</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">...);</span> <span style="color: #000080;font-style:italic;">-- Default makes args optional (== actual defn)</span>
<!--</syntaxhighlight>-->
No special syntax is needed on actual or forward function definitions for named parameters, and calls are identical whether still forward or now fully defined.<br>
Defaults on optional parameters in forward definitions can also be dummy (but type compatible) values should the actual not yet be defined.


=={{header|PL/I}}==
Note that the <tt>...</tt> in all of these stub bodies is literally part of the declaration syntax.
<syntaxhighlight lang="pli">
declare s1 entry;
declare s2 entry (fixed);
declare s3 entry (fixed, float);


declare f1 entry returns (fixed);
A prototype declaration for a function that does not require arguments (and returns an Int):
declare f2 entry (float) returns (float);
<lang perl6>sub foo ( --> Int) {...}</lang>
declare f3 entry (character(*), character(*)) returns (character (20));
</syntaxhighlight>


=={{header|PureBasic}}==
A prototype declaration for a function that requires two arguments.
PureBasic defines both functions and procedures by using the keyword '''Procedure'''. For the purposes of this task I will describe both 'procedures' and 'functions' using only the term 'procedure'. PureBasic uses a one-pass compiler. All procedures need to be defined before use. The prototypes referred to in the task description are performed with forward declarations in PureBasic.
Note that we can omit the variable name and just use the sigil in the stub, since we don't need to reference the argument until the actual definition of the routine. Also, unlike in Perl 5, a sigil like <tt>@</tt> defaults to binding a single positional argument.
<lang perl6>sub foo (@, $ --> Int) {...}</lang>


PureBasic allows two types of prototyping.
A prototype declaration for a function that utilizes varargs after one required argument.
The first uses the keyword '''Declare''' and describes the name, return value, and parameters of a procedure.
Note the "slurpy" star turns the <tt>@</tt> sigil into a parameter that accepts all the rest of the positional arguments.
It is identical in form with the first line of a procedure definition with the exception that the keyword
<lang perl6>sub foo ($, *@ --> Int) {...}</lang>
'''Declare''' is used instead of the keyword 'Procedure'''.
It must be placed before the first use of the procedure and must occur before the procedure's definition.
The procedure declaration's parameteres need to match the order, type, and number of those in the procedure's
definition, though their names may be different.


The keyword '''ProtoType''' may be used for pointers to procedures so that a definition of the parameters and return type for the function being pointed to are defined and that the pointer may be used to execute the function with type checking. The parameter names do not have to match in the 'ProtoType' definition but the order, type and optional parameters do. 'ProtoTypes' must be defined before their first use.
A prototype declaration for a function that utilizes optional arguments after one required argument. Optionality is conferred by either a question mark or a default:
<lang perl6>sub foo ($, $?, $ = 42 --> Int) {...}</lang>


A prototype declaration for a function that utilizes named parameters:
PureBasic does not allow either variable arguments or named parameters.
<syntaxhighlight lang="purebasic">;Forward procedure declare defined with no arguments and that returns a string
<lang perl6>sub foo ($, :$faster, :$cheaper --> Int) {...}</lang>
Declare.s booTwo()
;Forward procedure declare defined with two arguments and that returns a float
Declare.f moo(x.f, y.f)
;Forward procedure declare with two arguments and an optional argument and that returns a float
Declare.f cmoo(x.f, y.f, m.f = 0)


;*** The following three procedures are defined before their first use.
Example of prototype declarations for subroutines or procedures, which in Perl 6 is done simply by noting that nothing is returned:
;Procedure defined with no arguments and that returns a string
<lang perl6>sub foo ($, $ --> Nil) {...}</lang>
Procedure.s boo(): ProcedureReturn "boo": EndProcedure
;Procedure defined with two arguments and that returns an float
Procedure.f aoo(x.f, y.f): ProcedureReturn x + y: EndProcedure
;Procedure defined with two arguments and an optional argument and that returns a float
Procedure.f caoo(x.f, y.f, m.f = 1): ProcedureReturn (x + y) * m: EndProcedure


;ProtoType defined for any function with no arguments and that returns a string
A routine may also slurp up all the named arguments that were not bound earlier in the signature:
Prototype.s showString()
<lang perl6>sub foo ($, :$option, *% --> Int) {...}</lang>
;Prototype defined for any function with two float arguments and that returns a float
Prototype.f doMath(x.f, y.f)
;ProtoType defined for any function with two float arguments and an optional float argument and that returns a float
Prototype.f doMathWithOpt(x.f, y.f, m.f = 0)


Define a.f = 12, b.f = 5, c.f = 9
A routine may make a named parameter mandatory using exclamation mark. (This is more useful in multi subs than in stubs though.)
Define proc_1.showString, proc_2.doMath, proc_3.doMathWithOpt ;using defined ProtoTypes
<lang perl6>sub foo ($, :$option! --> Int) {...}</lang>
If OpenConsole("ProtoTypes and Forward Declarations")
PrintN("Forward Declared procedures:")
PrintN(boo())
PrintN(StrF(a, 2) + " * " + StrF(b, 2) + " = " + StrF(moo(a, b), 2))
PrintN(StrF(a, 2) + " * " + StrF(b, 2) + " + " + StrF(c, 2) + " = " + StrF(cmoo(a, b, c), 2))
PrintN(StrF(a, 2) + " * " + StrF(b, 2) + " = " + StrF(cmoo(a, b), 2))
;set pointers to second set of functions
proc_1 = @boo()
proc_2 = @aoo()
proc_3 = @caoo()
PrintN("ProtoTyped procedures (set 1):")
PrintN(proc_1())
PrintN(StrF(a, 2) + " ? " + StrF(b, 2) + " = " + StrF(proc_2(a, b), 2))
PrintN(StrF(a, 2) + " ? " + StrF(b, 2) + " ? " + StrF(c, 2) + " = " + StrF(proc_3(a, b, c), 2))
PrintN(StrF(a, 2) + " ? " + StrF(b, 2) + " = " + StrF(proc_3(a, b), 2))
;set pointers to second set of functions
proc_1 = @booTwo()
proc_2 = @moo()
proc_3 = @cmoo()
PrintN("ProtoTyped procedures (set 2):")
PrintN(proc_1())
PrintN(StrF(a, 2) + " ? " + StrF(b, 2) + " = " + StrF(proc_2(a, b), 2))
PrintN(StrF(a, 2) + " ? " + StrF(b, 2) + " ? " + StrF(c, 2) + " = " + StrF(proc_3(a, b, c), 2))
PrintN(StrF(a, 2) + " ? " + StrF(b, 2) + " = " + StrF(proc_3(a, b), 2))
Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input()
CloseConsole()
EndIf


A routine may unpack an <tt>Array</tt> automaticly. Here the first element is stored in a scalar and the rest in an <tt>Array</tt>. Other buildin types can be [http://design.perl6.org/S06.html#Unpacking_array_parameters unpacked] as well.
<lang perl6>sub foo ([$, @]) {...}</lang>


;*** If the forward Declaration above are not used then the following Procedure
A routine may ask for a closure parameter to implement higher order functions. Typed or untyped signatures can be supplied.
;definitions each have to be placed before the call to the respective procedure.
<lang perl6>sub foo (@, &:(Str --> Int)) {...}</lang>


;Procedure defined with no arguments and that returns a string
=={{header|Phix}}==
Procedure.s booTwo()
As explicit forward definitions, and optional - unless (eg) you want to use named parameters in a forward call.<br>
ProcedureReturn "booTwo"
Should be identical to the actual definition, but preceded by "forward" and with no body.
EndProcedure
<lang Phix>forward function noargs() -- Declare a function with no arguments
forward procedure twoargs(integer a, integer b) -- Declare a procedure with two arguments
forward procedure twoargs(integer, integer /*b*/) -- Parameter names are optional in forward (and actual) definitions
forward function anyargs(sequence s) -- varargs are [best/often] handled as a (single) sequence in Phix
forward function atleastonearg(integer a, integer b=1, ...); -- Default makes args optional (== actual defn)</lang>
No special syntax is needed on actual or forward function definitions for named parameters, and calls are identical whether still forward or now fully defined.<br>
Defaults on optional parameters in forward definitions can also be dummy (but type compatible) values should the actual not yet be defined.


;Procedure defined with two arguments and that returns an float
=={{header|PL/I}}==
Procedure.f moo(x.f, y.f)
<lang pli>
ProcedureReturn x * y
declare s1 entry;
EndProcedure
declare s2 entry (fixed);
declare s3 entry (fixed, float);


;Procedure defined with two arguments and an optional argument and that returns an float
declare f1 entry returns (fixed);
Procedure.f cmoo(x.f, y.f, m.f = 0)
declare f2 entry (float) returns (float);
ProcedureReturn (x * y) + m
declare f3 entry (character(*), character(*)) returns (character (20));
EndProcedure
</lang>
</syntaxhighlight>
Sample output:
<pre>Forward Declared procedures:
boo
12.00 * 5.00 = 60.00
12.00 * 5.00 + 9.00 = 69.00
12.00 * 5.00 = 60.00
ProtoTyped procedures (set 1):
boo
12.00 ? 5.00 = 17.00
12.00 ? 5.00 ? 9.00 = 153.00
12.00 ? 5.00 = 0.00
ProtoTyped procedures (set 2):
booTwo
12.00 ? 5.00 = 60.00
12.00 ? 5.00 ? 9.00 = 69.00
12.00 ? 5.00 = 60.00</pre>

=={{header|Quackery}}==

In Quackery a "word" corresponds to a function or subroutine. If you want to make a forward declaration (typically but not exclusively for recursive or mutually recursive words) you would use <code>forward is</code>, and resolve the forward declaration with <code>resolves</code>.

For example, the naive recursive Fibonacci function. (Note that the texts in parentheses are stack comments and can be omitted. Their inclusion is good practice. No declaration of parameters or arguments is required in Quackery.)

<syntaxhighlight lang="text"> forward is fibonacci ( n --> n )

[ dup 2 < if done
dup 1 - fibonacci
swap 2 - fibonacci + ] resolves fibonacci ( n --> n )</syntaxhighlight>


=={{header|Racket}}==
=={{header|Racket}}==
Most of the points are covered in this program
Most of the points are covered in this program
<lang racket>
<syntaxhighlight lang="racket">
#lang racket
#lang racket


Line 1,021: Line 1,618:
(define (varargs2 a . args) (void)) ;one obligatory argument and the rest are contained in the list
(define (varargs2 a . args) (void)) ;one obligatory argument and the rest are contained in the list


(define (optional-arg (a 5)) (void)) ;a defaults to 5</lang>
(define (optional-arg (a 5)) (void)) ;a defaults to 5</syntaxhighlight>


<tt>(void)</tt> is a function that returns "nothing", so this are prototypes that do nothing.
<tt>(void)</tt> is a function that returns "nothing", so this are prototypes that do nothing.
Although standard Racket doesn't allow type declarations, it allows contracts, so we can add this to the previous declarations
Although standard Racket doesn't allow type declarations, it allows contracts, so we can add this to the previous declarations
<lang racket>
<syntaxhighlight lang="racket">
(provide (contract-out
(provide (contract-out
[two-args (integer? integer? . -> . any)]))</lang>
[two-args (integer? integer? . -> . any)]))</syntaxhighlight>
then any module that imports the function can only pass integers to two-args.
then any module that imports the function can only pass integers to two-args.


Another way is using the <tt>typed/racket</tt> language, like this
Another way is using the <tt>typed/racket</tt> language, like this
<lang racket>
<syntaxhighlight lang="racket">
#lang typed/racket
#lang typed/racket


(: two-args (Integer Integer -> Any))
(: two-args (Integer Integer -> Any))
(define (two-args a b) (void))</lang>
(define (two-args a b) (void))</syntaxhighlight>

=={{header|Raku}}==
(formerly Perl 6)
There is no restriction on placement of prototype declarations. (Actually, we call them "stub declarations".) In fact, stub declarations are rarely needed in Raku because post-declaration of functions is allowed, and normal [http://design.raku.org/S06.html#Subroutines_and_other_code_objects function declarations] do not bend the syntax the way they sometimes do in Perl 5.

Note that the <tt>...</tt> in all of these stub bodies is literally part of the declaration syntax.

A prototype declaration for a function that does not require arguments (and returns an Int):
<syntaxhighlight lang="raku" line>sub foo ( --> Int) {...}</syntaxhighlight>

A prototype declaration for a function that requires two arguments.
Note that we can omit the variable name and just use the sigil in the stub, since we don't need to reference the argument until the actual definition of the routine. Also, unlike in Perl 5, a sigil like <tt>@</tt> defaults to binding a single positional argument.
<syntaxhighlight lang="raku" line>sub foo (@, $ --> Int) {...}</syntaxhighlight>

A prototype declaration for a function that utilizes varargs after one required argument.
Note the "slurpy" star turns the <tt>@</tt> sigil into a parameter that accepts all the rest of the positional arguments.
<syntaxhighlight lang="raku" line>sub foo ($, *@ --> Int) {...}</syntaxhighlight>

A prototype declaration for a function that utilizes optional arguments after one required argument. Optionality is conferred by either a question mark or a default:
<syntaxhighlight lang="raku" line>sub foo ($, $?, $ = 42 --> Int) {...}</syntaxhighlight>

A prototype declaration for a function that utilizes named parameters:
<syntaxhighlight lang="raku" line>sub foo ($, :$faster, :$cheaper --> Int) {...}</syntaxhighlight>

Example of prototype declarations for subroutines or procedures, which in Raku is done simply by noting that nothing is returned:
<syntaxhighlight lang="raku" line>sub foo ($, $ --> Nil) {...}</syntaxhighlight>

A routine may also slurp up all the named arguments that were not bound earlier in the signature:
<syntaxhighlight lang="raku" line>sub foo ($, :$option, *% --> Int) {...}</syntaxhighlight>

A routine may make a named parameter mandatory using exclamation mark. (This is more useful in multi subs than in stubs though.)
<syntaxhighlight lang="raku" line>sub foo ($, :$option! --> Int) {...}</syntaxhighlight>

A routine may unpack an <tt>Array</tt> automaticly. Here the first element is stored in a scalar and the rest in an <tt>Array</tt>. Other buildin types can be [http://design.raku.org/S06.html#Unpacking_array_parameters unpacked] as well.
<syntaxhighlight lang="raku" line>sub foo ([$, @]) {...}</syntaxhighlight>

A routine may ask for a closure parameter to implement higher order functions. Typed or untyped signatures can be supplied.
<syntaxhighlight lang="raku" line>sub foo (@, &:(Str --> Int)) {...}</syntaxhighlight>


=={{header|REXX}}==
=={{header|REXX}}==
Line 1,067: Line 1,702:
To begin with, we look at the definition provided [http://rosettacode.org/wiki/Function_definition#SNOBOL4 at the relevant task page]:
To begin with, we look at the definition provided [http://rosettacode.org/wiki/Function_definition#SNOBOL4 at the relevant task page]:


<lang snobol4> define('multiply(a,b)') :(mul_end)
<syntaxhighlight lang="snobol4"> define('multiply(a,b)') :(mul_end)
multiply multiply = a * b :(return)
multiply multiply = a * b :(return)
mul_end
mul_end
Line 1,074: Line 1,709:
output = multiply(10.1,12.2)
output = multiply(10.1,12.2)
output = multiply(10,12)
output = multiply(10,12)
end</lang>
end</syntaxhighlight>


The key to this is the <code>define()</code> BIF which declares the actual function and the <code>multiply</code> label which is the entry point to the code that is executed. The key is that SNOBOL4 is an almost militantly unstructured language. There is absolutely nothing special about the <code>multiply</code> entry point that distinguishes it from the target of any other branch target. What happens instead is that the <code>define()</code> BIF associates a certain string pattern--the prototype, in effect--with an entry point. The <code>:(mul_end)</code> piece at the end, in fact, exists because were it not present the body of the <code>multiply</code> "function" would be executed: it is a branch to the label <code>mul_end</code>.
The key to this is the <code>define()</code> BIF which declares the actual function and the <code>multiply</code> label which is the entry point to the code that is executed. The key is that SNOBOL4 is an almost militantly unstructured language. There is absolutely nothing special about the <code>multiply</code> entry point that distinguishes it from the target of any other branch target. What happens instead is that the <code>define()</code> BIF associates a certain string pattern--the prototype, in effect--with an entry point. The <code>:(mul_end)</code> piece at the end, in fact, exists because were it not present the body of the <code>multiply</code> "function" would be executed: it is a branch to the label <code>mul_end</code>.
Line 1,084: Line 1,719:
Of course this implies that you can separate the two pieces. Which you can, like this:
Of course this implies that you can separate the two pieces. Which you can, like this:


<lang snobol4> define('multiply(a,b)')
<syntaxhighlight lang="snobol4"> define('multiply(a,b)')


*
*
Line 1,104: Line 1,739:
output = multiply(10.1,12.2)
output = multiply(10.1,12.2)
output = multiply(10,12)
output = multiply(10,12)
end</lang>
end</syntaxhighlight>


With this structure the "function" is declared at the program, the implementation is somewhere down in the middle, and the mainline (<code>test</code> here) is at the end.
With this structure the "function" is declared at the program, the implementation is somewhere down in the middle, and the mainline (<code>test</code> here) is at the end.
Line 1,119: Line 1,754:
Thus a highly-contrived example function that illustrates all of these would look like this:
Thus a highly-contrived example function that illustrates all of these would look like this:


<lang snobol4> define('multiply(a,b)acc1,acc2','mult_impl') :(mult_end)
<syntaxhighlight lang="snobol4"> define('multiply(a,b)acc1,acc2','mult_impl') :(mult_end)
mult_impl acc1 = a
mult_impl acc1 = a
acc2 = b
acc2 = b
Line 1,128: Line 1,763:
output = multiply(10.1,12.2)
output = multiply(10.1,12.2)
output = multiply(10,12)
output = multiply(10,12)
end</lang>
end</syntaxhighlight>

=={{header|Wren}}==
Firstly, Wren makes a distinction between functions and methods. The latter are always members of a class and never need to be prototyped regardless of the order in which they are declared or called.

On the other hand functions are standalone objects and cannot be called before they have been declared. Consequently, prototypes are required if a function calls itself recursively, if two (or more) functions are mutually recursive or if a function is simply called out of order for some reason.

A prototype is just a forward declaration of the function's name. Details of any parameters are not needed and cannot even be optionally specified as parameters are considered to be part of the function's body.

In the following example, the 'factorial' function is recursive and so needs a forward declaration. However, even though the function takes a single argument, no prior information about that is needed or possible. There is an example of mutual recursion protoyping in the [[Mutual_recursion#Wren]] task.
<syntaxhighlight lang="wren">var factorial // forward declaration

factorial = Fn.new { |n| (n <= 1) ? 1 : factorial.call(n-1) * n }

System.print(factorial.call(5))</syntaxhighlight>

{{out}}
<pre>
120
</pre>


=={{header|zkl}}==
=={{header|zkl}}==
In zkl, all functions are var args. Prototypes provide provide some documentation and an overlay on the incoming args. Named parameters are not supported.
In zkl, all functions are var args. Prototypes provide some documentation and an overlay on the incoming args. Named parameters are not supported.
<lang zkl>fcn{"Hello World"} // no expected args
<syntaxhighlight lang="zkl">fcn{"Hello World"} // no expected args
fcn(){"Hello World"} // ditto
fcn(){"Hello World"} // ditto


Line 1,155: Line 1,809:


// no type enforcement but you can give a hint to the compiler
// no type enforcement but you can give a hint to the compiler
fcn([Int]n){n.sin()} //--> syntax error as Ints don't do sin</lang>
fcn([Int]n){n.sin()} //--> syntax error as Ints don't do sin</syntaxhighlight>


{{omit from|AutoHotkey}}
{{omit from|AutoHotkey}}
Line 1,178: Line 1,832:
{{omit from|NetRexx}}
{{omit from|NetRexx}}
{{omit from|PicoLisp}}
{{omit from|PicoLisp}}
{{omit from|Processing|No such thing as a function prototype.}}
{{omit from|Python}}
{{omit from|Python}}
{{omit from|R}}
{{omit from|R}}

Latest revision as of 11:33, 6 December 2023

Task
Function prototype
You are encouraged to solve this task according to the task description, using any language you may know.

Some languages provide the facility to declare functions and subroutines through the use of function prototyping.


Task

Demonstrate the methods available for declaring prototypes within the language. The provided solutions should include:

  • An explanation of any placement restrictions for prototype declarations
  • A prototype declaration for a function that does not require arguments
  • A prototype declaration for a function that requires two arguments
  • A prototype declaration for a function that utilizes varargs
  • A prototype declaration for a function that utilizes optional arguments
  • A prototype declaration for a function that utilizes named parameters
  • Example of prototype declarations for subroutines or procedures (if these differ from functions)
  • An explanation and example of any special forms of prototyping not covered by the above


Languages that do not provide function prototyping facilities should be omitted from this task.

Ada

In Ada, prototypes are called specifications.

  • Specifications must be an exact copy of everything prior to the "is" statement for a function or procedure.
  • All specifications must appear in a declarative section, ie: before a "begin" statement.
  • For a main program, specifications are only necessary if a function call appears in the source before the function definition.
  • For a package, specifications must appear as part of the specification(.ads) file, and do not appear in the body file(.adb) (The file extensions apply to Gnat Ada and may not apply to all compilers).
function noargs return Integer;
function twoargs (a, b : Integer) return Integer;
--  varargs do not exist
function optionalargs (a, b : Integer := 0) return Integer;
--  all parameters are always named, only calling by name differs
procedure dostuff (a : Integer);

Other Prototyping: Since pointers are not generic in Ada, a type must be defined before one can have a pointer to that type, thus for making linked-list type semantics another trivial prototyping exists:

type Box; --  tell Ada a box exists (undefined yet)
type accBox is access Box; --  define a pointer to a box
type Box is record --  later define what a box is
   next : accBox; --  including that a box holds access to other boxes
end record;

Example of a package specification (i.e. prototype):

package Stack is
   procedure Push(Object:Integer);
   function Pull return Integer;
end Stack;

Example of a package body:

package body Stack is

   procedure Push(Object:Integer) is
   begin
      -- implementation goes here
   end;

   function Pull return Integer;
   begin
      -- implementation goes here
   end;

end Stack;

To use the package and function:

with Stack;
procedure Main is
   N:integer:=5;
begin
   Push(N);
   ...
   N := Pull;
end Main;

Aime

integer f0(void);               # No arguments
void f1(integer, real);         # Two arguments
real f2(...);                   # Varargs
void f3(integer, ...);          # Varargs

void f4(integer &, text &);     # Two arguments (integer and string), pass by reference
integer f5(integer, integer (*)(integer));
                                # Two arguments: integer and function returning integer and taking one integer argument
integer f6(integer a, real b);  # Parameters names are allowed
record f7(void);                # Function returning an associative array

ALGOL 68

Works with: ALGOL 68 version Revision 1.
Works with: ALGOL 68G version Any - tested with release algol68g-2.8.
Works with: ELLA ALGOL 68 version Any (with appropriate job cards) - tested with release 1.8-8d

File: Function_prototype.a68

#!/usr/bin/a68g --script #
# -*- coding: utf-8 -*- #

# An explanation of any placement restrictions for prototype declarations #
PROC VOID no args; # Declare a function with no argument that returns an INTeger #
PROC (INT #a#,INT #b#)VOID two args; # Declare a function with two arguments that returns an INTeger #
MODE VARARGS = UNION(INT,REAL,COMPL);
PROC ([]VARARGS)VOID var args; # An empty parameter list can be used to declare a function that accepts varargs #
PROC (INT, []VARARGS)VOID at least one args; # One mandatory INTeger argument followed by varargs #

MODE OPTINT = UNION(VOID,INT), OPTSTRING=UNION(VOID,STRING); # a function that utilizes optional arguments #
PROC (OPTINT, OPTSTRING)VOID optional arguments;

# A prototype declaration for a function that utilizes named parameters #
MODE KWNAME = STRUCT(STRING name),
     KWSPECIES = STRUCT(STRING species),
     KWBREED = STRUCT(STRING breed),
     OWNER=STRUCT(STRING first name, middle name, last name);
 
# due to the "Yoneda ambiguity" simple arguments must have an unique operator defined #
OP NAME = (STRING name)KWNAME: (KWNAME opt; name OF opt := name; opt),
   SPECIES = (STRING species)KWSPECIES: (KWSPECIES opt; species OF opt := species; opt),
   BREED = (STRING breed)KWBREED: (KWBREED opt; breed OF opt := breed; opt);
 
PROC ([]UNION(KWNAME,KWSPECIES,KWBREED,OWNER) #options#)VOID print pet;

# subroutines, and fuctions are procedures, so have the same prototype declarations #

# An explanation and example of any special forms of prototyping not covered by the above:  #
COMMENT 
  If a function has no arguments, eg f, 
  then it is not requied to pass it a "vacuum()" to call it, eg "f()" not correct!
  Rather is can be called without the () vacuum. eg "f"
  A GOTO "label" is equivalent to "PROC VOID label".
END COMMENT

SKIP

Amazing Hopper

Function prototypes are included in a #PROTO declaration in the header, at the beginning of a HOPPER source file, before the functional code (MAIN :). This is enforced by the HOPPER compiler, to declare pseudo functions.

#!/usr/bin/hopper

// Archivo Hopper
#include <hopper.h>

#context-free noargs         /* Declare a pseudo-function with no argument */
#synon noargs             no arguments
#context multiargs           /* Declare a pseudo-function with multi arguments */
#proto twoargs(_X_,_Y_)      /* Declare a pseudo-function with two arguments. #PROTO need arguments */

main:
   no arguments
   _two args(2,2)   // pseudo-function #proto need "_" sufix
   println
   {1,2,3,"hola mundo!","\n"}, multiargs
exit(0)

.locals

multiargs:   
   _PARAMS_={},pushall(_PARAMS_)
   [1:3]get(_PARAMS_),stats(SUMMATORY),println
   {"Mensaje: "}[4:5]get(_PARAMS_),println
   clear(_PARAMS_)
back

twoargs(a,b)
   {a}mulby(b)
back

// This function is as useful a   s an ashtray on a motorcycle:
no args:
   {0}minus(0),kill
back

{0}return

C

Function prototypes are typically included in a header file at the beginning of a source file prior to functional code. However, this is not enforced by a compiler.

int noargs(void); /* Declare a function with no argument that returns an integer */
int twoargs(int a,int b); /* Declare a function with two arguments that returns an integer */
int twoargs(int ,int); /* Parameter names are optional in a prototype definition */
int anyargs(); /* An empty parameter list can be used to declare a function that accepts varargs */
int atleastoneargs(int, ...); /* One mandatory integer argument followed by varargs */

C#

Abstract methods
Interfaces and abstract classes can define abstract methods that must be implemented by subclasses.

using System;
abstract class Printer
{
    public abstract void Print();
}

class PrinterImpl : Printer
{
    public override void Print() {
        Console.WriteLine("Hello world!");
    }
}

Delegates
A delegate is similar to a function pointer. They are multicast: multiple methods can be attached to them.

using System;
public delegate int IntFunction(int a, int b);

public class Program
{
    public static int Add(int x, int y) {
        return x + y;
    }

    public static int Multiply(int x, int y) {
        return x * y;
    }

    public static void Main() {
        IntFunction func = Add;
        Console.WriteLine(func(2, 3)); //prints 5
        func = Multiply;
        Console.WriteLine(func(2, 3)); //prints 6
        func += Add;
        Console.WriteLine(func(2, 3)); //prints 5. Both functions are called, but only the last result is kept.
    }
}

Partial methods
A partial type is a type that is defined in multiple files.
A partial method has its signature defined in one part of a partial type, and its implementation defined in another part of the type. If it is not implemented, the compiler removes the signature at compile time.
The following conditions apply to partial methods:
- Signatures in both parts of the partial type must match.
- The method must return void.
- No access modifiers are allowed. Partial methods are implicitly private.

//file1.cs
public partial class Program
{
    partial void Print();
}

//file2.cs
using System;

public partial class Program
{
    partial void Print() {
        Console.WriteLine("Hello world!");
    }

    static void Main() {
        Program p = new Program();
        p.Print(); //If the implementation above is not written, the compiler will remove this line.
    }
}

C++

Function declaration in C++ differs from that in C in some aspect.

int noargs(); // Declare a function with no arguments that returns an integer
int twoargs(int a,int b); // Declare a function with two arguments that returns an integer
int twoargs(int ,int); // Parameter names are optional in a prototype definition
int anyargs(...); // An ellipsis is used to declare a function that accepts varargs
int atleastoneargs(int, ...); // One mandatory integer argument followed by varargs
template<typename T> T declval(T); //A function template
template<typename ...T> tuple<T...> make_tuple(T...); //Function template using parameter pack (since c++11)

Clojure

If you want to make forward declarations, you can use declare.

(declare foo)

COBOL

Prototypes were introduced in COBOL 2002. In the following examples, PROGRAM-ID and PROGRAM can be replaced with the equivalents for functions and methods. However, in method prototypes the PROTOTYPE clause is not used.

       *> A subprogram taking no arguments and returning nothing.
       PROGRAM-ID. no-args PROTOTYPE.
       END PROGRAM no-args.

       *> A subprogram taking two 8-digit numbers as arguments, and returning
       *> an 8-digit number.
       PROGRAM-ID. two-args PROTOTYPE.
       DATA DIVISION.
       LINKAGE SECTION.
       01  arg-1 PIC 9(8).
       01  arg-2 PIC 9(8).
       01  ret   PIC 9(8).
       PROCEDURE DIVISION USING arg-1, arg-2 RETURNING ret.
       END PROGRAM two-args.

       *> A subprogram taking two optional arguments which are 8-digit
       *> numbers (passed by reference (the default and compulsory for
       *> optional arguments)).
       PROGRAM-ID. optional-args PROTOTYPE.
       DATA DIVISION.
       LINKAGE SECTION.
       01  arg-1 PIC 9(8).
       01  arg-2 PIC 9(8).
       PROCEDURE DIVISION USING OPTIONAL arg-1, OPTIONAL arg-2.
       END PROGRAM optional-args.

       *> Standard COBOL does not support varargs or named parameters.

       *> A function from another language, taking a 32-bit integer by
       *> value and returning a 32-bit integer (in Visual COBOL).
       PROGRAM-ID. foreign-func PROTOTYPE.
       OPTIONS.
           ENTRY-CONVENTION some-langauge.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  arg PIC S9(9) USAGE COMP-5.
       01  ret PIC S9(9) USAGE COMP-5.
       PROCEDURE DIVISION USING arg RETURNING ret.
       END PROGRAM foreign-func.

Common Lisp

In Common Lisp, function prototypes can be used with (declaim (inline func-name)) function arguments are taken when the function is defined. In addition, the argument types aren't needed.

Caveat -- This works with specific implementations of CL. This was tested in SBCL.

(declaim (inline no-args))
(declaim (inline one-arg))
(declaim (inline two-args))
(declaim (inline optional-args))

(defun no-args ()
  (format nil "no arguments!"))

(defun one-arg (x) 
  ; inserts the value of x into a string
  (format nil "~a" x))

(defun two-args (x y)
  ; same as function `one-arg', but with two arguments
  (format nil "~a ~a" x y))

(defun optional-args (x &optional y) ; optional args are denoted with &optional beforehand
  ; same as function `two-args', but if y is not given it just prints NIL
  (format nil "~a ~a~%" x y))


(no-args) ;=> "no arguments!" 

(one-arg 1) ;=> "1"

(two-args 1 "example") ;=> "1 example" 

(optional-args 1.0) ;=> "1.0 NIL" 

(optional-args 1.0 "example") ;=> "1.0 example"

More about declaim here

D

Beside function prototypes similar to the ones available in C (plus templates, D-style varargs), you can define class method prototypes in abstract classes and interfaces. The exact rules for this are best explained by the documentation

/// Declare a function with no arguments that returns an integer.
int noArgs();

/// Declare a function with two arguments that returns an integer.
int twoArgs(int a, int b);

/// Parameter names are optional in a prototype definition.
int twoArgs2(int, int);

/// An ellipsis can be used to declare a function that accepts
/// C-style varargs.
int anyArgs(...);

/// One mandatory integer argument followed by C-style varargs.
int atLeastOneArg(int, ...);

/// Declare a function that accepts any number of integers.
void anyInts(int[] a...);

/// Declare a function that accepts D-style varargs.
void anyArgs2(TArgs...)(TArgs args);

/// Declare a function that accepts two or more D-style varargs.
void anyArgs3(TArgs...)(TArgs args) if (TArgs.length > 2);

/// Currently D doesn't support named arguments.

/// One implementation.
int twoArgs(int a, int b) {
    return a + b;
}

interface SomeInterface {
    void foo();
    void foo(int, int);

    // Varargs
    void foo(...); // C-style.
    void foo(int[] a...);
    void bar(T...)(T args); // D-style.

    // Optional arguments are only supported if a default is provided,
    // the default arg(s) has/have to be at the end of the args list.
    void foo(int a, int b = 10);
}

void main() {}

Delphi

In Delphi, prototype function is named Class/Record Helper. For now, is not possible has more then one helper active in a same object, if two or more was declareted, just the present in the last Unit declareted will be active, the others will be ignored. In case two or more helpers was declareted in same Unit, just the last helper declareted will be active. Can not inherit record helpers, but class helper can be.
Patten: " identifierName = record helper for TypeIdentifierName"
See Documentation for more details.

program Function_prototype;

{$APPTYPE CONSOLE}

uses
  System.SysUtils;

type
  TIntArray = TArray<Integer>;

  TIntArrayHelper = record helper for TIntArray
    const
      DEFAULT_VALUE = -1;
    // A prototype declaration for a function that does not require arguments
    function ToString(): string;

    // A prototype declaration for a function that requires two arguments
    procedure Insert(Index: Integer; value: Integer);

    // A prototype declaration for a function that utilizes varargs
    // varargs is not available, but a equivalent is array of const
    procedure From(Args: array of const);

    //A prototype declaration for a function that utilizes optional arguments
    procedure Delete(Index: Integer; Count: Integer = 1);

    //A prototype declaration for a function that utilizes named parameters
    // Named parameters is not supported in Delphi

    //Example of prototype declarations for subroutines or procedures
    //(if these differ from functions)
    procedure Sqr;    //Procedure return nothing
    function Averange: double; //Function return a value
  end;

{ TIntHelper }

function TIntArrayHelper.Averange: double;
begin
  Result := 0;
  for var e in self do
    Result := Result + e;
  Result := Result / Length(self);
end;

procedure TIntArrayHelper.Delete(Index, Count: Integer);
begin
  System.Delete(self, Index, Count);
end;

procedure TIntArrayHelper.From(Args: array of const);
var
  I, Count: Integer;
begin
  Count := Length(Args);
  SetLength(self, Count);

  if Count = 0 then
    exit;
  for I := 0 to High(Args) do
    with Args[I] do
      case VType of
        vtInteger:
          self[I] := VInteger;
        vtBoolean:
          self[I] := ord(VBoolean);
        vtChar, vtWideChar:
          self[I] := StrToIntDef(string(VChar), DEFAULT_VALUE);
        vtExtended:
          self[I] := Round(VExtended^);
        vtString:
          self[I] := StrToIntDef(VString^, DEFAULT_VALUE);
        vtPChar:
          self[I] := StrToIntDef(VPChar, DEFAULT_VALUE);
        vtObject:
          self[I] := cardinal(VObject);
        vtClass:
          self[I] := cardinal(VClass);
        vtAnsiString:
          self[I] := StrToIntDef(string(VAnsiString), DEFAULT_VALUE);
        vtCurrency:
          self[I] := Round(VCurrency^);
        vtVariant:
          self[I] := Integer(VVariant^);
        vtInt64:
          self[I] := Integer(VInt64^);
        vtUnicodeString:
          self[I] := StrToIntDef(string(VUnicodeString), DEFAULT_VALUE);
      end;
end;

procedure TIntArrayHelper.Insert(Index, value: Integer);
begin
  system.Insert([value], self, Index);
end;

procedure TIntArrayHelper.Sqr;
begin
  for var I := 0 to High(self) do
    Self[I] := Self[I] * Self[I];
end;

function TIntArrayHelper.ToString: string;
begin
  Result := '[';
  for var e in self do
    Result := Result + e.ToString + ', ';
  Result := Result + ']';
end;

begin
  var val: TArray<Integer>;
  val.From([1, '2', PI]);
  val.Insert(0, -1); // insert -1 at position 0
  writeln('  Array:    ', val.ToString, ' ');
  writeln('  Averange: ', val.Averange: 3: 2);
  val.Sqr;
  writeln('  Sqr:      ', val.ToString);
  Readln;

end.
Output:
  Array:    [-1, 1, 2, 3, ]
  Averange: 1.25
  Sqr:      [1, 1, 4, 9, ]

Class helper example, with inherited helpers:
Patten: " identifierName = class helper (ancestor list*) for TypeIdentifierName"
Ancertor list is optional, and only will be used if this helper will inhret a parent helper.

program Function_prototype_class;

{$APPTYPE CONSOLE}

uses
  System.SysUtils,
  System.Classes;

type
  TStringListHelper1 = class helper for TStringList
    constructor Create(FileName: TFileName); overload;
  end;

  TStringListHelper2 = class helper (TStringListHelper1) for TStringList
    procedure SaveAndFree(FileName: TFileName);
  end;

    TStringListHelper3 = class helper (TStringListHelper2) for TStringList
    procedure AddDateTime;
  end;

{ TStringListHelper1 }

constructor TStringListHelper1.Create(FileName: TFileName);
begin
  inherited Create;
  if FileExists(FileName) then
    LoadFromFile(FileName);
end;

{ TStringListHelper2 }

procedure TStringListHelper2.SaveAndFree(FileName: TFileName);
begin
  SaveToFile(FileName);
  Free;
end;

{ TStringListHelper3 }

procedure TStringListHelper3.AddDateTime;
begin
  self.Add(DateToStr(now));
end;

begin
  with TStringList.Create('d:\Text.txt') do
  begin
    AddDateTime;
    SaveAndFree('d:\Text_done.txt');
  end;
  readln;
end.

Diego

// A prototype declaration for a function that does not require arguments

begin_funct(foo);                           // function as a 'method' with no arguments, no return type
end_funct(foo);

// or

with_funct(foo);                            // function as a 'method' with no arguments, no return type

// A prototype declaration for a function that requires two arguments

begin_funct(goo)_arg({string}, str1, str2); // two arguments, no return type
end_funct[];                                // derived name of function using [], like 'this'

with_funct(goo)_arg({str}, str1, str2);     // two arguments, no return type
with_funct(hoo)_param({integer}, i, j);     // 'param' posit can be used instead of 'arg'

// A prototype declaration for a function that utilizes varargs

begin_funct(voo)_arg({int}, [vararg], v);   // variable number of arguments, no return type, 'int' can be used instead of 'integer'
end_funct[];

begin_funct({int}, voo)_arg({int}, ..., v);   // variable number of arguments, with return type
    add_var({int}, sum)_v(0);
    forall_var(v)_calc([sum]+=[v]);
    [voo]_ret([sum]);
end_funct[];

// A prototype declaration for a function that utilizes optional arguments
        
begin_funct({int}, ooo)_arg(o)_value(1);   // optional argument with default value and return type integer
    with_funct(ooo)_return([o]);           // Can be shortened to [ooo]_ret([0]);
end_funct[];

begin_funct({int}, oxo)_arg(o,u,v)_opt(u)_value(1); // optional argument of second argument with default value and return type integer
    [ooo]_ret(1);                               // the execution has to name arguments or missing in comma-separated list of arguments
end_funct[];   

// A prototype declaration for a function that utilizes named parameters

begin_funct({int}, poo)_param({int}, a, b, c); // to enforce named parameters '_param' posit can be used.
    [poo]_ret([a]+[b]+[c]);                    
end_funct[];

exec_funct(poo)_param(a)_value(1)_param(b, c)_value(2, 3) ? me_msg()_funct(poo); ;

begin_funct({int}, poo)_arg({int}, a, b, c); // named parameters can still be used with '_arg' posit.
    [poo]_ret([a]+[b]+[c]);                    
end_funct[];

me_msg()_funct(poo)_arg(a)_value(1)_value(2, 3); // Callee has to figure out unnamed arguments by extraction
                                                 // 'exec_' verb is implied before '_funct' action

// Example of prototype declarations for subroutines or procedures (if these differ from functions)

begin_instruct(foo);                        // instructions are 'methods', no arguments, no return type
end_instruct[foo];                          // explicit end of itself

// or

with_instruct(foo);                         // instructions are 'methods', no arguments, no return type

begin_funct(yoo)_arg(robotMoniker)_param(b);        // A '_funct' can be used as a subroutine when missing the '{}' return datatype 
                                                    // a mix of '_arg' and '_param' posits can be used
    with_robot[robotMoniker]_var(sq)_calc([b]^2);   // create a variable called 'sq' on robot 'robotMoniker'
end_funct(yoo);

begin_instruct(woo)_arg(robotType)_param(b);           // An '_instuct' is only used for subroutines and return datatypes are not accepted
    with_robot()_type[robotType]_var(sq)_calc([b]^2);  // create a variable called 'sq' on all robots of type 'robotType'
end_funct(woo);

// An explanation and example of any special forms of prototyping not covered by the above

begin_funct({double}, voo)_arg({int}, [numArgs], v);   // variable-defined number of arguments, with return type
    add_var({int}, sum)_v(0);
    add_var({double}, average)_v(0);
    for_var(v)_until[numArgs]_calc([sum]+=[v]);        // the number of arguments [numArgs] does not have to be number of arguments of v 
    [voo]_ret([sum]/[numArgs]);
end_funct[];

begin_funct({int}, [numArgsOut], voo)_arg({int}, [numArgsIn], v);   // variable-defined number of arguments, with variable-defined number of return types
    add_var({int}, sum)_v(0);
    add_var({double}, average)_v(0);
    for_var(v)_until[numArgsOut]_calc([sum]+=[v]);
    [voo]_ret([sum]/[numArgsOut]);
end_funct[];

F#

In F#, prototypes are called signatures. Signature files are used to bulk annotate the accessibility of the things within them. If something is in an implementation file but not in the signature file, it is assumed to be private to that file. If it is in the signature file without the internal accessibility modifier, then it is assumed to public, otherwise it is internal to the assembly. For more details, see the documentation. Below is an example of the signatures produced for the functions specified in the task (without any accessibility modifiers):

// A function taking and returning nothing (unit).
val noArgs : unit -> unit
// A function taking two integers, and returning an integer.
val twoArgs : int -> int -> int
// A function taking a ParamPack array of ints, and returning an int. The ParamPack
// attribute is not included in the signature.
val varArgs : int [] -> int
// A function taking an int and a ParamPack array of ints, and returning an
// object of the same type.
val atLeastOnArg : int -> int [] -> int
// A function taking an int Option, and returning an int.
val optionalArg : Option<int> -> int

// Named arguments and the other form of optional arguments are only available on
// methods.
type methodClass =
  class
    // A method taking an int named x, and returning an int.
    member NamedArg : x:int -> int
    // A method taking two optional ints in a tuple, and returning an int. The
    //optional arguments must be tupled.
    member OptionalArgs : ?x:int * ?y:int -> int
  end

FreeBASIC

' FB 1.05.0 Win64

' The position regarding prototypes is broadly similar to that of the C language in that functions, 
' sub-routines or operators (unless they have already been fully defined) must be declared before they can be used. 
' This is usually done near the top of a file or in a separate header file which is then 'included'.

' Parameter names are optional in declarations. When calling functions, using parameter names 
' (as opposed to identifying arguments by position) is not supported.

Type MyType ' needed for operator declaration
  i As Integer
End Type

Declare Function noArgs() As Integer  ' function with no argument that returns an integer 
Declare Function twoArgs(As Integer, As Integer) As Integer ' function with two arguments that returns an integer 
Declare Function atLeastOneArg CDecl(As Integer, ...) As Integer ' one mandatory integer argument followed by varargs
Declare Function optionalArg(As Integer = 0) As Integer ' function with a (single) optional argument with default value 
Declare Sub noArgs2() ' sub-routine with no argument
Declare Operator + (As MyType, As MyType) As MyType ' operator declaration (no hidden 'This' parameter for MyType)


' FreeBASIC also supports object-oriented programming and here all constructors, destructors, 
' methods (function or sub), properties and operators (having a hidden 'This' parameter) must be 
' declared within a user defined type and then defined afterwards.


Type MyType2
  Public:
    Declare Constructor(As Integer)
    Declare Destructor()
    Declare Sub MySub()   
    Declare Function MyFunction(As Integer) As Integer 
    Declare Property MyProperty As Integer
    Declare Operator Cast() As String
  Private:
    i As Integer
End Type

Go

While the language specification does not use the word prototype it states, "A function declaration may omit the body. Such a declaration provides the signature for a function implemented outside Go, such as an assembly routine." This is the closest analogy to a C (e.g.) prototype.

Function declarations whether with a body or without must be "top level" declarations, that is, after the package clause and outside of any other function. Examples of function delarations without bodies are,

func a()          // function with no arguments
func b(x, y int)  // function with two arguments
func c(...int)    // varargs are called "variadic parameters" in Go.

Go does not directly support optional or named parameters and does not have any concept of procedures or subroutines as distinct from functions.

Otherwise, Go does have the concept of a function signature which includes parameters and return values. Go is strongly typed and functions are first class objects so function signatures are used in a variety of ways. These might be considered distinct from the concept of function prototype.

Haskell

A function can be declared without giving it's prototype in Haskell. The haskell compiler has got type inference whereby it can infer the return type and type of variable given to function. You can still hardcode the prototype which specifies the datatype of variables and return type. For ex. Consider a function add which takes two integers and returns their sum. It can be prototyped and declared as :

add :: Int -> Int -> Int
add x y = x+y

Actually all functions in haskell are functions with just one arguments. Haskell will treat above function as a function which takes an int and returns a function with type (:: (Int->Int)) . Then this function which is returned is such that it takes an int and returns an int. Similarly for any function add which takes 3 integers and adds them the actual prototype will be as follows:

add :: Int->(Int ->(Int->Int))

The one that does not require arguements could just be:

printThis = putStrLn("This is being printed.")

But haskell would rather consider the function to be of return type IO() in this case.

Two arguments:

add :: Int -> Int -> Int
add x y = x+y

The same thing can be done using the lambda function as :

add :: Int -> Int -> Int
add = \x->\y -> x+y

Two arguments with unnamed parameters:

doThis :: Int-> Int-> String
doThis _ _  = "Function with unnamed parameters"

Function with var args requires creation of type class as per the requirement.

J

J assumes an unknown name is a verb of infinite rank. Rank determines the frames on which the verb executes. As the demonstration shows, changing the rank, assigning the rank before the verb is used in other definitions affects the result. We could, of course, play other games by changing the unknown name from verb to another part of speech.

   NB. j assumes an unknown name f is a verb of infinite rank
   NB. f has infinite ranks
   f b. 0
_ _ _
   
   NB. The verb g makes a table.
   g=: f/~

   NB. * has rank 0
   f=: *


   NB. indeed, make a multiplication table
   f/~ i.5
0 0 0  0  0
0 1 2  3  4
0 2 4  6  8
0 3 6  9 12
0 4 8 12 16
   
   NB. g was defined as if f had infinite rank.
   g i.5
0 1 4 9 16
   
   NB. f is known to have rank 0.
   g=: f/~

   NB. Now we reproduce the table
   g i.5
0 0 0  0  0
0 1 2  3  4
0 2 4  6  8
0 3 6  9 12
0 4 8 12 16
   
   

   NB. change f to another rank 0 verb
   f=: +   

   NB. and construct an addition table
   g i.5
0 1 2 3 4
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8
   

   NB. f is multiplication at infinite rank
   f=: *"_
   

   NB. g, however, has rank 0
   g i.5
0 0 0  0  0
0 1 2  3  4
0 2 4  6  8
0 3 6  9 12
0 4 8 12 16

Java

The order of declarations in Java is unimportant, so forward declaration of functions is neither needed nor supported. The only place where function prototypes are needed is in abstract classes or interfaces, where implementation will be provided by the derived or implementing class.

public final class FunctionPrototype {
	
	public static void main(String[] aArgs) {
		Rectangle rectangle = new Rectangle(10.0, 20.0);
		System.out.println("Area = " + rectangle.area());
		
		Calculator calculator = new Calculator();
		System.out.println("Sum = " + calculator.sum(2, 2));
		calculator.version();
	}	

	private static class Rectangle implements Shape {
		
		public Rectangle(double aWidth, double aLength) {
			width = aWidth; length = aLength;
		}
		
		@Override
	    public double area() {
	        return length * width;
	    }		
		
		private final double width, length;
	    
	}	
	
	private static class Calculator extends Arithmetic {
		
		public Calculator() {
			// Statements to create the graphical 
			// representation of the calculator
		}
		
		@Override
		public int sum(int aOne, int aTwo) {
			return aOne + aTwo;
		}
		
		@Override
		public void version() {
			System.out.println("0.0.1");
		}
		
	}	

}

interface Shape {
    public double area();
}	 

abstract class Arithmetic {
	public abstract int sum(int aOne, int aTwo);
	public abstract void version();		
}
Output:
Area = 200.0
Sum = 4
0.0.1

JavaScript

ES5

JavaScript functions may also be used to define prototype objects

// A prototype declaration for a function that does not require arguments
function List() {}

List.prototype.push = function() {
  return [].push.apply(this, arguments);
};

List.prototype.pop = function() {
  return [].pop.call(this);
};

var l = new List();
l.push(5);
l.length; // 1
l[0]; 5
l.pop(); // 5
l.length; // 0

// A prototype declaration for a function that utilizes varargs
function List() {
  this.push.apply(this, arguments);
}

List.prototype.push = function() {
  return [].push.apply(this, arguments);
};

List.prototype.pop = function() {
  return [].pop.call(this);
};

var l = new List(5, 10, 15);
l.length; // 3
l[0]; 5
l.pop(); // 15
l.length; // 2

ES6

Class Declarations are used to define prototype objects

// A prototype declaration for a function that does not require arguments
class List {
  push() {
    return [].push.apply(this, arguments);
  }
  pop() {
    return [].pop.call(this);  
  }
}

var l = new List();
l.push(5);
l.length; // 1
l[0]; 5
l.pop(); // 5
l.length; // 0



// A prototype declaration for a function that utilizes varargs
class List {
  constructor(...args) {
    this.push(...args);
  }
  push() {
    return [].push.apply(this, arguments);
  }
  pop() {
    return [].pop.call(this);  
  }
}

var l = new List(5, 10, 15);
l.length; // 3
l[0]; 5
l.pop(); // 15
l.length; // 2

jq

jq does not have "function prototypes" in the strict sense, so this entry focuses on jq function signatures as specified in function definitions.

jq does not limit the number of formal parameters of a function and supports multi-arity functions, but each allowed "restriction" to a particular arity must be specified explicitly.

Although jq does not support varargs functions, their effect can be achieved by using an array-valued argument in conjunction with "destructuring", as illustrated below.

Note also that:

  • any restrictions on the allowed values of the parameters must be specified programmatically and are only checked at run-time;
  • function definitions may be included within function definitions;
  • recursive and mutually recursive functions are allowed, but calls to a function can only occur within the scope of its definition.
  • a function of a particular arity can be defined more than once, with lexical scoping rules determining how each invocation will be handled.

In the following examples, only `def` and `as` are jq keywords, and .... is used to indicate ellipsis.

def Func: # no arguments

def Func(a;b): # two arguments

def Vararg(v):  
  v as [$a1, $a2] ....  # if v is an array, then $a1 will be the first item specified by v, or else null, and so on

def Vararg(a; v):
  v as [$a1, $a2] ....  # if v is an array, then $a1 will be the first item specified by v, or else null, and so on

Julia

Julia does not need or use function prototypes in general. Generic functions are further specialized as to argument type and return type during just-in-time compilation if required. However, when interacting with other languages such a C which use function prototypes, Julia can prototype its functions for passing its functions to external languages with the @cfunction macro:

julia > function mycompare(a, b)::Cint
      (a < b) ? -1 : ((a > b) ? +1 : 0)
  end
mycompare (generic function with 1 method)

Using @cfunction to create a prototype for passing this to C's quicksort:

julia> mycompare_c = @cfunction(mycompare, Cint, (Ref{Cdouble}, Ref{Cdouble}))

Kotlin

The order of declarations in Kotlin is unimportant and so forward declaration of 'top level' functions is neither needed nor supported.

The only place where function (or property) prototypes are needed is for abstract members of classes or interfaces whose implementation will be provided by overriding those members in a derived or implementing class or object.

Here's an example of this. Note that since Kotlin allows arguments to be passed either by name or position for all functions, there is no separate prototype for this situation. Moreover, since arguments may be passed by name, it is strongly recommended (but not obligatory) that the parameter names for overriding members should be the same as for the functions they override. The compiler will issue a warning if this recommendation is not followed.

// version 1.0.6

interface MyInterface {
    fun foo()                     // no arguments, no return type
    fun goo(i: Int, j: Int)       // two arguments, no return type
    fun voo(vararg v: Int)        // variable number of arguments, no return type
    fun ooo(o: Int = 1): Int      // optional argument with default value and return type Int
    fun roo(): Int                // no arguments with return type Int
    val poo: Int                // read only property of type Int
}

abstract class MyAbstractClass {
    abstract fun afoo()           // abstract member function, no arguments or return type
    abstract var apoo: Int        // abstract read/write member property of type Int
}

class Derived : MyAbstractClass(), MyInterface {
    override fun afoo() {}
    override var apoo: Int = 0

    override fun foo() {}
    override fun goo(i: Int, j: Int) {}
    override fun voo(vararg v: Int) {}
    override fun ooo(o: Int): Int = o  // can't specify default argument again here but same as in interface
    override fun roo(): Int = 2
    override val poo: Int = 3
}

fun main(args: Array<String>) {
    val d = Derived()
    println(d.apoo)
    println(d.ooo())  // default argument of 1 inferred
    println(d.roo())
    println(d.poo)
}
Output:
0
1
2
3

Lua

function Func() -- Does not require arguments
	return 1
end

function Func(a,b) -- Requires arguments
	return a + b
end

function Func(a,b) -- Arguments are optional
	return a or 4 + b or 2
end

function Func(a,...) -- One argument followed by varargs
	return a,{...} -- Returns both arguments, varargs as table
end

Luck

function noargs(): int = ? ;;
function twoargs(x:int, y:int): int = ? ;;

/* underscore means ignore and is not bound to lexical scope */
function twoargs(_:bool, _:bool): int = ? ;;

function anyargs(xs: ...): int = ? ;;
function plusargs(x:int, xs: ...): int = ? ;;

M2000 Interpreter

Functions/modules are declared before used. So the flow matter, position in code not matter (perhaps we can put functions in a simple routine, using a label, execute a gosub to label, then make the functions, and then return. Functions amd modules added to a specific list of functions/modules, so every time interpreter check that list (a hash table). They can change definition including signature. Any module/function before executed has no declared local modules/functions. Declarations performed as they executed. For modules, we can prepare a non changed module before begin execute module's code, and when declaration for same name module comes to execute, it just skipped.

Subroutines are parts of functions/modules and first searched from bottom, added to a list of subs positions,therefore they can't changed. Example of change an inner module using another module with same signature. Module MyBeta {Read x : ... } or Module MyBeta (x) { ... } or Module MyBeta(x) { } is the same.

Module Check {
      Module MyBeta (a) {
            Print "MyBeta", a/2
      }
      Module TestMe {
            Module Beta (x) {
                  Print "TestMeBeta", x
            }
            Beta 100
      }
      TestMe ; Beta as MyBeta
}
Check

Signatures needed for Event object. An event object get a list of functions, called as modules, and call every function with same signature. We can provide arguments by reference too. We can define simple functions (without visibility except local and global), or group functions (static groups) with visibility local, global and group level, or we can define local scope functions.

Module Check {, 
      \\ make an event object
      \\ with a prototype signature
      \\ first parameter  is numeric/object by value, and second is by reference
      Event Alfa {
            Read x, &z
      }
      
      \\ make a function with same signature
      Function ServiceAlfa {
            read a, &b
            b+=a
      }
      
      \\ add function to event
      Event Alfa new &ServiceAlfa()
      
      \\ call event in this module
      var=30
      Call Event Alfa,  10, &var
      Print var=40
      \\ make a local module, and pass event by value
      Module checkinside (ev) {
            \\ ev is a copy of Alfa
            m=10
            call event ev, 4, &m
            Print m=14
            \\ clear functions from ev
            Event ev Clear
            \\ we can call it again, but nothing happen
            call event ev, 4, &m
            Print m=14
      }
      checkinside Alfa
      \\ so now we call Alfa 
      Call Event Alfa,  10, &var
      Print var=50
      Event Alfa Hold
      \\ calling do nothing, because of Hold state
      Call Event Alfa,  10, &var
      Event Alfa Release
      Call Event Alfa,  10, &var
      Print var=60
}
Check

Using a function for local call (module visibility)

Module Check {, 
      \\ make an event object
      \\ with a prototype signature
      \\ first parameter  is numeric/object by value, and second is by reference
      Event Alfa {
            Read x, &z
      }
      
      \\ make a function with same signature
      \\ but here prepared to used with current module visibility
      m=0
      Function ServiceAlfa {
            \ this code "see" m variable
            \\ we have to use new, to make new a, b for sure
            read new a, &b
            b+=a
            m++
      }
      
      \\ add function to event, making reference as local to module
      Event Alfa new Lazy$(&ServiceAlfa())
      
      \\ call event in this module
      var=30
      Call Event Alfa,  10, &var
      Print var=40
      \\ make a local module, and pass event by value
      Module checkinside (ev) {
            \\ ev is a copy of Alfa
            m=10
            call event ev, 4, &m
            Print m=14
            \\ clear functions from ev
            Event ev Clear
            \\ we can call it again, but nothing happen
            call event ev, 4, &m
            Print m=14
      }
      checkinside Alfa
      \\ so now we call Alfa 
      Call Event Alfa,  10, &var
      Print var=50
      Event Alfa Hold
      \\ calling do nothing, because of Hold state
      Call Event Alfa,  10, &var
      Event Alfa Release
      Call Event Alfa,  10, &var
      Print var=60
      Print m=4  ' 4 times called ServiceAlfa
}
Check

Using a Function in a Group (Groups are the User objects in M2000)

Module Check {, 
      \\ make an event object
      \\ with a prototype signature
      \\ first parameter  is numeric/object by value, and second is by reference
      Event Alfa {
            Read x, &z
      }
      
      \\ make a group function with same signature
     
     Group IamStatic {
            m=0
            Function ServiceAlfa(a, &b) {
                  b+=a
                  .m++
            }
}
      
      \\ add function to event, making reference as local to module
      Event Alfa new &IamStatic.ServiceAlfa()
      
      \\ call event in this module
      var=30
      Call Event Alfa,  10, &var
      Print var=40
      \\ make a local module, and pass event by value
      Module checkinside (ev) {
            \\ ev is a copy of Alfa
            m=10
            call event ev, 4, &m
            Print m=14
            \\ clear functions from ev
            Event ev Clear
            \\ we can call it again, but nothing happen
            call event ev, 4, &m
            Print m=14
      }
      checkinside Alfa
      \\ so now we call Alfa 
      Call Event Alfa,  10, &var
      Print var=50
      Event Alfa Hold
      \\ calling do nothing, because of Hold state
      Call Event Alfa,  10, &var
      Event Alfa Release
      Call Event Alfa,  10, &var
      Print var=60
      Print IamStatic.m=4  ' 4 times called IamStatic.ServiceAlfa
}
Check

Nim

Procedure declarations can be used if a proc is to be used before its definition.

# Procedure declarations. All are named
proc noargs(): int
proc twoargs(a, b: int): int
proc anyargs(x: varargs[int]): int
proc optargs(a, b: int = 10): int

# Usage
discard noargs()
discard twoargs(1,2)
discard anyargs(1,2,3,4,5,6,7,8)
discard optargs(5)

# Procedure definitions
proc noargs(): int = echo "noargs"
proc twoargs(a, b: int): int = echo "twoargs"
proc anyargs(x: varargs[int]): int = echo "anyargs"
proc optargs(a: int, b = 10): int = echo "optargs"

OCaml

(* Usually prototype declarations are put in an interface file,
   a file with .mli filename extension *)

(* A prototype declaration for a function that does not require arguments *)
val no_arg : unit -> unit

(* A prototype declaration for a function that requires two arguments *)
val two_args : int -> int -> unit

(* A prototype declaration for a function that utilizes optional arguments *)
val opt_arg : ?param:int -> unit -> unit
(* in this case we add a unit parameter in order to omit the argument,
   because ocaml supports partial application *)

(* A prototype declaration for a function that utilizes named parameters *)
val named_arg : param1:int -> param2:int -> unit

(* An explanation and example of any special forms of prototyping not covered by the above *)

(* A prototype declaration for a function that requires a function argument *)
val fun_arg : (int -> int) -> unit

(* A prototype declaration for a function with polymorphic argument *)
val poly_arg : 'a -> unit

Oforth

Oforth can only forward declare methods (see Mutual Recursion task). A method can be declared without any class implementation :

Method new: myMethod

This creates a new method object with name myMethod (or does nothing if this object already exists). It says nothing about method implementations (number of parameters, return value, ...).

A method object is not directly related to classes :

- A method object is created.

- Classes are created.

- Into classes, you can create implementations for particular methods. If, at this point, the method object does not exist yet, it is created.

Ol

Ol have no function prototypes.

Ol functions is a first-class functions with dynamic arguments translation so no function prototypes is required.

OxygenBasic

'DECLARE FUNCTION' ABBREVIATED TO '!'

!  f()                     ' a procedure with no params
!  f(int a)                ' with 1 int param
!  f(int *a)               ' with 1 int pointer param
!  f(int a, int b, inc c)  ' with 3 int params
!  f(int a,b,c)            ' compaction with 3 int params
!  f(string s, int a,b)    ' with 1 string and 2 int params
!  f() as string           ' function returning a string
!  f(string s) as string   ' with 1 string param
! *f(string s) as string   ' as a function pointer: @f=address
!  f(string s, optional i) ' with opptional param
!  f(string s = "Hello")   ' optional param with default value
!  f(int n, ...)           ' 1 specific param and varargs
!  f(...)                  ' any params or none

'TRADITIONAL BASIC DECLARATIONS
declare sub f( s as string, i as long, j as long)  ' byref by default
declare function f( byref s as string, byval i as long, byval j as long) as string

'C-STYLE DECLARATIONS
void f(string *s, long i, long j)
string f(string *s, long i, long j)



'BLOCK DIRECTIVES FOR FUNCTION PROTOTYPES:

extern                      ' shareable stdcall functions

extern  lib "xyz.dll"       ' for accessing functions in xyz Dynamic Link Library

extern export               ' functions to be exported if this is a DLL

extern virtual              ' for accssing interfaces and other virtual classes

end extern                  ' revert to internal function mode

PARI/GP

GP does not use function prototypes.

PARI uses C prototypes. Additionally, gp2c parser codes are essentially function prototypes. They must be placed in the file called by gp2c, not in a file included by it, and they must appear as a GP; comment. For a function

long
foo(GEN a, GEN b)

which takes two (required) t_INT arguments, returns a small integer (a C long) and appears as bar to the gp interpreter, the following command would be used:

/*
GP;install("foo","LGG","bar","./filename.gp.so");
*/

If its arguments were optional it could be coded as

/*
GP;install("foo","LDGDG","bar","./filename.gp.so");
*/

although other parser codes are possible; this one sends NULL if the arguments are omitted.

A code like

/*
GP;install("foo","s*","bar","./filename.gp.so");
*/

can be used to take a variable (0 or more) number of arguments. Note that the return type in this case is implicitly GEN

Other special forms are described in the User's Guide to the PARI library, section 5.7.3.

Perl

The perl scripting language allows prototypes to be checked during JIT compilation. Prototypes should be placed before subroutine definitions, declarations, or anonymous subroutines. The sigil special symbols act as argument type placeholders.

sub noargs(); # Declare a function with no arguments
sub twoargs($$); # Declare a function with two scalar arguments. The two sigils act as argument type placeholders
sub noargs :prototype(); # Using the :attribute syntax instead
sub twoargs :prototype($$);

Phix

Library: Phix/basics

Use explicit forward definitions. Optional, unless (for instance) you want to use named parameters in a forward call.
Should be identical to the actual definition, but preceded by "forward" and with no body.

forward function noargs() -- Declare a function with no arguments
forward procedure twoargs(integer a, integer b) -- Declare a procedure with two arguments
forward procedure twoargs(integer, integer /*b*/) -- Parameter names are optional in forward (and actual) definitions
forward function anyargs(sequence s) -- varargs are [best/often] handled as a (single) sequence in Phix
forward function atleastonearg(integer a, integer b=1, ...); -- Default makes args optional (== actual defn)

No special syntax is needed on actual or forward function definitions for named parameters, and calls are identical whether still forward or now fully defined.
Defaults on optional parameters in forward definitions can also be dummy (but type compatible) values should the actual not yet be defined.

PL/I

declare s1 entry;
declare s2 entry (fixed);
declare s3 entry (fixed, float);

declare f1 entry returns (fixed);
declare f2 entry (float) returns (float);
declare f3 entry (character(*), character(*)) returns (character (20));

PureBasic

PureBasic defines both functions and procedures by using the keyword Procedure. For the purposes of this task I will describe both 'procedures' and 'functions' using only the term 'procedure'. PureBasic uses a one-pass compiler. All procedures need to be defined before use. The prototypes referred to in the task description are performed with forward declarations in PureBasic.

PureBasic allows two types of prototyping. The first uses the keyword Declare and describes the name, return value, and parameters of a procedure. It is identical in form with the first line of a procedure definition with the exception that the keyword Declare is used instead of the keyword 'Procedure. It must be placed before the first use of the procedure and must occur before the procedure's definition. The procedure declaration's parameteres need to match the order, type, and number of those in the procedure's definition, though their names may be different.

The keyword ProtoType may be used for pointers to procedures so that a definition of the parameters and return type for the function being pointed to are defined and that the pointer may be used to execute the function with type checking. The parameter names do not have to match in the 'ProtoType' definition but the order, type and optional parameters do. 'ProtoTypes' must be defined before their first use.

PureBasic does not allow either variable arguments or named parameters.

;Forward procedure declare defined with no arguments and that returns a string
Declare.s booTwo()
;Forward procedure declare defined with two arguments and that returns a float
Declare.f moo(x.f, y.f)
;Forward procedure declare with two arguments and an optional argument and that returns a float
Declare.f cmoo(x.f, y.f, m.f = 0)

;*** The following three procedures are defined before their first use.
;Procedure defined with no arguments and that returns a string
Procedure.s boo(): ProcedureReturn "boo": EndProcedure
;Procedure defined with two arguments and that returns an float
Procedure.f aoo(x.f, y.f): ProcedureReturn x + y: EndProcedure
;Procedure defined with two arguments and an optional argument and that returns a float
Procedure.f caoo(x.f, y.f, m.f = 1): ProcedureReturn (x + y) * m: EndProcedure

;ProtoType defined for any function with no arguments and that returns a string
Prototype.s showString() 
;Prototype defined for any function with two float arguments and that returns a float
Prototype.f doMath(x.f, y.f)
;ProtoType defined for any function with two float arguments and an optional float argument and that returns a float
Prototype.f doMathWithOpt(x.f, y.f, m.f = 0) 

Define a.f = 12, b.f = 5, c.f = 9
Define proc_1.showString, proc_2.doMath, proc_3.doMathWithOpt ;using defined ProtoTypes
If OpenConsole("ProtoTypes and Forward Declarations")
  
  PrintN("Forward Declared procedures:")
  PrintN(boo())
  PrintN(StrF(a, 2) + " * " + StrF(b, 2) + " = " + StrF(moo(a, b), 2))
  PrintN(StrF(a, 2) + " * " + StrF(b, 2) + " + " + StrF(c, 2) + " = " + StrF(cmoo(a, b, c), 2))
  PrintN(StrF(a, 2) + " * " + StrF(b, 2) + " = " + StrF(cmoo(a, b), 2))
  
  ;set pointers to second set of functions
  proc_1 = @boo()
  proc_2 = @aoo()
  proc_3 = @caoo()
  
  PrintN("ProtoTyped procedures (set 1):")
  PrintN(proc_1())
  PrintN(StrF(a, 2) + " ? " + StrF(b, 2) + " = " + StrF(proc_2(a, b), 2))
  PrintN(StrF(a, 2) + " ? " + StrF(b, 2) + " ? " + StrF(c, 2) + " = " + StrF(proc_3(a, b, c), 2))
  PrintN(StrF(a, 2) + " ? " + StrF(b, 2) + " = " + StrF(proc_3(a, b), 2))
  
  ;set pointers to second set of functions
  proc_1 = @booTwo()
  proc_2 = @moo()
  proc_3 = @cmoo()
  
  PrintN("ProtoTyped procedures (set 2):")
  PrintN(proc_1())
  PrintN(StrF(a, 2) + " ? " + StrF(b, 2) + " = " + StrF(proc_2(a, b), 2))
  PrintN(StrF(a, 2) + " ? " + StrF(b, 2) + " ? " + StrF(c, 2) + " = " + StrF(proc_3(a, b, c), 2))
  PrintN(StrF(a, 2) + " ? " + StrF(b, 2) + " = " + StrF(proc_3(a, b), 2))
  
  
  Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input()
  CloseConsole()
EndIf


;*** If the forward Declaration above are not used then the following Procedure
;definitions each have to be placed before the call to the respective procedure.

;Procedure defined with no arguments and that returns a string
Procedure.s booTwo()
  ProcedureReturn "booTwo"
EndProcedure

;Procedure defined with two arguments and that returns an float
Procedure.f moo(x.f, y.f)
  ProcedureReturn x * y
EndProcedure

;Procedure defined with two arguments and an optional argument and that returns an float
Procedure.f cmoo(x.f, y.f, m.f = 0)
  ProcedureReturn (x * y) + m
EndProcedure

Sample output:

Forward Declared procedures:
boo
12.00 * 5.00 = 60.00
12.00 * 5.00 + 9.00 = 69.00
12.00 * 5.00 = 60.00
ProtoTyped procedures (set 1):
boo
12.00 ? 5.00 = 17.00
12.00 ? 5.00 ? 9.00 = 153.00
12.00 ? 5.00 = 0.00
ProtoTyped procedures (set 2):
booTwo
12.00 ? 5.00 = 60.00
12.00 ? 5.00 ? 9.00 = 69.00
12.00 ? 5.00 = 60.00

Quackery

In Quackery a "word" corresponds to a function or subroutine. If you want to make a forward declaration (typically but not exclusively for recursive or mutually recursive words) you would use forward is, and resolve the forward declaration with resolves.

For example, the naive recursive Fibonacci function. (Note that the texts in parentheses are stack comments and can be omitted. Their inclusion is good practice. No declaration of parameters or arguments is required in Quackery.)

                         forward is fibonacci ( n --> n )

  [ dup  2 < if done
    dup  1 - fibonacci
    swap 2 - fibonacci + ] resolves fibonacci ( n --> n )

Racket

Most of the points are covered in this program

#lang racket

(define (no-arg) (void))

(define (two-args a b) (void)) ;arguments are always named

(define (varargs . args) (void)) ;the extra arguments are stored in a list

(define (varargs2 a . args) (void)) ;one obligatory argument and the rest are contained in the list

(define (optional-arg (a 5)) (void)) ;a defaults to 5

(void) is a function that returns "nothing", so this are prototypes that do nothing. Although standard Racket doesn't allow type declarations, it allows contracts, so we can add this to the previous declarations

(provide (contract-out
          [two-args (integer? integer? . -> . any)]))

then any module that imports the function can only pass integers to two-args.

Another way is using the typed/racket language, like this

#lang typed/racket

(: two-args (Integer Integer -> Any))
(define (two-args a b) (void))

Raku

(formerly Perl 6) There is no restriction on placement of prototype declarations. (Actually, we call them "stub declarations".) In fact, stub declarations are rarely needed in Raku because post-declaration of functions is allowed, and normal function declarations do not bend the syntax the way they sometimes do in Perl 5.

Note that the ... in all of these stub bodies is literally part of the declaration syntax.

A prototype declaration for a function that does not require arguments (and returns an Int):

sub foo ( --> Int) {...}

A prototype declaration for a function that requires two arguments. Note that we can omit the variable name and just use the sigil in the stub, since we don't need to reference the argument until the actual definition of the routine. Also, unlike in Perl 5, a sigil like @ defaults to binding a single positional argument.

sub foo (@, $ --> Int) {...}

A prototype declaration for a function that utilizes varargs after one required argument. Note the "slurpy" star turns the @ sigil into a parameter that accepts all the rest of the positional arguments.

sub foo ($, *@ --> Int) {...}

A prototype declaration for a function that utilizes optional arguments after one required argument. Optionality is conferred by either a question mark or a default:

sub foo ($, $?, $ = 42 --> Int) {...}

A prototype declaration for a function that utilizes named parameters:

sub foo ($, :$faster, :$cheaper --> Int) {...}

Example of prototype declarations for subroutines or procedures, which in Raku is done simply by noting that nothing is returned:

sub foo ($, $ --> Nil) {...}

A routine may also slurp up all the named arguments that were not bound earlier in the signature:

sub foo ($, :$option, *% --> Int) {...}

A routine may make a named parameter mandatory using exclamation mark. (This is more useful in multi subs than in stubs though.)

sub foo ($, :$option! --> Int) {...}

A routine may unpack an Array automaticly. Here the first element is stored in a scalar and the rest in an Array. Other buildin types can be unpacked as well.

sub foo ([$, @]) {...}

A routine may ask for a closure parameter to implement higher order functions. Typed or untyped signatures can be supplied.

sub foo (@, &:(Str --> Int)) {...}

REXX

In the REXX language, there is no difference between functions and subroutines,   except that   functions   must   return a value,   even if that value is a "null"   (empty string).

In REXX, if a function doesn't return a value, a   syntax   condition is raised.

REXX has no need of pre─allocating a prototype   (such as required arguments and the like)   for functions or subroutines,   but there are facilities (in the form of BIFs) to assist the REXX programmer to easily determine the number of arguments passed (if any),   and perform (and/or enforce) any necessary argument passing (including the   type   of values or variables passed),   and also including checking for omitted arguments.   In effect, the relaxation of requirements/rules for function or subroutine invocations has been moved from the compile stage (for REXX, the parsing/interpretive) stage) to the execution stage.


Note:   REXX is an interpretive language.

SNOBOL4

In SNOBOL4, functions are actually a hack and are defined in an idiosyncratic way that is simultaneously like a prototype or not like one as the case may be.

Basics

To begin with, we look at the definition provided at the relevant task page:

          define('multiply(a,b)') :(mul_end)
multiply  multiply = a * b        :(return)
mul_end

* Test
          output = multiply(10.1,12.2)
          output = multiply(10,12)
end

The key to this is the define() BIF which declares the actual function and the multiply label which is the entry point to the code that is executed. The key is that SNOBOL4 is an almost militantly unstructured language. There is absolutely nothing special about the multiply entry point that distinguishes it from the target of any other branch target. What happens instead is that the define() BIF associates a certain string pattern--the prototype, in effect--with an entry point. The :(mul_end) piece at the end, in fact, exists because were it not present the body of the multiply "function" would be executed: it is a branch to the label mul_end.

On execution, the SNOBOL4 runtime will execute line by line of the script. When it reaches the define BIF call it will do the stuff it needs to do behind the scenes to set up function-like access to the multiply branch target. It would then proceed to execute the next line were it not for the branch.

Separation of prototype and body

Of course this implies that you can separate the two pieces. Which you can, like this:

          define('multiply(a,b)')

*
* Assume lots more code goes here.
*
                                  :(test)

*
* MORE CODE!
*

multiply  multiply = a * b        :(return)

*
* MORE CODE!
*

test
          output = multiply(10.1,12.2)
          output = multiply(10,12)
end

With this structure the "function" is declared at the program, the implementation is somewhere down in the middle, and the mainline (test here) is at the end.

Full prototyping

The define() BIF is used for more than merely providing function-like access to a label with the same name. It is used to prototype all of these (with some default behaviour):

  • the function name (multiply in the examples);
  • the formal arguments to the function (a, b in the examples);
  • the entry point label for the function's code (defaults to the function name, mult_impl in the following example);
  • any local variables which should be protected in the function (defaults to none, acc1,acc2 in the following example).

Thus a highly-contrived example function that illustrates all of these would look like this:

          define('multiply(a,b)acc1,acc2','mult_impl') :(mult_end)
mult_impl acc1 = a
          acc2 = b
          multiply = acc1 * acc2                       :(return)
mult_end

* Test
          output = multiply(10.1,12.2)
          output = multiply(10,12)
end

Wren

Firstly, Wren makes a distinction between functions and methods. The latter are always members of a class and never need to be prototyped regardless of the order in which they are declared or called.

On the other hand functions are standalone objects and cannot be called before they have been declared. Consequently, prototypes are required if a function calls itself recursively, if two (or more) functions are mutually recursive or if a function is simply called out of order for some reason.

A prototype is just a forward declaration of the function's name. Details of any parameters are not needed and cannot even be optionally specified as parameters are considered to be part of the function's body.

In the following example, the 'factorial' function is recursive and so needs a forward declaration. However, even though the function takes a single argument, no prior information about that is needed or possible. There is an example of mutual recursion protoyping in the Mutual_recursion#Wren task.

var factorial // forward declaration

factorial = Fn.new { |n| (n <= 1) ? 1 : factorial.call(n-1) * n }

System.print(factorial.call(5))
Output:
120

zkl

In zkl, all functions are var args. Prototypes provide some documentation and an overlay on the incoming args. Named parameters are not supported.

fcn{"Hello World"}   // no expected args
fcn(){"Hello World"} // ditto

fcn{vm.arglist}(1,2)   // ask the VM for the passed in args -->L(1,2)
fcn f(a,b){a+b}  // fcn(1,2,3) works just fine
fcn f(args){}(1,2,3)  //args = 1
fcn(args){vm.arglist.sum()}(1,2,3) //-->6

fcn(a=1,b=2){vm.arglist}()  //-->L(1,2)
fcn(a=1,b=2){vm.arglist}(5) //-->L(5,2)
fcn(a=1,b){vm.arglist}()    //-->L(1), error if you try to use b
fcn(a,b=2){vm.arglist}(5)   //-->L(5,2)
fcn(a,b=2,c){vm.arglist}(1) //-->L(1,2)

fcn(){vm.nthArg(1)}(5,6)           //-->6
fcn{vm.numArgs}(1,2,3,4,5,6,7,8,9) //-->9
fcn{vm.argsMatch(...)}   // a somewhat feeble attempt arg pattern matching based on type (vs value)

   // you can do list assignment in the prototype:
fcn(a,[(b,c)],d){vm.arglist}(1,L(2,3,4),5) //-->L(1,L(2,3,4),5)
fcn(a,[(b,c)],d){"%s,%s,%s,%s".fmt(a,b,c,d)}(1,L(2,3,4),5) //-->1,2,3,5

   // no type enforcement but you can give a hint to the compiler
fcn([Int]n){n.sin()} //--> syntax error as Ints don't do sin