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.




// 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[];