• The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
Menu
  • The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
  • Use Named Constants to Write Clearer Code

    August 18, 2004 Ted Holt

    You’d expect experienced programmers to know and use techniques that less experienced programmers might not know. But even programmers with little experience know how to define named constants in one or more languages, although they may not know how to use them effectively. Yet named constants can contribute so much to program clarity, as I wish to show you now. I use RPG IV to illustrate, since that’s the language I use most often, but the principles apply to any language that supports named constants.

    THE PROBLEM WITH LITERALS

    The purpose of named constants is to avoid using literals, a fact that raises the question, “What’s wrong with literals?” Literals suffer from more than one deficiency.

    For one, literals are not self-documenting. What does 20 mean in the following statement?

    eval OrdSt = 20
    

    Who knows? When I work on a program with code like this, I have to ask around until I find someone who knows the order status codes. I’d much rather see something like this:

    eval OrdSt = Suspended
    

    Literals are also confusing. Look at the following selected lines of code from an RPG member.

    D MntSls          s              9p 0 dim(12)
    D RgnSls          s              9p 0 dim(12)
    
    eval OrdSt = 12
    
    eval Amt = Amt * 12
    
    if Status = 12
    
    for i = 1 to 12
    

    There are six instances of the literal 12 in this example. Do they all mean the same thing? If one of them has to be changed, do any or all of the others have to be changed as well? I don’t know. To be sure I modify the program correctly, I have to take time to examine all of them. I have to determine the purpose of each one, because changing a literal that should not be changed, or failing to change a literal that should be changed, could cause problems.

    HOW TO CODE NAMED CONSTANTS

    In the RPG IV language, constants are defined in definition specs. They are distinguished from other data definitions by the letter C in position 24 (definition type), and a constant value in positions 44 through 80 (keywords). In the keyword section, you may code the constant value by itself or as a parameter of the CONST keyword, as the following two definitions illustrate.

    D NbrOfRegions    c                   const(12)
    D NbrOfRegions    c                   12
    

    GOOD USE OF CONSTANTS

    Keep these principles in mind when using literals and named constants.

    • A constant’s name should reflect function, not value.

    • A numeric literal other than 0 or 1 is a good candidate for conversion to a named constant.

    • A literal that represents a special value, such as a code, probably should be converted to a named constant.

    • A literal intended for humans, such as an error message, probably does not need to be converted to a constant.

    Let me discuss these principles in more detail.

    A constant’s name should reflect function, not value.

    Look at the following RPG calculation.

    eval QtyDue = TotQty / 5
    

    You could replace the literal 5 with a named constant FIVE.

    D FIVE            c                   const(5)
    
    eval QtyDue = TotQty / FIVE
    

    You’ve replaced the literal 5 with a named constant, but the code is no more understandable than it was. Not only that, you’ve introduced another problem.

    Let’s assume that the value 5 in this example indicates the number of working days in a week. What are you going to do when your organization decides to produce product on Saturday as well? Well, you could change the value of the named constant.

    D FIVE            c                   const(6)
    
    eval QtyDue = TotQty / FIVE
    

    Isn’t that a beauty? The program will work correctly, but doesn’t something about it bother you?

    Instead of basing the constant’s name on its value, base the name on its function. I suggest the name WorkDaysPerWeek would be more appropriate.

    D WorkDaysPerWeek...
    D                 c                   const(5)
    
    eval QtyDue = TotQty / WorkDaysPerWeek
    

    A numeric literal other than 0 or 1 is a very good candidate for conversion to a named constant.

    The literal 1 is often used for counting.

    eval CompletedOrders += 1
    
    eval LineNbr = LineNbr + 1
    

    The literal 0 is often used in numeric comparisons and for resetting the value of a numeric variable.

    eval  TotalSales = 0
    
    if TotalSales > 0
    
    if AmtDue <= 0
    

    In such cases, use of literal 0 and 1 is fine, although I prefer the predefined constant *ZERO or *ZEROS instead of the character 0.

    eval  TotalSales = *zero
    
    if TotalSales > *zero
    
    if AmtDue <= *zero
    

    The same could be said for other literals that are not likely to change. Here weight in pounds is converted to kilograms.

    eval (h) MetricWeight = Weight / 2.2046
    

    You could replace the value 2.2046 with a named constant, but it wouldn’t buy you much. The fact that the ratio of kilograms to pounds will never change supports the idea of leaving it alone. The idea of readability suggests that a named constant called PoundsPerKilogram makes for more readable code. If this conversion factor is frequently used, including it among the source lines in a copybook member of named constants would be another good reason to create a named constant. The bottom line is that you can make a good case for changing it or leaving it alone.

    But as a rule, numbers other than 0 and 1 are suspect. Here’s some code that contains a number other than 0 or 1, the number 8.

    D RgnSls          s              9p 0 dim(8)
    
    if Regn >= 1 and Regn <= 8
    
    for x = 1 to 8
    

    It is possible that someone might someday redimension the array to 9 elements without changing the test or the for loop limit. Using a named constant ensures that redimensioning the array won’t affect the intention of the program.

    D NbrOfRegions    c                   8
    D RgnSls          s              9p 0 dim(NbrOfRegions)
    
    if Regn >= 1 and Regn <= NbrOfRegions
    
    for x = 1 to NbrOfRegions
    

    A literal that represents a special value, such as a code, probably should be converted to a named constant.

    Databases are full of code values. I guess they always have been, since there wasn’t a lot of extra room on 80-column punched cards. Codes are wonderful, not only because they conserve disk space but also because they’re less error-prone. It’s much easier to misspell accounts receivable than 1000.

    But codes are cryptic, and thus make programs harder to read. As a rule, you should define named constants that describe code values and use the named constants in source programs. You might want to place codes in copybook members so that you can include them at run time with the /COPY or /INCLUDE compiler directives. Here is an example of what I’m talking about.

    D Open            c                   0
    D Suspended       c                   1
    D Closed          c                   2
    D Posted          c                   3
    
    if   BatchStatus = Open
    
    eval BatchStatus = Posted
    
    

    Notice that two of the status code values are 0 and 1, which, as I said earlier, do not always need to be converted to named constants. In this case, they serve as code values and therefore do need to be represented by named constants.

    Codes are not found just in databases. OS/400 APIs often include special values, many of them in four-byte binary values. The p-values used to set attributes in display files are one-byte hexadecimal values that are much more readable as constants. When you get in the habit of questioning the use of any literal, you will see more and more places to use named constants.

    Besides readability, named constants offer another advantage over literals. Suppose you decide to add another status code for deleted batches. You need to define the new status code in one place: the copy member. All programs that use the batch status field gain access to the new status code upon recompilation.

    Or suppose you need to reassign the codes. You would have to change the copybook, recompile the programs that use the copybook, modify code that cannot take advantage of named constants (such as an OPNQRYF command in a CL procedure), and update the codes in the database to their new values.

    A literal intended for humans, such as an error message, probably does not need to be converted to a constant.

    Converting the following literal to a named constant is probably of no advantage.

    eval   ErrMsg = 'Invalid customer number'
    

    But even these literals are worthy of a second look. Instead of using literals, perhaps you should be using another technique, such as message descriptions.

    If you’d like to see a program that makes good use of named constants, take a look at Alex Nubla’s FTP request-validation program.

    NAMING CONVENTIONS

    Many programmers feel the need to distinguish constant names from variable names on sight. It is common to see constant names written with all capital letters in the case-sensitive C language. In his excellent book Code Complete, Steve McConnell suggests appending _c or _C to constant names. If you like that approach, that’s fine, but I have not found it advantageous. After all, what is today a named constant might tomorrow become a variable retrieved from a data area or an entry parameter to the program.

    However, that is not to say that there is no need for a naming convention. It is probably good to develop some convention in order to avoid duplication of names among constants and other identifiers. Customer orders, purchase orders, and employees can all be suspended, but the codes for each entity might be different. It is unlikely that one constant can, or should, serve triple duty. You need three constants, which you might name coSuspended, poSuspended, and empSuspended.

    CLARITY IS IMPORTANT

    I hope this article has challenged you to think about the importance of writing programs with clarity in mind, no matter what language you use. I frequently work on programs and software systems that were written by people who gave no thought to clear code but threw together something to get the job done. The result is that, what should be a four-day job, takes me two weeks. I feel embarrassed to be so unproductive. Maybe that’s one reason why I try so hard to continually improve the quality of the systems I design and the source code I write. Maybe by searching for and implementing better practices, such as the judicious use of named constants, I can make life easier for myself or for other maintenance programmers in days to come.

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    Tags:

    Sponsored by
    WorksRight Software

    Do you need area code information?
    Do you need ZIP Code information?
    Do you need ZIP+4 information?
    Do you need city name information?
    Do you need county information?
    Do you need a nearest dealer locator system?

    We can HELP! We have affordable AS/400 software and data to do all of the above. Whether you need a simple city name retrieval system or a sophisticated CASS postal coding system, we have it for you!

    The ZIP/CITY system is based on 5-digit ZIP Codes. You can retrieve city names, state names, county names, area codes, time zones, latitude, longitude, and more just by knowing the ZIP Code. We supply information on all the latest area code changes. A nearest dealer locator function is also included. ZIP/CITY includes software, data, monthly updates, and unlimited support. The cost is $495 per year.

    PER/ZIP4 is a sophisticated CASS certified postal coding system for assigning ZIP Codes, ZIP+4, carrier route, and delivery point codes. PER/ZIP4 also provides county names and FIPS codes. PER/ZIP4 can be used interactively, in batch, and with callable programs. PER/ZIP4 includes software, data, monthly updates, and unlimited support. The cost is $3,900 for the first year, and $1,950 for renewal.

    Just call us and we’ll arrange for 30 days FREE use of either ZIP/CITY or PER/ZIP4.

    WorksRight Software, Inc.
    Phone: 601-856-8337
    Fax: 601-856-9432
    Email: software@worksright.com
    Website: www.worksright.com

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    Wake Up, Sunrise 2005 Is Almost Here Midrange i5s Versus the iSeries, Revisited

    Leave a Reply Cancel reply

Volume 4, Number 28 -- August 18, 2004
THIS ISSUE
SPONSORED BY:

Advanced Systems Concepts
Guild Companies
COMMON

Table of Contents

  • Use Named Constants to Write Clearer Code
  • Securely Resetting Disabled User Profiles
  • Admin Alert: Searching for Elusive OS/400 Green-Screen Commands

Content archive

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

Recent Posts

  • 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
  • Will The Turbulent Economy Downdraft IBM Systems Or Lift It?
  • How IBM Improved The Database With IBM i 7.6
  • Rocket Celebrates 35th Anniversary As Private Equity Owner Ponders Sale
  • 50 Acres And A Humanoid Robot With An AI Avatar
  • IBM i PTF Guide, Volume 27, Number 17

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