%LEFT and %RIGHT Built-in Functions

Bad Joke of the Month:

A friend went Axe Throwing.  I asked if she ever tried it blind folded. She replied, “No.” so I said “You don’t know what you’re missing!”

%LEFT and %RIGHT Built-in Functions

On October 10, IBM announced the latest RPG features. Among the new features were the %LEFT and %RIGHT built-in functions for RPG. They will be available via PTFs for IBM i 7.4 and 7.5, but the PTFs have not been published yet. They will be included at GA for future releases.  To watch for the PTF announcements, check here:


The %LEFT and %RIGHT functions are simplified versions of the %SUBST function that we’ve always had. They don’t really offer any new functionality, but they make our lives easier as programmers – and that’s something I certainly appreciate!


The %LEFT built-in function takes a substring of the leftmost portion of a character variable.  For example:

dcl-s leftChars varchar(50);


leftChars = %LEFT(‘abcdefg’: 3);

// leftChars = ‘abc’

The parameters to %LEFT are the string that you wish to take the leftmost characters of, and the length of characters (or bytes, see below) to take. The first parameter can be a literal string (as shown above) or it can be a variable in char, varchar, ucs2 or varucs2 format.
For example:

dcl-s fullName varchar(30) inz(‘Scott Klement’);

dcl-s firstName varchar(15);

firstName = %left(fullName: 5);

Of course, the obvious problem with that example is that it hard-codes the number 5, and people have different length names.  Thankfully, you can use expressions for the parameters to %LEFT as well, so you could do this:

dcl-s fullName varchar(30) inz(‘Scott Klement’);

dcl-s firstName varchar(15);


firstName = %left(fullName: %scan(‘ ‘: fullName) 1);

If you’ve been watching the new features that IBM has added to RPG over the last year, you’ll know that the length of data passed to functions such as %SUBST and %SCAN is measured in the number of characters when working with EBCDIC data or with UTF-16/UCS-2 data. However, when working with UTF-8, it frustratingly substrings based on the number of bytes.

That’s why in last autumn’s updates, IBM introduced the natural character count feature, that lets UTF-8 substrings also work as a number of characters. I won’t explain that feature in-depth here, since it isn’t new – but I want to let you know that it also works with the %LEFT and %RIGHT functions, just as it does with the others.

ddcl-s string varchar(10) ccsid(*utf8) inz(‘ábçdë’);

dcl-s leftChars varchar(10) ccsid(*utf8);


leftChars = %left(string: 3);


// leftChars = ‘áb’

In this case, we only get two letters (‘áb’) because the á character occupies two bytes, and since *utf8 character strings are measured in bytes by default, the leftmost 3 bytes will only return two characters.  Like all of the other string functions, you can use natural character mode to overcome this.

dcl-s string varchar(10) ccsid(*utf8) inz(‘ábçdë’);

dcl-s leftChars varchar(10) ccsid(*utf8);


leftChars = %left(string: 3: *natural);

// leftChars = ‘ábç’

The other ways of invoking natural character count mode work
as well – but for brevity I won’t explain them all – instead, look at the examples
IBM provided last year, and just remember that the %SUBST examples also apply
to %LEFT and %RIGHT.


As you would suspect, the %RIGHT built-in function works the same way as %LEFT, except that it takes characters from the rightmost portion of the string rather than the leftmost portion.  That said, I personally find it to be a bigger time saver than %LEFT is.

For example, observe what I would need to do to take the leftmost 5 characters of a string prior to this update:

dcl-s fullName varchar(30) inz(‘Scott Klement’);

dcl-s firstName varchar(15);

firstName = %subst(fullName: 1: 5);

That’s not much more work than using %LEFT – I just have to provide the starting position, which would be always be 1…  so very easy.

Compare taking the rightmost 7 positions prior to this update:

dcl-s lastname  varchar(15);

dcl-s len       int(10);


len = 7;
lastname = %subst(fullName: %len(%trimr(fullName)) (len 1): len);

That’s quite a bit uglier, isn’t it?  You could omit the %TRIMR function if you know you have a variable length string that won’t have trailing blanks in it, but even without that function, it’s still not very pretty.

With the new %RIGHT function, it’s much nicer:

lastName = %right(fullName: 7);

Or if the length is in a variable like the previous example:

len = 7;

lastName = %right(fullName: len);

All of the features of %LEFT also apply to %RIGHT, including natural character counts and expressions. These will be a very welcome addition to the language!

Scott Klement

Scott Klement
Midrange Dynamics
Development & Solutions Architect

Scott Klement is an IT professional with a passion for both programming and mentoring. He joined Midrange Dynamics at the beginning of October 2022. He formerly was the Director of Product Development and Support at Profound Logic and the IT Manager and Senior Programmer at Klement’s Sausage

Co., Inc. Scott also serves on the Board of Directors of COMMON, where he represents the Education, Innovation, and Certification teams. He is an IBM Champion for Power Systems.

Subscribe to our newsletter and join us next month to see what is happening in Scott’s Corner. Add a great dad joke to your arsenal and gain an even better IT insight from this recognized industry expert as he continues his quest to educate and support the IBM i community.

Similar Posts