Function pointers are values indicating functions.
Function pointer variables are declared much like functions are, with the variable name preceded in order by a ‘(’ sign and a ‘*’ sign and followed by a ‘)’ sign, followed by the parameters list.
integer (*fp1)(integer); real (*fp2)(real, real); text (*fp3)(text, integer); object (*fp4)(object, &...);
Multiple declarations may occur on the same declarations line and may be mixed with declarations of non function pointer variables and declarations of function pointer variables of the same outer most function (evaluation) type.
integer (*fp5)(integer), a, b, (*fp6)(integer, integer); real c, (*fp7)(real, real); void (*fp8)(integer), (*fp9)(text, ...);
Like for function declarations, the parameters list appears between an opening paranthesis and a closing one. The parameters are separated by commas, and they have a type and an optional name. Exception is taken for the typeless anonymous and variadic ones, that have neither. Pass by reference is indicated by a ‘&’ sign.
integer (*fpa)(integer,), (*fpb)(,,), (*fpc)(real, &,, text); void (*fpd)(...), (*fpe)(text, &...), (*fpf)(&, integer,, ...);
The proper aime type of function pointers reflects the fully qualified signature of the assignable functions, return type and arguments list included. Thus ‘fp1’ and ‘fp5’ have the same type (‘integer (*)(integer)’), ‘fp5’ and ‘fp6’ do not (the type of ‘fp6’ is ‘integer (*)(integer, integer)’).
Also like for function declarations, the named non function pointer parameters that appear without type take their type from the preceding parameter, if the latter had one. Function pointer parameters, when missing the outer most function type, take the type or outer most function type of the preceding parameter, that has to be typed.
integer (*fpg)(integer, integer, integer), (*fph)(integer, b, c); void (*fpi)(integer, integer (*)(integer)), (*fpj)(integer, (*)(integer));
‘fpg’ and ‘fph’ have the same type, and so do ‘fpi’ and ‘fpj’.
Function pointer variables may be assigned from functions and function pointers, via the ‘=’ function pointer assignment operator, the ‘set’ function argument assignment function, etc.
See Positional Arguments Access.
fp1 = abs; fp5 = fp1; fp6 = min; fp2 = pow; fp4 = call;
void pointers_1(integer (*&f)(integer, integer)) { f = max; }
void pointers_2(integer (*&f)(integer, integer)) { set(0, max); }
The assigned value should match the function pointer in function evaluation type, arguments list, etc.
The assignation is still allowed if the two differ in function evaluation type only and the latter is ‘void’ for the assigned function pointer (some library interfaces may not permit this exception).
void (*f)(real, real &); real e; f = modf; f(4.8, e);
Functions may be viewed as read-only function pointer variables, though the view may not always apply. The aime interpreter will make function pointers out of functions where required.
The functions indicated by function pointers are called via the function pointers the way they would be called by their name, with the function pointer substituting the function name.
fp1(4); fp2(.5, 2); fp3("aime", 6); fp4(pow, 4, 4);
call(fp5, 4); call(fp6, 4, 8z); trap(fp7, 0, .25);
The alternate function call syntax that has the first argument before the function name is not available for function pointers.
Like any value, function pointers may be passed to functions as arguments or returned by functions.
integer pointers_3(integer (*f)(integer), integer (*g)(integer), integer (*h)(integer)) { return call($drand(2), -88); }
The function ‘pointers_3’ randomly calls a function in its input set and returns the result.
integer (*pointers_4(void))(integer) { return abs; }
The function ‘pointers_4’ returns a function pointer indicating the ‘abs’ function.
integer (*pointers_5(integer (*f)(integer), integer (*g)(integer), integer (*h)(integer)))(integer) { return $drand(2); }
The function ‘pointers_5’ randomly returns one of its arguments.
Function calls through unassigned function pointers will fail.