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:
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:
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:
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
Post a Comment