It is a programming paradigm that typically avoids using mutable state. (Whatever does that mean?)
Functional programming avoids side effects (change of state) during execution of a function. Compare that to imperative style programming, like in ABAP, where usually state can be changed by commands/statements e.g. for I/O, database operations, global variables, buffering etc.
Stateful programming is a major cause of bugs in software programs. It introduces complexity, uncertainty and affects readability of code that in turn causes bugs during initial development and even more during maintenance. Such code is not easily understandable and other programmers end up making unintentional changes during maintenance phase.
In my view, readability of a program is not about good looking, handsome or beautiful code. Nevertheless, some developers achieve the objective of writing *good-looking* code by hiding all the code inside a method / routine that does not even gets or returns any parameter. So the main program is probably just a few calls of such routines, that might even have lengthy comments, along with all the stars and moons around it. And it does *look* good and clean.
I would consider a program, function or method as readable, if I can use my brain as a virtual m/c or a Runtime Environment for the code, and depending on the known parameters or state at a given point, I could effectively run the program in my head, pass through the flow with a decent level of accuracy and have an understanding of the results. Obviously in the process I'll have to check the values in database tables etc. but you get the idea.
Now, object oriented programming might have solved many other issues with software development but I don't think Readability or even Debuggability is one of them. When you are reading code and trying to run it in your head, it works quite well till you hit a global variables, attributes, instances etc. that are populated through another function, method or constructor. Brain starts hurting. First of all it's not really a programming language runtime environment, secondly you use the same environment for so many different programming languages and paradigms now on top of it, you are asking it to run code that does not provide complete instruction, definition of data-structures or data. So it just basically starts sending signals to use debugger, try 'Where Used', look for event listeners, design or tech documents, UML diagrams, match the design pattern etc.
Basically, I found the idea of avoiding state changes quite fascinating and it does seem like, with a little exaggeration, the holy grail for producing relatively error free and maintainable software. Though I don’t have any data to prove this but I've around 15 years of experience in software development, mostly with solving problems in my own or others’ code so it’s probably just my intuition.
Even before I started exploring the main idea behind functional programming, I've always been a bit cautious in my programming style. e.g. avoid use of global variables and writing functions/methods/routines with proper input / output parameters without trying to access global data from within, unless when really pressed on the performance and has to implement buffering etc. To give you another example of a cautious style, I hesitate using [ LOOP at ITAB ASSIGNING <FS>
So coming back to the point, in functional programming, functions are like mathematical function that takes input and returns an output without changing state in that process of computation. e.g. add(1,1)returns 2.
Compare that to a function in ABAP, for example, BAPI_ORDER_CREATE (fictional but you’ll get the idea) . This also takes input and returns an output e.g. an order number. But while trying to generate that Order, it makes several changes to the state like database change, number range increment output/print of a document, download file/IDoc , trigger another process or interface etc.
Now, I might be wrong in my interpretation of the idea behind functional programming but one thing I've learned about the process of learning; It’s OK to start with even a hazy conceptual understanding of a new concept through analogy and comparison with an already known subject. It provides a starting point from where you can improvise as you explore further into an alien subject. That's Ok, but where is the analogy? I had the same question. I mean how would you create, say a Purchase Order, using a mathematical style function that makes no changes to state. Or how can we create a purchase order using a functional programming style?
So while I found the idea behind functional programming quite fascinating and clearly beneficial too, how to achieve something substantial in an industrial programming environment was an equally intriguing question.
Exploring a bit further, I realized that there might be a bit of compromise required in some cases but there are some special features in a functional programming language environment to support the main essence that is stateless programming.
Functional programming requires that functions are first-class, which means that they are treated like any other values and can be passed as arguments to other functions or be returned as a result of a function.
Now, I do understand that ABAP is not a functional programming language and it does not support any of these features except for recursion ( that too without any in-built optimization for tail recursion) but my intention is to look into the possibility of bringing some of the functional programming goodness (avoid state changes) into my ABAP design/programming style. Obviously, pure functional programming style will be more beneficial for parallel or distributed programming, but concept of immutable data can be useful even in normal scenario.
- Higher Order Functions : are functions that take other functions as their arguments. So if SAP ABAP could have such feature then you can compose another function / computation by passing one function to another function like a parameter. Further Reference : http://www0.cs.ucl.ac.uk/teaching/3C11/book/ch4.pdf
- Purity : Referes to Language feature that prohibits side effects.
- Recursion : [ just a link to wikipedia and not a Google style Joke for recursion ]
FUNCTION z_ram_test_iterate_itab.
*"--------------------------------------------------------------
*"*"Local Interface:
*" IMPORTING
*" VALUE(I_INDEX) TYPE I DEFAULT 1
*" VALUE(I_ITAB) TYPE STANDARD TABLE
*"--------------------------------------------------------------
FIELD-SYMBOLS : <fs_itab> TYPE c.
READ TABLE i_itab ASSIGNING <fs_itab> CASTING INDEX i_index.
CHECK sy-subrc EQ 0.
* Record found so now try iterating next otherwise it will come
* out at this point.
* Do some calculation etc. here
* WRITE /: <fs_itab> .
* Now go on...
i_index = i_index + 1.
CALL FUNCTION 'Z_RAM_TEST_ITERATE_ITAB'
EXPORTING
i_index = i_index
i_itab = i_itab.
ENDFUNCTION.
Following screenshot of ABAP debugger shows the call-stack for a recursive function...shows a python decorator which implements tail call optimization. It does this by throwing an exception if it is it's own grandparent, and catching such exceptions to fake the tail call optimization.I'll add the list of other references for functional programming at the end of this post...later.
There is no conclusion as far as this Blog post is concerned...apart from the obvious fact that ABAP Language and ABAP Programmers, both have a lot to learn and improve :)
IMO recursive functions are not an improvement over traditional loops, they are simply a side effect of not having mutable data.
ReplyDeleteConsider that for loops using an incrementing number or while loops checking a flag are impossible since these values cannot change. They are also the only way of working with immutable linked lists.
Thanks for your comment Andy.
DeleteAgree that recursion is not an improvement rather a way to handle iteration while maintaining the restriction of immutability in a *functional programming language*.
Not to mention that there are some cases where recursive patterns comes more naturally to developers, while writing modular code, specially if you are traversing backwards, even in non-functional language.
For example, if you want to write a function to find out which programs will be impacted, if you change a data-element in data-dictionary that might have been used in several tables, programs. Also, those program routines/tables might have been called in other programs too. In such case, recursive implementation seems to be obvious choice.
Similarly there could be other cases where recursive data-structures are required.
However, the question that I am trying to explore is:
Is it feasible to impose the immutability restriction in a non-functional language just as a manual application code/design level constraint ( as language itself is not putting that constraint in place ) and still manage to get some benefits associated with the concept of immutability.
Thanks,
Ram
Without language support, immutability is an up hill struggle. For example in java Creating an immutable class is relatively easy but then what if I want to "copy" that object with a new field? Manually copying every field plus the new one is a lot of code.
DeleteUse erlang instead.
ABAP is a born imperative language, and added with some object - oriented features. So I think there's no way to take benefit of functional programming thinking in ABAP at all.
ReplyDeleteThanks Jun for your comment...so unless a language was born Functional, there is no other way to apply functional *thinking* with it?
Delete