• ☆ Yσɠƚԋσʂ ☆
    link
    11
    edit-2
    2 years ago

    I’d argue there’s a historical aspect to this as well. Back when personal computers became available these were slow machines with limited resources. Originally they were programmed by writing assembly by hand, and C was effectively a way to write portable code that was very close to assembly but could be compiled against different instruction sets. Meanwhile, the kinds of software people were writing was relatively small and often maintained by a single developer. Having an imperative language that allows you to squeeze as much as you can out of your hardware made a lot of sense in this scenario.

    A whole generation of programmers learned to code in this environment, and then they went on to design languages and teach others. Most mainstream languages are derived from C, and bear a lot of similarity to it both syntactically as well as semantically.

    And of course we now have mountains of reusable code written in imperative languages, documentation, application platforms, and so on. So, there is a lot of incentive to use a language that’s popular.

    Of course, today the problems we’re solving are different from ones we solved forty years ago. Raw performance is often not the most important consideration for code. Being able to write code that’s easier to reason about, maintain, and to work on in teams are often a much more important considerations.

    The fact that we’re seeing functional programming being adapted shows that it does solve real problems for people that can’t be easily addressed using the imperative style.

    My experience is that imperative programs quickly become difficult to reason about as they grow. This is especially true with OO style programming. Each object is basically a state machine, and your program is a graph of these interdependent state machines. It’s very difficult to tell what any particular object is doing without knowing the state of the entire program.

    On the other hand, FP style focuses on using pure functions that can be reasoned about independently with the state being passed around explicitly between them. This style of programming makes it much easier to create independent components that can be reasoned about in isolation.

    I find that a good general approach is to push state to the edges of the application while keeping business logic pure. Clean architecture approach is a good example of this pattern.