Application Development Blog Posts
Learn and share on deeper, cross technology development topics such as integration and connectivity, automation, cloud extensibility, developing at scale, and security.
cancel
Showing results for 
Search instead for 
Did you mean: 
jwood_bowdark
Active Participant

Last fall, my 10 year old son expressed some interest in learning how to program games. So I, being the CS nerd that I am, was thrilled and immediately went to work trying to find good learning resources to help get him started. Eventually, I settled on a book entitled Hello World! Computer Programming for Kids and Other Beginners (you can read about it here). As the name suggests, this book is geared for kids looking to get started with programming for the first time. Though there are several books out there that purport to do this, I thought there were two things that really set this book apart:

  1. The book is co-authored by the author's 12 year old son. So, you get the insight of a young developer learning how to program for the first time. In particular, the book contains many sidebars which document specific pain points encountered during the learning process.
  2. It uses Python as its language of choice for teaching introductory programming.

Given my natural prejudices when it comes to scripting languages, I was a little skeptical about the selection of Python as a first programming language. What little I had seen of it had given me horrible flashbacks to my days of doing CGI scripting in Perl in the late 1990s. Back then, scripting languages just seemed like controlled chaos: no typed variables, weird and cryptic syntax, and a certain amount of terseness that just went against everything I had ever learned about programming in school. Still, if you look at what the young whippersnappers of this generation are learning in schools, you'll find that scripting languages like Python are towards the top of the list. So either a whole generation of developers has it wrong (probably), or maybe it's me that needs to broaden my horizons. So, I decided we'd give it a shot.

So what's all this got to do with ABAP you might ask? Well, during the course of our journey, I discovered some things about scripting languages in general and Python in particular that really got me to thinking about the way we perform day-to-day tasks using traditional enterprise programming languages such as ABAP and Java. So what follows is an opinion piece which documents some of the lessons I learned while coming up to speed with Python.

Lesson 1: Dynamic Typing Ain't That Bad

Though I've programmed in many languages over the years, Java has always been my first love (sorry ABAP). And it was in Java that I really began to embrace the notion of static typing. If you're not familiar with this concept, then a brief description is in order.

When we talk about types in a programming language, we're talking about artificial constructs which provide an abstraction on top of some section of memory. For example, the primitive int (integer) type in Java carves out 4 bytes in memory to store a 32-bit signed, two's complement integer. Similarly, other data types such as float, double, or char in Java or I, F, P, and C in ABAP map an abstract data type onto a series of bits in memory. To the computer, it's 1's and 0's as usual; to us, we have an intuitive construct which can be used to model the data we encounter in the real world.

As practitioners of a given language, we normally remain blissfully unaware of such bookkeeping, relying on the runtime environment to take care of the low-level bit-twiddling details. Language designers, on the other hand, care about these details a great deal. In particular, they are interested in defining a scheme for determining when and where to apply a particular abstraction (type). Such mapping schemes can be usually classified into two broad categories:

  • Static Typing
    • With static typing, the types of variables must be declared up front at compile time.
    • If a variable is created without a type, a syntax error will occur and the code won't compile.
    • Similarly, if a variable of a given type is statically assigned a value which is outside the boundaries of that type, the compiler will catch that too. Of course, there are limits to what can be checked at compile time. After all, the compiler can't predict how a poorly written loop might cause overflow in a variable assignment, etc.
    • In addition to the efficiencies it offers to compiler implementations, static typing is geared towards preventing developers from hanging themselves with type mismatches and the like.
  • Dynamic Typing
    • With dynamic typing, a variable is not assigned a type until runtime whenever it is first assigned a value.
    • This is made possible by VM/interpreter implementations which are designed to allocate just about everything on the fly.
    • Since there are no compile-time restrictions on type declarations, it is possible that some type mismatch errors won't be caught until runtime.

As you may have guessed, both ABAP and Java employ static typing. So, whenever we define a variable in one of these languages, we must assign it two things:

  • A name
  • A specific type

For example, if we wanted to define a variable to hold a floating point number in Java, we would need to define it using a syntax like the following:

float pi = 3.14159f;

With ABAP, we probably end up with a syntax like this:

DATA pi TYPE p DECIMALS 5.

pi = '3.14159'.

Conversely, the equivalent variable declaration in Python looks like this:

pi = 3.14159

