What is a prototype?
In RPGLE, particularly in free-format style, a prototype serves as a function signature, outlining the exact way a program or procedure should be invoked. It's essentially the "agreement" that details the routine's name, input parameters, and output type, all without providing the underlying code.
In IBM i RPGLE, a prototype is basically the diva's dressing room memo for your code: it spells out exactly how a procedure or program expects to be summoned, down to the name, parameters, and what it spits back, without spilling a drop of the actual implementation.
Think of it as the "please don't call me unless you're wearing this" contract that keeps your modular code from turning into a chaotic family reunion. Declare one with DCL-PR, toss in your params like picky guest lists, and wrap with END-PR. Call it wrong? The compiler rolls its eyes and halts the compile, saving you from debugging disasters that could make even the most stoic sysadmin chuckle nervously.
Purpose and Benefits
Type safety: Ensures parameters passed match expected types.
Modularity: Lets you call procedures across modules or service programs.
Reusability: You can /COPY prototypes into multiple programs.
Clarity: Makes your code easier to read and maintain.
RPGLE Prototype Syntax (Free-form)
parm1 char(10) const;
parm2 packed(7:2);
end-pr;
dcl-prstarts the prototype block.MyProcedureis the name of the procedure.int(10)is the return type (optional if void).- Each parameter is defined with its type and optional keywords like
const,options(*nopass), etc. end-prcloses the prototype.
Calling External Programs
If you're calling an external program (like QCMDEXC), you use extpgm to process the call in the same way as an internal procedure
This prototype defines the call to QCMDEXC and you could use it like this:
dcl-pr RunCommand extpgm('QCMDEXC');
command char(3000) const;
length packed(15:5) const;
end-pr;
dcl-s cmdString char(3000);
dcl-s cmdLen packed(15:5);
// Build the command string
cmdString = 'DSPJOB OUTPUT(*PRINT)';
// Calculate the length (trim trailing blanks)
cmdLen = %len(%trimr(cmdString));
// Call the API
RunCommand(cmdString:cmdLen);
dsply ('Command executed! Check your printer spool.');
*inlr = *on;
Looking for a more obvious business example?
How about a simple procedure prototype for a "CalculateTax" function:
dcl-pr CalculateTax extproc('CALCTAX');
Amount packed(9:2);
Rate packed(3:2);
TaxResult char(10);
end-pr;
Here, the prototype defines a procedure expecting an amount and rate, returning a tax result string. When calling it (e.g., CalculateTax(100.00 : 0.08 : result);), the compiler checks against this definition.
