• The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
Menu
  • The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
  • Guru: Enumerated Data Types In RPG

    September 16, 2019 Ted Holt

    IT has changed a lot since I entered the field several decades ago, but some things have not changed. I would read in those early days that COBOL was dead, and I read the same thing now. Yet COBOL is 60 years old and still going strong. Back then I heard RPG criticized as “Real Poor Garbage”. These days I hear it scorned as “legacy”, which I assume is supposed to mean the same thing. Yet today’s RPG is better than any of its predecessors for business programming.

    RPG supposedly does not have the features of modern languages. Maybe not, but I have found that I can make RPG do what I need it to do anyway. One example is enumerated data types.

    An enumerated type is a data type with a restricted set of allowable values. They are wonderful because they preclude the option of assigning an invalid value to a variable. Currently hot languages like JavaScript, C# and Python support them, but they’re not new. I used enumerated types in Pascal in my university days. To learn more about enumerated types and see some examples, visit Wikipedia.

    RPG has no special syntax for enumerated types, but the existing syntax works quite well. Here’s how it’s done.

    Let’s say that we have a program that calls a subprocedure to process a batch of transactions of some sort. The subprocedure can operate in one of three modes:

    • It can validate the data, i.e. check the data for errors.
    • It can validate the data and post the data if it passes validation.
    • It can skip validation and post the data.

    Such a subprocedure would probably be part of a service program, but to simplify my example, I make it an internal subprocedure.

    The subprocedure returns a status code to report the result to the caller. Possible status codes are:

    • The subprocedure executed without error.
    • The subprocedure executed, but had to make some assumptions, and therefore generated one or more warning messages.
    • The subprocedure found an error condition.

    Here’s a copybook in which these data types are defined.

    **free
    dcl-s  Action_t       char(2)   template;
    dcl-c  Validate          'V ';
    dcl-c  Post              'P ';
    dcl-c  ValidateAndPost   'VP';
    
    dcl-s  RunStatus_t    packed(1) template;
    dcl-c  SuccessfulRun     0;
    dcl-c  RunWithWarning    1;
    dcl-c  RunFailed         2;
    

    I’ve defined two datatypes: Action_t and RunStatus_t. I like to end the datatype names with _t. Notice the TEMPLATE keyword on each declaration to prevent the compiler from allocating memory.

    For each datatype, I’ve defined a set of allowable values as constants. Since RPG is not case-sensitive, I prefer to make constants look like any other type of identifier.

    Any source member that includes this copybook can define variables and functions of these data types.

    Here’s an example caller:

    **free
    /include copybooks,DataTypes
    
    dcl-s  Stat          like(RunStatus_t);
    dcl-s  BatchNumber   packed(3);
    
    Stat = ProcessBatch (BatchNumber: ValidateAndPost);
    
    if Stat = RunFailed;
          // do something to handle the error
    endif;
    
    
    dcl-proc  ProcessBatch;
    
      dcl-pi  ProcessBatch      like(RunStatus_t);
         inBatch   packed(3)        const;
         inAction  like(Action_t)   const;
      end-pi;
    
      if (inAction = Validate
      or  inAction = ValidateAndPost);
         // calcs to validate the data
         if . . . some error condition . . .
            return RunFailed;
         endif;
      endif;
    
      if (inAction = Post
      or  inAction = ValidateAndPost);
         // calcs to post the data
         if . . . some error condition . . .
            return RunFailed;
         endif;
      endif;
    
      return SuccessfulRun;
    
    end-proc;
    

    Notice the variable, function, and function parameter that are defined with these data types.

    dcl-s  Stat          like(RunStatus_t);
    dcl-pi  ProcessBatch      like(RunStatus_t);
    inAction  like(Action_t)   const;
    

    The compiler would not prevent me from assigning literals or comparing to literals, but I never do. I always refer to the constants.

    return SuccessfulRun;
    if Stat = RunFailed;
    

    One last point I’d like to make is that I can truly use these template variables as if they were real data types, at least in most cases. For instance, I can use one of the constants in the INZ keyword.

    dcl-s Stat like(RunStatus_t) inz(RunFailed);
    

    This is not foolproof. The compiler won’t stop me from assigning an invalid value to a variable or assigning a literal for one type to a variable of another compatible type. Avoiding such errors is a matter of discipline, but it’s not an egregious task, and usually the errors stick out like a sore thumb. For example, this looks reasonable:

    Color = Blue;
    

    But this does not:

    Color = RunFailed;
    

    The newer languages certainly have their place, but that doesn’t mean that we should dump RPG overnight under the theory that anything new has to be better than anything old. RPG is an effective business programming language, and believe it or not, can do a lot that some critics say it can’t do.

    RELATED RESOURCE

    Wikipedia – Enumerated type

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    Tags: Tags: 400guru, C, COBOL, FHG, Four Hundred Guru, IBM i, JavaScript, Python, RPG

    Sponsored by
    Raz-Lee Security

    Protect Your IBM i and/or AIX Servers with a Free Virus Scan

    Cyber threats are a reality for every platform, including IBM i and AIX servers. No system is immune, and the best defense is prompt detection and removal of viruses to prevent costly damage. Regulatory standards across industries mandate antivirus protection – ensure your systems are compliant and secure.

    Get My Free Virus Scan

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    Unperspective: In Your Face New System z15 Mainframe Takes The Heat Off Power Systems

    3 thoughts on “Guru: Enumerated Data Types In RPG”

    • Jim Mitchell says:
      September 16, 2019 at 11:03 am

      Interesting article, Ted.

      It would not be difficult to check within the subprocedure to ensure the input variable contains one of those numerated values and return, say -1, if not. Thus strengthening the association of the enumerated list with the template variable.

      I’d love to see the Compiler offer a mechanism for enumerated values of a variable; or DB2 for that matter.

      IBM has ‘toyed’ with the idea from way back; as with the VALUES keyword in DDS.

      IBM has certainly brought RPG a long way to becoming truly competitive with other modern languages, that’s for sure! But there remains some challenges to be met.

      Thank you for your advocacy with thoughts such as this one.

      Reply
    • Jose Walker says:
      September 24, 2019 at 10:10 am

      Hello Ted.

      I use this DS:
      //
      D Task DS qualified
      D FillSFL 2s 0 inz(96)
      D Error 2s 0 inz(97)
      D BackPgm 2s 0 inz(98)
      D ExitPgm 2s 0 inz(99)
      D Init 2s 0 inz(0)
      D Continue 2s 0 inz(1)
      D Find 2s 0 inz(10)
      D GetData 2s 0 inz(20)
      D ShowSFL 2s 0 inz(30)
      D Print 2s 0 inz(40)
      D Selected 2s 0 inz(50)

      You can use RDI/WSDC autocomplete like: Task.Find

      Best Regards,
      Jose

      Reply
    • Barbara Morris says:
      November 8, 2021 at 12:55 pm

      There is an RFE requesting a “real” enumerated data type for RPG. http://www.ibm.com/developerworks/rfe/execute?use_case=viewRfe&CR_ID=145920.

      One of the comments has some information from IBM about what it might look like for RPG. The “typed enum” form would probably involve restrictions on what could be assigned to a variable defined LIKE(theEnum) or passed to a parameter prototyped with LIKE(theEnum).

      Reply

    Leave a Reply Cancel reply

