To MAIN or Not to MAIN, That Is the Question: Writing Modern RPG on IBM i


Not all RPG is better in its original Klingon. And for the Star Wars fans—not every line of code needs to growl like a Wookie.

This morning's brew is a Dunkin’ Medium Roast—reliable, straightforward, and exactly what I need to think clearly. Kind of like good code. So let’s talk about one of the cleanest decisions you can make in RPG: whether to use MAIN or go NOMAIN.

It sounds like a simple compiler setting. It’s not. It defines how your code is organized, tested, and reused. If you're serious about writing modern RPG, this choice matters.


Before MAIN and NOMAIN: How RPG Used to Work

In the days before MAIN, RPG programs started executing at the top. No entry point. No structure. Just linear execution—statements ran in the order they appeared, and business logic lived side by side with display logic and data declarations.

Something like this:

A screenshot of a computer program

AI-generated content may be incorrect.Everything was in one block. No reusable pieces. No clear boundaries. This made testing, reusability, and structure tough. The code worked, but it didn’t scale.


Enter Procedures: MAIN and NOMAIN

The introduction of dcl-proc and dcl-pi gave us real modularity. Then came MAIN and NOMAIN—keywords that tell the compiler how to treat the program.

  • MAIN = "This source contains the entry point."
  • NOMAIN = "This source has no entry. Just procedures."

Think of it this way:

  • MAIN is the captain of the ship. It sets the direction.
  • NOMAIN is the crew. Skilled specialists ready to serve.

Using MAIN: For Standalone Programs

Here’s a basic example of a MAIN procedure:

A screen shot of a computer code

AI-generated content may be incorrect.This works great for tools, jobs, and one-off utilities. It gives your program a clear starting point, but still benefits from modular logic.


Using NOMAIN: For Modular Design

Now here’s the same logic built for reuse using NOMAIN:

A computer code with text

AI-generated content may be incorrect.No entry point. No startup logic. Just a procedure waiting to be called. This is the approach you want when:

  • Building service programs
  • Sharing logic between apps
  • Writing unit-testable functions
  • Creating APIs or business rules

It’s focused. It’s clean. It’s modern RPG.


MAIN vs NOMAIN: Use Case Guide

Scenario

Use MAIN

Use NOMAIN

Batch or interactive program

Utility or job that runs directly

Business logic to share or test

REST API handler logic

(wrapper)

(logic)

Unit-testable function library

The best approach? Mix both. A clean MAIN wrapper that calls reusable NOMAIN procedures is modern RPG at its best.


Best Practice

Use NOMAIN as your default. Build your logic into clear, callable pieces. Then, wrap it with a MAIN when you need to execute it directly. That gives you flexibility, testability, and clean architecture.

And if you're modernizing older code—start here. Break the monolith, one procedure at a time.


Final Sip

This morning’s Dunkin’ is almost gone. And just like a good cup of coffee, clean code should leave you feeling sharper, not jittery.

So here’s your takeaway:

“Boldly choose, you must. Clean your code shall be. And always, hot keep your coffee.” – Yoda, probably

Choose structure. Choose reuse.
Write RPG that’s easy to test, easy to share, and built for the future.

Final Sip: Choose boldly. Code clean. And keep your coffee hot.

Comments

Popular Posts