Question How to decide when to use FUNCTION or INTERNAL PROCEDURE? What is the difference?

Rob Fitzpatrick

ProgressTalk.com Sponsor
A user-defined function is used when you want to perform some calculation and return a single value. In this respect it is the same as a built-in ABL function, like the SUBSTRING or EXP functions. Putting this calculation code in a FUNCTION block instead of inline in your code allows you to put it in one place and reference it multiple times without code duplication.

An internal procedure is also an encapsulated piece of code that does some work, but it is more general-purpose. While a function must return a single value, an internal procedure may or may not have input parameters or output parameters.

I suggest you read the sections about Defining Functions and Running ABL Procedures in the manual Getting Started: ABL Essentials. You can download the manuals for your release here:
OpenEdge 11.7 Product Documentation - Wiki - OpenEdge General - Progress Community
 

Cringer

ProgressTalk.com Moderator
Staff member
You are right in theory, Rob, although ABL allows you to define output parameters for a function as well as the return value. So in a sense either is usable in most cases.
If you are starting out as a Progress developer though, I would strongly recommend focusing on classes and methods.
 

Rob Fitzpatrick

ProgressTalk.com Sponsor
You are right in theory, Rob, although ABL allows you to define output parameters for a function as well as the return value. So in a sense either is usable in most cases.
Thanks for the correction. I assumed that functions in ABL are like functions in other languages I've encountered.
If you are starting out as a Progress developer though, I would strongly recommend focusing on classes and methods.
Agreed.
 

TomBascom

Curmudgeon
There are other languages that allow functions to have output parameters. Living fossil that I am, Pascal springs to mind.

IMHO:

Functions are most appropriate when your typical use case will be to embed the function call into other statements that use the return value. For instance:

s2 = substring( s1, firstSpace( s1 )).

where firstSpace() is a user defined function that returns the offset of the first space character in a string.

Procedures must be RUN - so you cannot embed them in other statements. And if you have more than one return value or output parameter procedures are generally more logical and sensible.

I would be tempted to use a class instead of a function if there is "state" data that is useful to keep outside the scope of a function. With a function that data has to be a variable that could be subject to side-effects. With a class that data becomes a property (which could be kept private) and a method of the class is a straight-forward replacement for a function.

Classes would also be a good replacement for procedures that have many arguments and procedures with multiple output parameters and procedures with "state".

Regarding OO -- it would also help to not have to support v9 ;)
 

andre42

Member
I don't think there is a significant difference in memory usage between functions and internal procedures. If you have to use either instead of methods and they are used in multiple programs you should just put them in a super procedure or session session service so they will only be loaded once in your session.
There are more important differences to think about. Function calls are checked at compile time (existence and matching parameters), run statements are not checked. A run ... no-error will suppress an error even if the procedure doesn't exist or the parameters don't match.
Functions can't return errors, procedures can.
With functions you can get the error "Input blocking statement is invalid while executing a user-defined function (2780)" in older Progress versions. Essentially that means that you can't use PROMPT-FOR, SET, UPDATE, WAIT-FOR, READKEY and PROCESS EVENTS while inside a function, including all procedures called from that function. The easiest way to avoid this is not to call procedures from a function. With newer versions this doesn't seem to be an issue anymore, see documentation on the -IOEverywhere parameter.

Methods kind of merge the advantages while avoiding the disadvantages. Method calls are checked at compile time and can return errors / exceptions.
 
Top