TFH Volume: 29 Issue: 51

This Issue Sponsored By

  • Profound Logic Software
  • New Generation Software
  • ARCAD Software
  • Computer Keyes
  • WorksRight Software

Table of Contents

  • IBM Lab Services: Your IBM i All-Star Team
  • New System z15 Mainframe Takes The Heat Off Power Systems
  • Guru: Enumerated Data Types In RPG
  • Unperspective: In Your Face
  • Maxava Hits Multiple Targets With The Same HA Arrow

Content archive

  • The Four Hundred
  • Four Hundred Stuff
  • Four Hundred Guru

Recent Posts

  • POWERUp 2025 –Your Source For IBM i 7.6 Information
  • Maxava Consulting Services Does More Than HA/DR Project Management – A Lot More
  • Guru: Creating An SQL Stored Procedure That Returns A Result Set
  • As I See It: At Any Cost
  • IBM i PTF Guide, Volume 27, Number 19
  • IBM Unveils Manzan, A New Open Source Event Monitor For IBM i
  • Say Goodbye To Downtime: Update Your Database Without Taking Your Business Offline
  • i-Rays Brings Observability To IBM i Performance Problems
  • Another Non-TR “Technology Refresh” Happens With IBM i TR6
  • IBM i PTF Guide, Volume 27, Number 18

Subscribe

To get news from IT Jungle sent to your inbox every week, subscribe to our newsletter.

Pages

  • About Us
  • Contact
  • Contributors
  • Four Hundred Monitor
  • IBM i PTF Guide
  • Media Kit
  • Subscribe

Search

Copyright © 2025 IT Jungle