Python from a COBOL perspective
Some years ago, Gavin Scott ported Python to the HP 3000. An Object Oriented scripting language authored by Guido van Rossum, Python was being done in his (and his teams) spare time while they worked their normal jobs. In May, the core team was hired by BeOpen.com to strictly develop Python, which has lead to the current 2.0 release in early October (a pretty major upgrade). Lets hope that someone ports this 2.0 release to MPE/iX.
My new company is making a big investment in time on Python as a desktop and application scripting language, and is putting in debugging and visual designers and such. So I thought that since we were spending all this time on Python, I should probably learn it, at least a bit. I have to say that Python is really the most interesting language Ive looked at in some time, and will probably be the last language I ever learn (crossing my fingers). Python runs on just about every platform you care to name, and there are also environments for Windows so if you wish to go that route, see the resources Ive included at the end of this column.
Im not going to get into a huge dissertation trying to teach you the language, but I want to illustrate some features that are very cool, and compare them to COBOL so you can get a feel for what Python can do compared to COBOL. Remember, Python is Object Oriented, so we can quickly get out of the realm of realistic comparisons. Keep in mind Im new to Python, so there might be a couple of details Im still learning about.
Python requires that variables start with a letter or an underscore, nothing else. Variables are also case sensitive (which Ive always hated), and a variable cannot be a reserved word, but there arent that many of those. Variables in Python do not have to be declared beforehand, so you can say:
X = 0 # X is now an integer object
X = Hello # X is now a string object
X = [1, 2, 3] # X is now a list object (well cover this more later)
In this case, X is changing its type each time. In COBOL these would have to be three separate variables, and they would have to be declared before use, such as:
01 X PIC S9(4) COMP VALUE 0.
One of the things I really love about Python is its ability to work with strings. Let me describe some of its variable types that are going to be unusual to you before I get into describing some of its string functions.
First there are Lists. Lists are essentially tables, but they are really collections of arbitrary objects. You dont have to specify the variable type that is in a List, and you can do all sorts of fun things with them. A List is specified by using ; for example:
L1 = [ ] #Creates an empty
As we illustrated earlier, a List in Python would be a table declaration with OCCURS in COBOL, and you also cant assign values to table members during variable declaration. Now if you want to add to the list, you would say L1.append(shawn) to write to the end of our list. We can sort it with L1.sort(), reverse the order L1.reverse(), we can loop through it with:
for x in L1
This will produce: 1 ABC DEF 2 3 shawn
In COBOL, if the table has been declared with 10 members, and you want to add an eleventh, you are flat out of luck unless you have declared a larger table somewhere that you can move your contents to. There is absolutely no way to do dynamic variable declaration in COBOL. We have covered bubble sorts in COBOL in a previous column, so you already know that it requires at least five lines of code and a couple of extra variables to sort a table (although the COBOL 2002 standard is supposed to include this as a function). You can, however, reverse a string in COBOL using the functions that are part of the 89 addendum, as in MOVE FUNCTION REVERSE(MY-VAR) TO MY-VAR.
What is also interesting in Python is that the indentation is important. We indented the print statement from the for statement, and this caused it to be part of the condition. If the next line is also indented, it would also be part of the condition; if it is not indented, then the condition block is done. There are no end statements or periods or curly braces to indicate scope. This forces you to make your code a bit more readable. Some people balk at this feature, but I rather like it. I could have done the above as: for x in L1: print x
So now lets talk a bit about strings. Consider the following:
A = Shawn
You essentially get native operator overloading, so you can use some standard math operators on strings you can get a repeating string by using * for example. The above example can be done pretty simply in COBOL with the STRING statement, as in STRING VAR1 VAR2 DELIMITED BY SIZE INTO VAR3. The downside to this is the DELIMITED BY. If we use the SIZE parameter, then it will string the entire length of the string; if you only have four characters in a 10-character string, then you will have six spaces between the words in your new string. You can solve this by saying DELIMITED BY SPACES; however, if there is a space in your variable, then the second word will be cut out. So unless you really know what is in your data, youve got trouble. Im hoping this gets solved in the 2002 standard.
Some other neat examples of functions for strings:
string.capwords(now is the time)
Now Is The Time
string.count(now is the time, i)
string.replace(now is the time, , _)
String.split(now is the time)
[now, is, the, time]
What is interesting to note here is that a list has been returned that is a dynamic array containing each of the words in the phrase, automatically tokenized by the white space. I absolutely love this feature. You dont have to try and create a table first that will hold everything, and you have one quick command to parse out your words into an ordered table.
Lets look at how we would do this in COBOL. We can fake out a couple of the COBOL functions to get what we want:
MOVE FUNCTION UPPER-CASE(VAR1(1:1) TO VAR1(1:1).
This will upshift the first character of a string. For the .capwords function you would need to actually loop one character through the string at a time, and use the above syntax on each byte that was non-blank after the last byte was a blank, at least five lines of code. To continue our comparison:
INSPECT VAR1 TALLYING SUB1 FOR ALL i.
Assuming SUB1 is defined as an integer, this will assign a number equal to the number of is in the string.
INSPECT VAR1 REPLACING ALL BY _.
UNSTRING VAR1 DELIMITED BY INTO VAR2 VAR3 VAR4 VAR5.
As you can see in the case of UNSTRING, you have to know how many variables to unstring into. Usually I set up more than I know I will ever need for this kind of case. But you can see that some of the functions in Python are pretty easy to reproduce in COBOL, but others are a good bit harder.
There are functions to center, right justify, left justify, strip spaces, swap the case of the letters, and others. Doing any of this in COBOL is a real pain, and its something Ive been suggesting to the COBOL committee for years that they change.
This was just a high-level quick overview, which hopefully piqued your interest a bit. Heres some links to find out more:
www.jpython.org (Python written and deployable in Java);
and finally, linux.com/development/newsitem.phtml?sid=64&aid=10564 (an excellent getting started paper.)
Shawn Gordon, whose S.M. Gordon & Associates firm supplies HP 3000 utilities, has worked with 3000s since 1983.
Copyright The 3000 NewsWire. All rights reserved.