Yes, I have some experience with them - dim and distant, now.
The form compiler (sformbld) has to accept any function call that you make - it cannot tell whether it will be valid or not at run time. It does not know which functions are available to the (custom) Perform runner that will be needed to run the form.
Similarly, the report compiler (saceprep) has to accept any function call that you make because it cannot tell whether it will valid or not at run time.
To run a form that contains a function call other than the built-in functions, you must create a custom runner (rather than using the standard sperform). The script to do that on Unix is 'cperf'; it will take the function definitions that you provide and build a custom runner that can call those functions. You can then run a report which uses those functions using the custom runner. If your custom code does not do any ESQL/C calls, you don't even need ESQL/C on the machine; the ISQL product is sufficient.
The parallel circumstances apply to reports; you cannot use the standard sacego but must create an appropriate custom runner with 'cace'.
Now, in the dim distant dark ages (say before 1990), you did not get the custom ACE and Perform stuff with ISQL - you had to buy ISQL and ESQL/C. But since ISQL version 4.00 was released (AFAICR, in 1988 or 1989), the custom runners and libraries were provided with ISQL and you no longer need to buy ESQL/C unless you want to build ESQL/C functions into your custom functions.
Note that you do not create a custom compiler; therefore, the compiler cannot tell what functions are available.