Hello,
I am not sure to understand what you mean exactly by "in terms of structural code base", but I'll try to answer anyway. The most important feature of functional programming is the separation between effects and functions. Effects are the part which interact with the outside world, (which can be the world outside the application, or just outside the component you are considering). The rest of the code is composed of functions, which have no other interaction than receiving values as argument and returning a result. In pure functional programming, there are no effects, which does not mean that the programs do nothing observable, but that they return something which will make the effect observable once activated. You can see it as if functional programs were returning a kind of imperative programs that can be executed. Less pure functional programs simply separate functions and effect inside the same program. To allow a maximal separation, it is necessary to push abstraction as far as possible. For example, all control structures are abstracted into functions, so you never manipulate these control structures, such as loops, conditional instructions, try..catch blocks, etc., Of course, this is not completely true if you use a non functional friendly language like
Java: You have to define your own abstractions, so you must use them once.)
The benefit form separating functions from effects are that the functional parts are deterministic, so they can very easily be fully tested, and even often proven correct. This makes programs more reliable. It also make them faster to develop, since
testing time is much reduced as well as the number of implementation bugs due to the abstraction of control structures. It also makes programs more readable because abstractions are named and can be recognized. This is not obvious for beginners, because it is difficult to recognize what you don't already know. Functional programming implies a different way of thinking. One must not see programs as a control flow, with instruction changing the state of some components, but as series of expressions that may be combined to create new expressions, until obtaining a single function taking the input data as its argument and returning the output.