Functional ABAP – Functional Programming in ABAP ?!
The idea to write a blog exploring the possibilities of functional programming in ABAP first came to my mind when I read Horst Keller‘s blogs on ABAP Language News for Release 7.40, SP08. Especially the REDUCE operator that is part of the new iterator expressions ( ABAP News for 7.40, SP08 – FOR Expressions) immediately reminded me of the reduce function in Clojure. As I was learning different function languages in my spare time anyway I started to try to implement some of the examples used in the functional programming tutorial in ABAP. After a twitter conversation with Uwe Fetzer and Fred Verheul (see Uwe’s blog Rosetta Code and ABAP) I decided to collect some of the code examples I created so far and share them in a blog.
A (very, very) short introduction to functional programming
Functional programming is one of the oldest programming paradigms, dating back as far as the late 1950s (cf. Functional programming – Wikipedia). Despite this long history, functional programming never gained widespread acceptance (compared to e.g. C or C++). However, in recent years there has been a growing interest in functional programming and functional programming languages again.
For example, the RedMonk Programming Language Ranking for January 2015 list with Scala (The Scala Programming Language), Haskell (Haskell Language) and Clojure (Clojure – home) three functional languages among the top 20 programming languages (cf. image below). In addition functional extensions to popular programming languages like Java have been developed (cf. Functional Java and How Functional is Java 8?).
There are numerous articles and discussions available on the internet regarding the advantages and/or disadvantages of function programming (e.g. Functional thinking: Why functional programming is on the rise and Advantages Of Functional Programming). In my opinion there are two key advantages that lead to the current interest in functional programming. Firstly, the possibility to develop specific abstractions is an integrated part of each functional language. Secondly, the property of functional languages of being side effect free simplifies the development of parallel programs.
I don’t advocate the code examples I will show below for productive usage (at least not yet). With all the new language features getting added to the ABAP language Tobias Trapp‘s advice “Don’t try to be smart. Be smart.” is more valid then ever. In the context of what I’ll show below I would paraphrase Tobias’s statement as “Just because something is possible doesn’t mean it is a good idea to do it.”
Furthermore, it is important to keep in mind that ABAP is not (and most likely will never be) a functional programming language. In ABAP, it is not possible to pass functions as arguments to other functions. The ABAP compiler and runtime currently lack important features (e.g. tail call optimization, cf. Tail call – Wikipedia or What Is Tail Call Optimization? – Stack Overflow) of runtime engines for functional languages. Consequently, functional programming in ABAP is limited to certain cases. The examples shown below might also only run very slowly or only work for small input values compared to an imperative or object-oriented implementation.
Nevertheless, it is in my opinion quite interesting to see what is possible with the current version of the ABAP language.
Functional ABAP examples
In the following sections I’ll show some quasi functional implementations of different algorithms in ABAP. Note that all code examples in this blog a screen shots. There reason for this is that no syntax highlighting for ABAP is available. In order to simplify the usage of the code snippets is also create a pastie (Pastie) for each snippet and added a link to it below each screen shot.
As a simple start to functional programming in ABAP let’s calculate the sum and the product of the values of an internal table. The code snippet below shows how this would be implemented in ABAP without the usage of any of the new language features. To calculate the sum and the product one would simply loop through the internal table and store the calculation result in a temporary variable. It would of course be possible to calculate the sum and the product using a single loop. However, I used two loops to make the similarity to the functional implantation more obvious.
Using the reduce table expression calculating the sum and the product can also be implemented as shown below.
Note that in this case there is not much difference with respect to the code amount between the two solutions. In fact the classical solution using only one loop would be shorter than the functional one. The key advantage of the REDUCE operator is that it can be combined with other operators to create more expressive expressions.
The first a little more advanced algorithm I implemented using a functional paradigm in ABAP is the Fizz Buzz Test. The Fizz Buzz Test is a simple programming exercise I stated to use in job interviews for developers lately. Many implementations of the Fizz Buzz Test in different languages are documented on rosettacode (http://rosettacode.org/wiki/FizzBuzz). The goal of this test is to:
“Write a program that prints the numbers from 1 to 100. But for multiples of three print “Fizz” instead of the number and for the multiples of five print “Buzz”. For numbers which are multiples of both three and five print “FizzBuzz”.”
The code snippet below shows the implementation of the Fizz Buzz Test in “normal” ABAP without the usage of any of the new ABAP features. In lines 6 to 9 an internal table is initialized with the numbers 1 to 100. After that the lines 11 to 22 show the core implementation of the FIZZ BUZZ Test.
An alternative implementation of of the Fizz Buzz Test using functional ABAP is shown below. It is immediately obvious that the second implementation is much more concise then the previous one. The implementation consists of a constructor expression for a string table (line 4). Using the FOR iterator expression the values form 1 to 100 are passed to a COND expression. The COND expressions uses a LET expression to create two local variables r3 and r5. r3 and r5 store the result of i MOD 3 and i MOD 5 respectively. Finally, the WHEN and ELSE clauses in lines 8 to 11 implement the core logic of the Fizz Buzz Test.
Besides being more concise, the functional implementation is in my opinion a lot cleaner then the classical one.
Next I implemented the factorial function. The factorial of a positive integer n is defined as the product of the sequence n, n-1, n-2, …1. Furthermore, the factorial of 0 is defined as being 1. Using the the COND and the REDUCE operator the factorial function can be implemented as shown below. This functional implementation of the factorial function nicely resembles the definition. Therefore the functional implementation is in my opinion simpler to understand compared to the classical implementation.
Note, that the COND operator is not required in the implementation. The REDUCE operator would also handle the special case of 0 correctly. Nevertheless, I included the COND operator in order to have the function definition more clearly expressed in the code.
The last algorithm I implemented using the functional operators is the Fibonacci sequence. I used a recursive approach for this implementation. The COND operator is used to represent the definition of the Fibonacci numbers (lines 13 – 18). In order to implement the recursive call I used a LET expression to invoke the Fibonacci function recursively (line 18). The two auxiliary variables x and y store the last and second to last element to the Fibonacci sequence for n-1 (lines 19 and 20). Finally the result of adding x and y is concatenated with the elements of the Fibonacci sequence for n-1 and returned (line 22).
As stated in the introduction it is quite interesting to see what is possible with the new ABAP features. However, there are still some open questions:
In the examples above I didn’t compare the performance of the classical ABAP solutions to the functional ones. It would be quite interesting to see how the different solutions compare with respect to performance. This might be the topic for a future blog post.
2. Productive usage scenarios
Another open question is which productive usage scenarios are suitable to apply the functional ABAP features. The examples above are implementation of mathematical algorithm. However, productive ABAP code usually deals with the handling of business objects (e.g. business partners). The first usage scenario that came to my mind is the usage of the FILTER operator (not shown in the examples above, cf.FILTER expression) to filter an internal table after some select (e.g. select from BUT000 and the filter the business partner type). However, It would be interesting to find further usage scenarios in which a functional solution offer advantages over the classical one.
3. Future ABAP versions
It will be really interesting to see what future ABAP version will offer. Maybe ABAP will in the future offer some functional features that are currently still missing.
Finally, I’d be interested to hear your opinion of the code examples I’ve shown above. Do you think this is something that should be used in productive code?