Beginner

Hello World in RPG

Your first RPG program - the classic Hello World example in modern free-form RPG IV

Every programming journey starts with Hello World. RPG (Report Program Generator) is unique among the languages on this site because it runs exclusively on IBM i (formerly AS/400) - there is no open-source compiler or Docker image available for other platforms. We’ll show the code and explain how it works, but running it requires access to an IBM i system.

The Code

Create a file named hello.rpgle:

**FREE
dsply 'Hello, World!';
return;

That’s it - three lines for a fully free-form RPG Hello World.

Understanding the Code

The **FREE Directive

**FREE
  • **FREE must appear on the very first line, starting in column 1
  • Tells the compiler this is fully free-form source code
  • Without this directive, the compiler expects fixed-format column-based syntax
  • Available since IBM i 7.1 TR11 / 7.2 TR3 (November 2015)

DSPLY Operation

dsply 'Hello, World!';
  • dsply is the RPG operation code that displays a message
  • On IBM i, this sends a message to the program message queue
  • On a 5250 terminal session, the message appears and waits for the user to press Enter
  • In batch mode, the message is written to the job log
  • RPG is case-insensitive - DSPLY, dsply, and Dsply are all equivalent

RETURN Statement

return;
  • Exits the procedure or program
  • All statements end with a semicolon in free-form RPG

Alternative: Using *INLR

A more traditional RPG ending uses the Last Record indicator:

**FREE
dsply 'Hello, World!';
*inlr = *on;

Setting *INLR = *ON tells the RPG runtime to:

  1. Close all files
  2. Free program resources
  3. Return the program to its caller

This is the classic RPG way to end a program, inherited from the original program cycle where *INLR signaled “last record processed.”

Running on IBM i

RPG requires an IBM i system. There is no open-source RPG compiler for Linux, macOS, or Windows, and no Docker image is available.

Compiling and Running on IBM i

If you have access to an IBM i system, you can compile and run this program using CL (Control Language) commands:

1
2
3
CRTRPGMOD MODULE(MYLIB/HELLO) SRCSTMF('/home/user/hello.rpgle')
CRTPGM PGM(MYLIB/HELLO)
CALL PGM(MYLIB/HELLO)

Or as a single compile-and-bind step:

1
2
CRTBNDRPG PGM(MYLIB/HELLO) SRCSTMF('/home/user/hello.rpgle')
CALL PGM(MYLIB/HELLO)

Accessing IBM i

Options for getting IBM i access:

  • PUB400.COM - A free public IBM i system maintained by volunteers, available for learning and experimentation
  • IBM Power Virtual Server - Cloud-based IBM i instances on IBM Cloud
  • IBM i Access Client Solutions - Client software for connecting to IBM i systems

Expected Output

Hello, World!

On IBM i, the DSPLY operation shows this as a message that requires the user to press Enter to acknowledge. In batch mode, the message appears in the job log prefixed with DSPLY (e.g., DSPLY Hello, World!).

RPG Syntax Basics

Even in this simple Hello World, we can explore RPG’s distinctive features.

Fixed vs. Free Format

Modern RPG supports two formats. All new code should use free-form:

Free-Form (Modern - recommended):

**FREE
dcl-s message char(50) inz('Hello, World!');
dsply message;
*inlr = *on;

Fixed-Format (Legacy):

1
2
3
     D message         S             50    INZ('Hello, World!')
     C                   DSPLY                   message
     C                   EVAL      *INLR = *ON

In fixed format, each character’s column position determines its meaning - a direct holdover from the punched card era. The D in column 6 marks a definition specification, and C marks a calculation specification.

Variables and Data Types

**FREE
// Character
dcl-s name char(30) inz('World');

// Variable-length character
dcl-s greeting varchar(100);

// Packed decimal (for financial data)
dcl-s amount packed(11:2) inz(1234.56);

// Integer
dcl-s count int(10) inz(42);

// Indicator (boolean)
dcl-s active ind inz(*on);

// Date
dcl-s today date(*iso);
today = %date();

// Build greeting using string concatenation
greeting = 'Hello, ' + %trim(name) + '!';
dsply greeting;

*inlr = *on;

Built-in Functions

RPG provides many built-in functions (BIFs), all prefixed with %:

**FREE
dcl-s text char(50) inz('  Hello, World!  ');

// %TRIM - Remove leading and trailing blanks
dsply %trim(text);

// %LEN - Get length
dcl-s len int(10);
len = %len(%trim(text));

// %CHAR - Convert to character
dsply %char(len);

// %DATE - Current date
dcl-s today date(*iso);
today = %date();
dsply %char(today);

*inlr = *on;

Subprocedures

Modern RPG supports modular programming with subprocedures:

**FREE
ctl-opt main(main);

dcl-proc main;
  dcl-s greeting varchar(100);
  greeting = getGreeting('World');
  dsply greeting;
end-proc;

dcl-proc getGreeting;
  dcl-pi *n varchar(100);
    name varchar(50) const;
  end-pi;
  return 'Hello, ' + %trim(name) + '!';
end-proc;

Key features:

  • ctl-opt main(main) - Specifies the entry point procedure
  • dcl-proc / end-proc - Procedure boundaries
  • dcl-pi / end-pi - Procedure interface (parameters)
  • const - Parameter passed by read-only reference

Indicators: RPG’s Unique Feature

Numbered indicators (*IN01 through *IN99) are RPG’s most distinctive feature, inherited from tabulating machine indicator lights:

**FREE
// Indicators are boolean flags
*in50 = *on;

if *in50;
  dsply 'Indicator 50 is ON';
else;
  dsply 'Indicator 50 is OFF';
endif;

// Special indicators
// *INLR = Last Record (program end)
// *INOF = Overflow (page break)
// *IN01-*IN99 = General purpose

*inlr = *on;

While modern RPG prefers named indicator variables, numbered indicators remain common in legacy code.

Embedded SQL

One of RPG IV’s most powerful features is embedded SQL for DB2 for i:

**FREE
dcl-s custName varchar(100);

exec sql
  SELECT name INTO :custName
  FROM customers
  WHERE id = 1001;

if sqlcode = 0;
  dsply custName;
else;
  dsply 'Customer not found';
endif;

*inlr = *on;

The :custName syntax (colon prefix) indicates a host variable - an RPG variable used within SQL.

Historical Context

RPG was developed at IBM around 1959 for the IBM 1401 computer. The language was deliberately designed so that operators familiar with wiring tabulating machine plugboards could transition to programming electronic computers. Its specification-based format, indicators, and program cycle all reflect this heritage.

Over six decades and multiple hardware generations (IBM 1401, System/3, System/38, AS/400, iSeries, IBM i), RPG has continuously evolved while maintaining backward compatibility. A fixed-format RPG II program from the 1970s can still compile on a modern IBM i system.

Today, RPG remains critical to global business infrastructure. According to the 2023 Fortra IBM i Marketplace Report, approximately 89% of IBM i shops use RPG for new development.

Key Takeaways

  1. **FREE enables fully free-form syntax (no column restrictions)
  2. dsply displays a message on IBM i
  3. *inlr = *on is the traditional way to end an RPG program
  4. RPG is case-insensitive and statements end with semicolons
  5. RPG runs exclusively on IBM i - no Docker or cross-platform compiler exists
  6. Modern free-form RPG looks very different from its fixed-format ancestors
  7. Built-in functions use the % prefix (e.g., %trim, %date, %char)
Last updated: