Rex Introduction

by "Blag" - Senior Developer Evangelist

Return to Geeky Thursday

What is Rexx?


Rexx (Restructured Extended Executor).


Interpreted programming language developed at IBM by Mike Cowlishaw on 1979.


Multiparadigm, procedural, structured.


Scripting and Macro Language.

How to install Rexx?


On Linux, the easy way is to do this


sudo apt-get install -y regina-rexx


For other platforms...


Go here.

We can call it like this

regina name_of_file.rexx


Rexx doesn't have a REPL...

Who uses Rexx?


It was used by mostly every single Mainframe...


It's also considered the first widely used Scripting Language...


Not many people might use it...but Rexx is there...


Starting out...


As I mentioned...Rexx doesn't have a REPL...so we need to create a file to call from the compiler


We can use the .rexx extension

Basic Concepts


Printing on the screen is easy...

We have one way to make comments...

				
say 'This is Rexx'



/*This is a Rexx comment*/



/* This is a multi-line

comment */
				

Arrays are easy...wait...there's no Arrays...


				
number.1 = 1; number.2 = 2; number.3 = 3


do i = 1 to 3

    say number.i

end


/*

1

2

3

*/
				

In Rexx, we call them "Compounds"...

More on Compounds

				
person.1.name = 'Blag'

person.1.age = 43


person.2.name = 'Milly'

person.2.age = 39


do i = 1 to 2

    say person.i.name person.i.age

end


/*Blag 43

  Milly 39*/
				

Looping


We have plenty of options when it comes to loops...


				
do i = 1 to 6 by 2

    say i

end


/*1

  3

  5*/
				
				
i = 1


do while(i <= 3)

    say i

    i = i + 1

end



/*1

  2

  3*/
				
				
i = 1

do until(i = 4)

    say i

    i = i + 1

end



/*1

  2

  3*/
				

Functions/Subroutines


Functions need to return a value, Subroutines don't need to return anything...


But Subroutines still need to use the "Return" keyword...


A Function need to have an exit after being called...


				
call sum 5, 6

say result

call another_sum 10, 6

exit


another_sum: /*Subroutine*/

    arg a, b

    say a + b

    return


sum: /*Function*/

    arg a, b

    return a + b
    
    
/* 11

   16 */
				

String Manipulation


If you thought that SNOBOL was good for Text Processing...you haven't seen Rexx in action...


				
string = 'This is a string'

say length(string) /* 16 */

say reverse(string) /* gnirts a si sihT */

say right(string,6) /* string */

say pos('string',string) /* 11 */

say insert('Rexx ', string, 10) /* This is a Rexx string */

say datatype(string) /* CHAR */

say copies('Rexx', 3) /* RexxRexxRexx */
  		

The External Data Queue, or "Stack"


If you have used either Forth, Factor or Joy the you know what the "Stack" is...otherwise...


Pretty much is a space on memory where you can store information using LIFO (Last In, First Out) or FIFO (First In, First Out)


Let's see a couple of examples...


LIFO (Last In, First Out)


				
do i = 1 to 3

    push 'Value' i

end


do i = 1 to 3

    pull line

    say line

end


/* Value 3

   Value 2

   Value 1*/
				

FIFO (First In, First Out)


				
do i = 1 to 3

    queue 'Value' i

end


do i = 1 to 3

    pull line

    say line

end


/* Value 1

   Value 2

   Value 3*/
				

Fibonacci List


Finally...we're going to make our first application...


So grab your favorite text editor and get ready...


Name your file "fibonacci.rexx"


				
say "Enter a number: "

pull number .

say ""

call fibo number, 0, 1

say

exit 0
				
				
if a = 0 then

    do

        a_b = a + b

        call charout, (a b a_b)

        call charout, " "

        call fibo num - 1, a + b, b

    end

else if a > 0 & num > 1 then

   do

        a_b = a + b

        call charout, a_b

        call charout, " "

        call fibo num - 1, a + b, a

    end

return
				

Open the Terminal and go to your source code folder...

regina "Name_of_File.rexx"


When we run it we're going to see...


Making an LED Number App


This is one of my favorite codes of all time...


Name your file "LED_Numbers.rexx"


				
led.0 = '';

led.0.1 = ' _  ';led.0.2 = '| | ';led.0.3 = '|_| '

led.1 = '';

led.1.1 = '    ';led.1.2 = '|   ';led.1.3 = '|   '

led.2 = '';

led.2.1 = ' _  ';led.2.2 = ' _| ';led.2.3 = '|_  '

led.3 = '';

led.3.1 = ' _  ';led.3.2 = ' _| ';led.3.3 = ' _| '

led.4 = '';

led.4.1 = '    ';led.4.2 = '|_| ';led.4.3 = '  | '

led.5 = '';

led.5.1 = ' _  ';led.5.2 = '|_  ';led.5.3 = ' _| '

led.6 = '';

led.6.1 = ' _  ';led.6.2 = '|_  ';led.6.3 = '|_| '
				
				
led.7 = '';

led.7.1 = ' _  ';led.7.2 = '  | ';led.7.3 = '  | '

led.8 = '';

led.8.1 = ' _  ';led.8.2 = '|_| ';led.8.3 = '|_| '

led.9 = '';

led.9.1 = ' _  ';led.9.2 = '|_| ';led.9.3 = ' _| '



say "Enter a number: "

pull number .



i = 1

line_1 = ''

line_2 = ''

line_3 = ''				
				
do while i <= length(number)

    num = substr(number,i,1)

    i = i + 1

    line_1 = line_1 || led.num.1

    line_2 = line_2 || led.num.2

    line_3 = line_3 || led.num.3

end



say line_1

say line_2

say line_3
				

When we run it we're going to see...


Random Names


This App will generate 100,000 random names using two 16 elements arrays


We will measure the runtime


Name your file "Random_Names.rexx"


				
names.1 = 'Anne'; names.2 = 'Gigi'; names.3 = 'Blag'

names.4 = 'Juergen'; names.5 = 'Marek'

names.6 = 'Ingo'; names.7 = 'Lars'; names.8 = 'Julia'

names.9 = 'Danielle'; names.10 = 'Rocky'

names.11 = 'Julien'; names.12 = 'Uwe'; 

names.13 = 'Myles'; names.14 = 'Mike'; 

names.15 = 'Steven'; names.16 = 'Fanny'
				
				
last_names.1 = 'Hardy'; last_names.2 = 'Read'

last_names.3 = 'Tejada'; last_names.4 = 'Schmerder'; 

last_names.5 = 'Kowalkiewicz'; 

last_names.6 = 'Sauerzapf'; last_names.7 = 'Karg'; 

last_names.8 = 'Satsuta'; last_names.9 = 'Keene'; 

last_names.10 = 'Ongkowidjojo'; 

last_names.11 = 'Vayssiere'; last_names.12 = 'Kylau'; 

last_names.13 = 'Fenlon'; last_names.14 = 'Flynn'; 

last_names.15 = 'Taylor'; last_names.16 = 'Tan'
			
				
call time 'Reset'


do i = 1 to 100000

    r_names = random(1,16)

    r_last_names = random(1,16)

    full_names.i = names.r_names || " " 

                   || last_names.r_last_names

end


say 'It took' format(time("E"),,2) 

    'seconds to process 100000 elements'
			

When we run it we're going to see...

How this behaves in Python?

And what about Go?

Decimal to Romans


This App will create a Roman Numeral based on a decimal number


This will include some nice commands...


Name your file "Decimal_to_Roman.rexx"


				
keys.0 = 0

keys.1 = 1000; keys.2 = 900; keys.3 = 500; 

keys.4 = 400; keys.5 = 100; keys.6 = 90; 

keys.7 = 50; keys.8 = 40; keys.9 = 10; 

keys.10 = 9; keys.11 = 5; keys.12 = 4

keys.13 = 1


values.0 = ''

values.1 = 'M'; values.2 = 'CM'; values.3 = 'D'; 

values.4 = 'CD'; values.5 = 'C'; values.6 = 'XC'; 

values.7 = 'L'; values.8 = 'XL'; values.9 = 'X'; 

values.10 = 'IX'; values.11 = 'V'; values.12 = 'IV'

values.13 = 'I'
			
				
result = ""


say "Enter a number: "

pull number .


do while number > 0

    counter = 1

        do i = 1 to 13

            if number >= keys.i then

                do

                    result = result || values.counter

                    number = number - keys.i

                    leave

                end
			
				
            counter = counter + 1

        end

end


say result
				

When we run it we're going to see...


Count Letters


In this example we're going to read a file and count how many time a letter appears...


Call your file "count_letters.rexx" (all in lowercase).


Create a file called "readme.txt" with the following text...


"This is a text file that we're going to read using Rexx"


				
i = 1

letter = ""


filein = "readme.txt"

input_line = linein(filein)


do while i <= length(input_line)
    
    letters.i = ''
    
    letters.i.1 = 0
    
    i = i + 1
end


i = 1
				
				
do while i <= length(input_line)

    letter = substr(input_line,i,1)

    j = 1

    do while j <= length(input_line)

        if letters.j = '' then

            do

                letters.j = letter

                letters.j.1 = 1

                leave

            end
				
				
        else
            
            if letters.j = letter then
			
                do
			
                    letters.j.1 = letters.j.1 + 1
			
                    leave
			
                end
			
            else
			
                j = j + 1
	
    end
	
    i = i + 1

end
				
				
i = 1

do while i <= length(input_line)

    if letters.i.1 > 0 then

        say letters.i "-->" letters.i.1		

        i = i + 1

end
				

When we run it we're going to see...


Why use the Queue, or "Stack"


In our Decimal to Romans example, you may have noticed that we didn't used Functions need to return a value, Subroutines don't need to return anything...or Subroutines.

And that's simply because Compounds cannot be passed as parameters...
But...if we use either the Queue or the Stack then we can...

it's a bit tricky but works...

				
keys.0 = 0

keys.1 = 1000; keys.2 = 900; keys.3 = 500; 

keys.4 = 400; keys.5 = 100; keys.6 = 90; 

keys.7 = 50; keys.8 = 40; keys.9 = 10; 

keys.10 = 9; keys.11 = 5; keys.12 = 4

keys.13 = 1


values.0 = ''

values.1 = 'M'; values.2 = 'CM'; values.3 = 'D'; 

values.4 = 'CD'; values.5 = 'C'; values.6 = 'XC'; 

values.7 = 'L'; values.8 = 'XL'; values.9 = 'X'; 

values.10 = 'IX'; values.11 = 'V'; values.12 = 'IV'

values.13 = 'I'
				
				
result = ""


do i = 1 to 13

    queue keys.i

end



do i = 1 to 13

    queue values.i

end




say "Enter a number: "

call romannumber

say result

exit
				
				
romannumber: procedure

result = ""



do i = 1 to 13

    pull line

    i_keys.i = line

end

	

do i = 1 to 13

    pull line

    i_values.i = line

end	
				
				
pull number .
	
    do while number > 0

        counter = 1

            do i = 1 to 13

                if number >= i_keys.i then

                    do

                        result = result || 
                        
                                 i_values.counter

                        number = number - i_keys.i

                        leave

                    end

                counter = counter + 1

           end

    end

return result
				

When we run it we're going to see...


That's it for now


Rexx is old but full of surprises


It can interact with Databases, use graphic interfaces...


and can be even used for Web Development...


Go ahead an explore!

Contact Information


Blag --> blag@blagarts.com

@Blag on Twitter

Go back home...