Can Functional Programming hinder the discovery of certain types of bugs?

Asked

Viewed 109 times

9

As I understand it, functional programming (or at least a functional programming style) makes it easy to find and avoid bugs (it’s easy to test pure functions, immutability protects data, indeterminate things like I/O are isolated, etc.); but reading this answer I came across the following report:

Recently there was a discussion involving hundreds of people in the company where I work, due to a very difficult bug to discover in a purely functional code snippet. The incident raised a red flag for some on the complexity problem of some functional implementations.

So, are there certain types of bugs that are more easily covered up in functional code than in other paradigm codes? And what kind of bugs would those be?

  • 1

    Certainly there is, probably all related to the fact of having to use some tricks to do what is simple in a more imperative paradigm, tricks trick the compiler and can fool the programmer.

  • @Maniero a answer here of utluiz illustrates your thinking? Or, you were thinking of other types of problems with PF (problems that can facilitate/hide bugs) and that have not yet been addressed?

  • Not exactly because he talked about the problems of using functional in a non-functional language, which makes perfect sense, but has the problems related to pure functional programming. It’s well answered to your question regarding what he said there in the original answer, if that’s what you wanted to know, great, if you wanted to know in general what can be complicated to do in functional I think it’s not quite the same thing. I do not venture to answer because my knowledge of functional is still, and I think it will always be superficial, I like, but I do not use strong mind. I do something functional in C#.

1 answer

8


TL;DR

The case in question in that posting involved a relatively complex functional code base, written in Java, and the question of Accessibility from a developer who was unfamiliar with her so that she could understand what was wrong.

Contrast of a code

A particular passage was similar to the following:

Either<Exception, Iterable<QuoteResponse>> quoteRequestProcessed =
    sequenceRight(
        from(request.getQuoteRequests())
            .transform(
                curried(priceCalculator).apply(request)
            ));

if (quoteRequestProcessed.isLeft()) {
    return left(quoteRequestProcessed.left().get());
}

An equivalent imperative code would be:

List<QuoteResponse> responses = new ArrayList<>();
for (QuoteRequest quoteRequest : request.getQuoteRequests()) {
    responses.add(priceCalculator.apply(quoteRequest));
}

priceCalculator is a function (Function) incoming.

Now, stop and think of exceptional cases that can occur in both parts. For example, what would happen if priceCalculator make an exception?

Well, in the second case, the exception would be dropped normally and you would have to capture it.

And in the first case, who uses the functional approach? The truth is that it is not possible to tell the result unless you understand concepts like currying, iterable effluent, the convention of left and right of a Either implemented in a specific library used there.

I will not explain the Functional code on purpose, so you feel a little more the "pain" of who was debugging it to find the problem.

Isolation, tribalism and elitism

The summary of the case is: the overload caused by the amount of concepts needed to understand well a functional code can prevent a "common" developer from fully understanding the possible execution scenarios of that code.

Of course, a developer trained on that code base could more easily have a good understanding. However, the reality is that the learning curve impacts directly on a company’s dynamic environment, where projects and people come and go.

Something that adds to the problem is "tribalism" in teams that adopt functional programming, that is, few people build a very specific way of developer the system that makes external contributions almost impossible. One way to do this is to create your own dialect, perhaps a library with functions that no one else knows. It is not uncommon for teams to live isolated from others. Such projects tend to arise by one or a few enthusiasts by PF and then die tend to die as soon as they leave the companies because no one wants to put their hand.

Accessibility and portability

In a collaborative environment, the portability of developers makes all the difference. Although I advocate the freedom of engineers to choose the most appropriate technology to solve every problem, it is also necessary to be aware that you are not the owner of the code.

One way around the problem of accessibility and portability would be to use a language that is naturally functional - e.g. Haskell, Erlang, Clojure, Scala - or at least to standardize use with known libraries.

In my opinion, the company’s culture will dictate whether it is possible to adopt a higher complexity functional language or whether it is better to stick to the basics.

  • For life, they have not yet created such a silver bullet.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.