As you can see, Python does not require a type declaration up front. So what, you say? Well, besides saving several keystrokes (or many if it's a complex data structure), the dynamic approach is much more flexible in the long run. For example, think about what would happen if at some point we needed to increase the precision of our PI variable. In the ABAP/Java examples, we would probably have to go back and touch up the code to choose a wider data type. With Python, no code changes are required; the interpreter will simply carve out a larger space in memory as needed.

In his article, Scripting: Higher-Level Programming for the 21st Century, John Ousterhout puts this into perspective: "...scripting languages are designed for gluing: they assume the existence of a set of powerful components and are intended primarily for connecting components together. System programming languages (e.g. C) are strongly typed to help manage complexity, while scripting languages are typeless to simplify connections between components and provide rapid application development."

As I progressed further and further with Python, I found that I didn't really miss the formal type declarations like I thought I would. That's not to say that I didn't encounter a runtime error here or there. But the thing is, I encounter those kinds of issues in my day-to-day ABAP work, too. So, at the end of the day, I had to ask myself a fundamental question: what is static typing truly buying me other than a lot more keystrokes? As much as I have been a strong proponent for static typing over the years, this is a question I found difficult to answer with anything other than "because...".

Lesson 2: Internal Tables Could Use a Facelift

One of the things I like about Python is its rich set of built-in collection types: lists, tuples, sets, and dictionaries. These collection types are quite feature rich and flexible in their use. Sure, you can accomplish all the same things with internal tables in ABAP, but the Python way of doing things is a whole lot easier. From a usage perspective, we have the option of working with these collections in two different ways:

  1. We can perform operations using the rich set of API methods provided with Python collection types just as we would with collection types in Java or (e.g. those in the java.util package).
  2. Python also allows us to perform certain operations on these objects using built-in operators (e.g. [ ], +, etc.).

To put this these advantages into perspective, let's take a look at a side-by-side comparison between ABAP code and Python code. The other day, I was tasked with enhancing a simple workflow report in ABAP that provides statistics about agents assigned to specific workflow items. As I read through the code, I found the selection logic to be pretty typical of most reports:

  1. First, the report fetched the work item information into an internal table.
  2. Then, for each work item record in the internal table, additional information about the assigned agent (e.g. agent name, duty, etc.) was fetched and aggregated into a report output table.

In order to improve performance and avoid the dreaded "SELECT within a LOOP", the developer had built a temporary table which contained the super set of agents assigned to the work items. That way, the agent information only had to be selected once as opposed to over and over again within the loop. From an ABAP perspective, the set generation process looked something like this:


LOOP AT lt_work_items ASSIGNING <ls_work_item>.

  READ TABLE lt_agents ASSIGNING <ls_agent>

        WITH KEY wi_aagent = <ls_work_item>-wi_aagent.

  IF sy-subrc NE 0.

    APPEND INITIAL LINE TO lt_agents ASSIGNING <ls_agent>.

    <ls_agent>-wi_aagent = <ls_work_item>-wi_aagent.

  ENDIF.

ENDLOOP.

Though this is pretty simple code, I would draw your attention to the number of lines of code it takes to perform a simple task such as building the  LT_AGENTS superset (and we didn't even include the type definitions, data declarations, and so on). Now, while there are arguably better ways of performing this task in ABAP (the somewhat obscure COLLECT statement comes to mind), this copy idiom is fairly typical of a lot of the ABAP code I see out there. With that in mind, let's look at the Python way of doing this. Here, if we structure our collection types correctly, we can achieve the same task using a single line of code:

#Assuming wi_dict is a dictionary type with key:value pairs of the form

#{Work Item:Agent ID}...

agent_set = set(wi_dict.values())

In this case, we simply collect the list of agents from the wi_dict dictionary object and then pass it to the set collection's constructor method. Since the set type automatically filters out duplicates, we can perform the task in one fell swoop. Of course, that's just one of many operations that is made easier using Python collections. Overall, I found that it was much easier to create custom data structures and perform all manners of operations on them in Python as opposed to ABAP (and Java, too for that matter). This leads into my next lesson learned.

Lesson 3: ABAP Would Taste Sweeter with Some Syntactic Sugar

The first time I looked at an ABAP program, my initial reaction was how much it looked like COBOL, a language often chastised for its verbosity. 12 years and a case of carpal tunnel syndrome later, things haven't really changed all that much on this front. Sure, there have been a lot of enhancements to the language, but there are still many trivial tasks that seem to take more lines of code than they should. For example, look at the following piece of sample code written in Python:

import os, glob

[f for f in glob.glob('*.xml') if os.stat(f).st_size > 6000]

This complex expression is called a list comprehension, and can be interpreted as "list the set of XML files in the current working directory that are larger than 6,000 bytes". In ABAP, we'd have to call a function to retrieve an internal table of files in the target directory, loop through each file, and apply the predicate logic after the fact. They both achieve the same thing, but I can get there quicker with Python.

Lesson 4: Less Fluff = Improved Readability

As I mentioned earlier, I certainly had my doubts about using Python as a learning language. However, I was surprised at how quickly my son was able to pick it up. After spending just a little time with it, he seemed to have no trouble reading sample code and tweaking it to create simple games. Ultimately, I think this comes down to the fact that Python has so little fluff in it that it's really easy to zero in on what a particular piece of code is trying to do. Compare this with the 30K line ABAP report which contains 2-3 pages full of nothing more than type/variable declarations. Sometimes less is more, and I think Python and scripting languages in general got this part of language design right.

Lesson 5: Everything Works Better if you get the Core Right

As I have begun branching out with my Python programming, I started looking at how to perform common IT-related tasks such as XML parsing, Web service calls, string processing, and so on. While working with these APIs, I noticed a common trend in the APIs: no matter the technology, most everything can be achieved using basic Python built-in types. For example, when parsing XML, I don't have to familiarize myself with 10-20 interfaces (Yes, I'm looking at you iXML). Instead, elements are stored in lists, attributes are stored in dictionaries, and it's basic Python programming as per usual.

I liken this to the Unix OS architecture where everything's a stream. Once you establish this foundation, everything just seems to flow better. Of course, every new technology is going to present a learning curve, but as long as the core remains the same, it is much easier to come up to speed with all the rest.

Conclusions

If you've made it this far through my ramblings, then you might be wondering what conclusions can be drawn from all this. After all, SAP's not likely to re-purpose ABAP as a scripting language anytime soon. Still, languages have a way of borrowing features from one another (see ABAP Objects), so maybe it's possible we'll see ABAP loosen up a little bit more in the coming years. Also, with the advent of VM implementations such as Jython, it's possible to mix-and-match languages to solve particular types of problems.

On a more personal level, I found it interesting to see how the next generation of developers are being taught to program. Clearly things have changed, and sometimes change is good. Like it or not, a good majority of next generation cloud-based applications are being built using these languages. Indeed, at Google, Python is right up there as a first-class citizen with Java in the enterprise realm. Suffice it to say that the dynamic programming hippies are here to stay, so lock up your daughters and hold your statically-typed variables close at hand. 🙂

  • SAP Managed Tags:
7 Comments