Dynamic Functions

Updated August 2020; see History

These are function calls that are dynamically bound—i.e. resolved—at runtime rather than at compile time.

To define a function that can be dynamically bound, insert the new keyword "dynamic" in front of the Function keyword in the function definition.

Dynamic Function Fn'Foo(...)

    ...

EndFunction

 

Tagging a function for dynamic binding like this does not interfere with traditional statically bound calls to the function; it simply opens up the additional possibility of dynamic binding.

To call the function with dynamic binding, use one of the new system functions DYNFUNC() or DYNFUNC$() ...

DYNFUNC(funcname,arg1,...,argN)   ! numeric function

DYNFUNC$(funcname,arg1,...,argN)  ! string function

These are analogous to the XFUNC and XFUNC$ system functions (used to dynamically call external functions implemented as SBX modules), except that here the target function is part of (i.e. compiled within) the current program. As with XFUNC()/XFUNC$(), the first argument (funcname here) is a string expression resolving at runtime to the name of the function to call. Unlike XFUNC/XFUNC$, dynamic function calls support Named Parameters, and they can be invoked via the CALL statement in addition to the normal method as an expression.

Examples

a$ = DYNFUNC$("Fn'Foo$",arg1,arg2)

n = 27

f$ = "Fn'Foo" + str(n) + "$"

call DYNFUNC$(f$,arg1,arg2,arg3)

 

call DYNFUNC$(f$,arg1,code=12345,qty=ordqty)

The first example calls the string function Fn'Foo$(arg1,arg2) The second calls a string function Fn'Foo27$(), passing it one positional parameter (arg1) and two named parameters (code=12345 and qty=ordqty). The last calls a function whose name is returned from Fn'Get'FuncName$(x).

A new BASIC error code, 72, undefined dynamic function, has been defined and added to the errmsg.xxx files. It will be triggered by an attempt to to dynamically call a function which is not declared dynamic within the current program.

Note that in all cases, the choice of DYNFUNC() vs DYNFUNC$() determines whether the function is expected to return a string or numeric value. Since the type of a function is determined by the presences of a "$" suffix, the presence or absence of the suffix on the DYNFUNC keyword should agree at runtime with the name of the target function. In other words, use DYNFUNC() to call numeric functions, and DYNFUNC$() to call string functions. Neither the compiler nor the runtime system will complain if you mix types, but the results are likely to disappoint.

Compatibility: RUN / SBX modules with Dynamic functions declared are fully compatible with earlier versions of A-Shell. But an attempt to call them from within an A-Shell session earlier than 6.5.1647.0 will generate an unsupported function error (35).

History

2022 August, A-Shell 6.5.1720, compiler edit 999:  Named parameters can now be used with DYNFUNC, and default parameter values are now supported in dynamic functions. Note that this affects both the compiler and runtime, so the use of named parameters in a DYNFUNC expression will now set the minimum runtime level to 6.5.1720. Also, with compiler edit 1000, /CI support has been extended to dynamic functions, both the function names and argument names.

2020 October, A-Shell 6.5.1689, compiler edit 937:  Arrays/collections may now be passed to DYNFUNC(), as they can in normal function references. Previously only array elements were supported.

2018 September, A-Shell 6.5.1647, compiler edit 879:  Added function to A-Shell