Technical Articles
Functional Programming in ABAP Series: PART I (Introduction)
Background
In computer coding, it’s super important to write really good code. Good code doesn’t just make programs run faster, it also helps developers work better. But figuring out what makes code good can be tricky, and it’s not just about making things run quickly.
Good code has things like being easy to test, easy to keep up, easy to use again, and easy to add more stuff to. These things are like measuring sticks for how tough and reliable the code is. But knowing how to make code like that isn’t always clear, so we look into ways to help us write clean code.
One cool way to do this is by using functional programming. It’s a style of coding inspired by math, and it’s all about using expressions and putting functions together. We separate pure functions, which only do one thing and don’t mess with anything else, from impure ones, which do more things. This helps make our code not just easy to understand but also makes testing and modifying way simpler.
In ABAP (a programming language), Object-Oriented ABAP is a great way to use functional programming ideas. It’s not a perfect solution for everything, but it really helps us think about problems in new ways.
Functional Programming in A Nutshell
Functional programming is programming using functions.
Functional programming is like building with LEGO blocks, combining functions to build a new and different use of function.
Let’s take a look at the provided Haskell code examples, showcasing the essence of functional programming:
even :: (Integral a) => a -> Bool
even x
| x `mod` 2 == 0 = True
| otherwise = False
Here, I’ve defined a function called even that takes an integral value, x, and returns a boolean indicating whether x is even. I’ve used guards (|) to make the code concise and expressive which is the main characteristic of functional programming.
odd :: (Integral a) => a -> Bool
odd = not . even
In this example, I leverage the composition operator (.) to define the odd function succinctly. I take advantage of the previously defined even function, showcasing the power of composing functions to create new ones.
filter :: (a -> Bool) -> [a] -> [a]
filter _ [] = []
filter pred (x:xs)
| pred x = x : filter pred xs
| otherwise = filter pred xs
The filter function showcases a common higher-order function in functional programming. I take a predicate function,, and a list of any type [a], returning a new list containing only the elements that satisfy the predicate. This serves as a clear example of functional programming’s emphasis on using higher-order functions for concise and expressive code.
In this function, I highlight the recursive technique — a fundamental aspect of functional programming. Recursion is not only a technical approach but also a distinctive way of thinking. Embracing recursion allows me to break down complex problems into simpler, more manageable sub-problems, fostering code elegance and a deeper understanding of functional programming principles.
ghci> filter odd [1..100]
[1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41,43,45,47,49,51,53,55,57,59,61,63,65,67,69,71,73,75,77,79,81,83,85,87,89,91,93,95,97,99]
ghci> filter even [1..100]
[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,88,90,92,94,96,98,100]
These examples demonstrate Haskell’s functional programming features, emphasizing the concise and declarative nature of the code. The use of higher-order functions, immutability, and function composition contributes to the readability and maintainability of the codebase. These principles form the basis for our exploration of functional programming in Object-Oriented ABAP in the subsequent sections.
Translating Functional Programming Concepts: Haskell to ABAP
Let’s seamlessly translate the Haskell code above into ABAP, aiming for a natural adaptation that captures the essence of functional programming concepts applied in an Object-Oriented (OO) paradigm, specifically within the ABAP language.
Here is the code implementation,
ABAP
INTERFACE zif_predicate
PUBLIC .
METHODS evaluate IMPORTING value TYPE any
RETURNING VALUE(result) TYPE abap_bool.
ENDINTERFACE.
The zif_predicate interface serves as a contract or blueprint for classes that implement a specific method signature, in this case, the evaluate method. I’ve defined it to establish a common contract that the zcl_predicate_even and zcl_predicate_odd classes adhere to.
The purpose of this interface is to declare a method, evaluate, that takes a value and returns a boolean result. Its usage lies in ensuring that all classes implementing this interface adhere to a consistent contract. In this context, I use the interface to implement a higher-order function through the application of dependency injection.
Even Predicate in Haskell vs ABAP
Haskell
even :: (Integral a) => a -> Bool
even x
| x `mod` 2 == 0 = True
| otherwise = False
ABAP
CLASS zcl_predicate_even DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES zif_predicate.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_predicate_even IMPLEMENTATION.
METHOD zif_predicate~evaluate.
FIELD-SYMBOLS <value> TYPE i.
ASSIGN value TO <value>.
result = COND #( WHEN <value> MOD 2 = 0
THEN abap_true
ELSE abap_false ).
ENDMETHOD.
ENDCLASS.
In both languages, I’ve defined a predicate to check if a number is even. The ABAP implementation uses an interface zif_predicate to establish a common contract and the evaluate method mirrors the Haskell logic. Additionally, I exemplify the application of dynamic programming in ABAP to adeptly handle generic data types, which is common in the functional programming world.
Odd Predicate in Haskell vs ABAP
Haskell
odd :: (Integral a) => a -> Bool
odd = not . even
ABAP
CLASS zcl_predicate_odd DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES zif_predicate.
PROTECTED SECTION.
PRIVATE SECTION.
METHODS negate IMPORTING truth TYPE abap_bool
RETURNING VALUE(result) TYPE abap_bool.
ENDCLASS.
CLASS zcl_predicate_odd IMPLEMENTATION.
METHOD zif_predicate~evaluate.
result = negate(
CAST zif_predicate(
NEW zcl_predicate_even( )
)->evaluate( value = value ) ).
ENDMETHOD.
METHOD negate.
result = COND #( WHEN truth = abap_true
THEN abap_false
ELSE abap_true ).
ENDMETHOD.
ENDCLASS.
Here, I define the odd predicate in Haskell by negating the even predicate. In ABAP, I encapsulate this logic in the zcl_predicate_odd class, which internally leverages the zcl_predicate_even class to evaluate evenness and then negate it. In this part, I use function composition in both languages. In functional programming, I believe function composition is the key to handling complexity.
Filtering Elements in a List in Haskell vs ABAP
Haskell
filter :: (a -> Bool) -> [a] -> [a]
filter _ [] = []
filter pred (x:xs)
| pred x = x : filter pred xs
| otherwise = filter pred xs
ABAP
CLASS zcl_filter DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
METHODS get_filtered IMPORTING predicate TYPE REF TO zif_predicate
value_tab TYPE ANY TABLE
RETURNING VALUE(result) TYPE REF TO data.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_filter IMPLEMENTATION.
METHOD get_filtered.
FIELD-SYMBOLS <result_tab> LIKE value_tab.
CREATE DATA result LIKE value_tab.
ASSIGN result->* TO <result_tab>.
LOOP AT value_tab ASSIGNING FIELD-SYMBOL(<value>).
IF predicate->evaluate( <value> ) = abap_false.
CONTINUE.
ELSE.
INSERT <value> INTO TABLE <result_tab>.
ENDIF.
ENDLOOP.
ENDMETHOD.
ENDCLASS.
In both languages, I’ve implemented the filter function as a higher-order function. In Haskell, it operates on lists, and in ABAP, it uses a generic table structure. The ABAP implementation defines a class zcl_filter that takes a predicate and a table of values, returning a filtered result.
In imperative programming languages, including ABAP, I always prefer to use loops over recursive methods. Handling generic data here becomes more complex but still acceptable. In this method, I observe the utilization of higher-order functions in ABAP through the implementation of dependency injection.
While in functional programming, functions are considered first-class citizens, in Object-Oriented Programming (OOP), objects take on this primary role.
Usage in GHCi vs ABAP Demo
ABAP
CLASS zcl_demo_fp DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES if_oo_adt_classrun.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_demo_fp IMPLEMENTATION.
METHOD if_oo_adt_classrun~main.
TYPES ty_t_integer TYPE STANDARD TABLE OF i WITH EMPTY KEY.
DATA(filter) = NEW zcl_filter( ).
DATA(even) = CAST zif_predicate( NEW zcl_predicate_even( ) ).
DATA(odd) = CAST zif_predicate( NEW zcl_predicate_odd( ) ).
DATA value_tab TYPE ty_t_integer.
" get even number from 1 to 100
out->write( `Even Numbers` ).
DATA(even_number) = filter->get_filtered(
predicate = even
value_tab = VALUE ty_t_integer( FOR i = 1 THEN i + 1 UNTIL i = 100
( i ) )
).
ASSIGN even_number->* TO FIELD-SYMBOL(<even_number>).
IF <even_number> IS ASSIGNED.
value_tab = CORRESPONDING #( <even_number> ).
DATA(string_even) = REDUCE string( INIT evens TYPE string
FOR <even> IN value_tab
NEXT
evens = COND #( WHEN evens IS INITIAL
THEN <even>
ELSE |{ evens }, { <even> }| ) ).
out->write(
EXPORTING
data = |[{ string_even }]| ).
ENDIF.
" get odd number from 1 to 100
out->write( `Odd Numbers` ).
DATA(odd_number) = filter->get_filtered(
predicate = odd
value_tab = VALUE ty_t_integer( FOR i = 1 THEN i + 1 UNTIL i = 100
( i ) )
).
ASSIGN odd_number->* TO FIELD-SYMBOL(<odd_number>).
IF <odd_number> IS ASSIGNED.
CLEAR value_tab.
value_tab = CORRESPONDING #( <odd_number> ).
DATA(string_odd) = REDUCE string( INIT odds TYPE string
FOR <odd> IN value_tab
NEXT
odds = COND #( WHEN odds IS INITIAL
THEN <odd>
ELSE |{ odds }, { <odd> }| ) ).
out->write(
EXPORTING
data = |[{ string_odd }]| ).
ENDIF.
ENDMETHOD.
ENDCLASS.
The final part of my ABAP code (zcl_demo_fp) showcases the usage of the defined classes and predicates, similar to how the examples were demonstrated in GHCi for Haskell. In my demo class, I create instances of the filter, even, and odd predicates, apply them to a range of integers, and output the results.
Conclusion
In this chapter, we explored basic ideas in functional programming, focusing on two important things: higher-order functions and function composition. Here’s what you need to remember:
Functional Programming Insights: We learned why higher-order functions and function composition are super important in functional programming. Understanding these concepts helps us make the most out of functional programming.
Natural Implementation in Object-Oriented Programming: Some people think that functional programming is only for certain languages, but I showed how these ideas can work smoothly in Object-Oriented Programming (OOP). Using dependency injection, I made higher-order functions work well. With functional method composition, I found a natural way to combine functions (using functional method) in an OOP setup.
Looking Ahead:
We’ve made good progress with using functional programming ideas, but there’s more to learn. To write really great code, we need to understand things in a more detailed way. So, in the next part, we’re going to look at a real-world example. We’ll explore how to design things in a smart way, using ideas from functional programming. Our goal is to show how these ideas can help us create clean code.
Our adventure is not finished yet. We’re ready to go deeper into the mix of functional programming and Object-Oriented ABAP. This could change the way we usually design and make software. Stick around as we uncover more about how these ideas can make a big difference in how we create software that works well.
Reference
- Allen, C. and Moronuki, J., 2017. Haskell Programming from first principles. Gumroad, 23, p.67.
- Hutton, G., 2016. Programming in haskell. Cambridge University Press.
Contributors

A higher order function takes functions as input and returns a function, https://en.wikipedia.org/wiki/Higher-order_function
Function composition takes two functions and creates a new function, https://en.wikipedia.org/wiki/Function_composition
In functional programming, functions are treated as first class citizens, https://en.wikipedia.org/wiki/Functional_programming
All of which is not possible in ABAP? The examples are object oriented programming in ABAP?
Hello Lars,
Thank you for your comment. I'm unclear about your specific question, but I'll share my thoughts on the topic you raised.
As I know ABAP is an imperative procedural/ object-oriented programming language. ABAP does not treat a function as a first-class citizen, the closest behavior of this is by using an object-oriented paradigm which is an object as a first-class citizen.
In more specific terms,
higher-order function: A function is called higher-order if it takes a function as an argument or returns a function as a result. But often, the functional programmer would say that a higher-order function is a function that takes a function as an argument, whereas a function that returns a function as a result is called a currying/ curried function. In ABAP it can only be achieved by using dependency injection (object-oriented).
In mathematics, function composition is defined like this: (f . g)(x) = f (g(x)).
This means that composing two functions is the equivalent of calling one
function with some value and then calling another function with the result
of the first function. In Haskell, function composition is pretty much the same thing. We do function composition with the . function, which is defined like this:
In ABAP we can achieve this by leveraging the functional method of a class/ object.
As I mentioned before I use object-oriented ABAP to implement functional programming concepts. There is nothing new in the example/ ABAP implementation above, I just translate the basic functional programming concepts into ABAP language leveraging object-oriented programming in ABAP to get used to the concepts.
hmm
Ew. Haskell uses Integral (which is among other things the area under a curve) to indicate an Integer.
Can you explain why what you're doing is using dependency injection?
Hello Matthew,
Thank you for your comment. That is an excellent question; in fact, it's inspiring me to write another blog post about dependency injection in ABAP. While there are already some blog posts on the topic, such as this one and this one. But still, I want to write my perspective about dependency injection.
Now, I'm going to re-explain why my ABAP example employs dependency injection.
please get focused on this code
In the given code, the dependency is the
zif_predicateinterface, and it is injected into theget_filteredmethod as a parameter (parameter injection).Here's a breakdown of the dependency injection in the above code:
get_filteredmethod takes two parameters:predicate(of typeREF TO zif_predicate) andvalue_tab(of typeANY TABLE).predicateparameter represents a dependency, and it is expected to be an instance of a class that implements thezif_predicateinterface.get_filteredmethod, thepredicateparameter is used to evaluate each element in thevalue_tabtable, which is its implementation can be changed in run time.By passing the
predicateas a parameter to theget_filteredmethod, we allow external code to determine the filtering logic, thus adhering to the principles of dependency injection.Example code that does not use dependency injection
The
zcl_predicate_oddclass takes a dependency on another class,zcl_predicate_even,but, instead of injecting it, the dependency instantiation is hard-coded within the method itself.
OK, I see it now. Thanks.
I use dependency injection routinely - I just couldn't see the injection point!
please check my blog post talking about dependency injection
FYI: there was a post about this in 2015.
Hello Jelena,
Thank you for your comment. I've read the mentioned post, and it's indeed a good blog post about functional programming. However, there are significant differences between my post and the one you referred to. If you haven't noticed these distinctions, it's possible that you didn't read my post all the way through.
Let me highlight the key differences between the two:
My post focuses on higher-level abstraction (design level), while the other post delves into syntax (lowest level/concrete level). The mentioned post doesn't cover the fundamental concepts of functional programming; it mainly discusses REDUCE, COND, VALUE, FOR, etc. – essentially syntax.
As developers, we follow these steps in learning programming:
The higher the number, the higher the level of abstraction (design patterns being the highest). Before reaching the design pattern stage, I need to explain the basic concepts of functional programming and how to implement them in ABAP. I believe my blog post is unique in this scope and fills a gap by covering concepts that haven't been addressed before.