Search code examples
functional-programmingprogramming-languages

How are functional programming constructs in multi-paradigm languages useful?


In pure functional programming languages like Haskell, the combination of purity and functional programming makes for nice properties, namely that all functions don't have side effects, so it's easier to reason about, abstract, debug, test, etc.

However, I'm wondering what the purpose of functional programming constructs in multi-paradigm languages that aren't mainly functional. For instance, Python has things like map, filter, lambda, reduce, but most of these things are considered "non-Pythonic" (as opposed to list comprehensions, which may be considered functional I guess). Functions can be considered objects in python, but besides that, it seems pretty much an OOP language.

Even in languages like Scala there isn't any guarantee for a function to be pure/functional, and it could very much be in OOP style (as it'd be when you load a java library, anyways). You'd need to read through each function to determine if it was pure or not.

So my question remains: what's the purpose of FP constructs in multi-paradigm languages?


Solution

  • I use FP constructs in java to process a lot of data, for example: You get a list of integers and have to apply following operations:

    1. Remove uneven numbers
    2. Remove each number, that occurs twice
    3. Map each one to the square root
    4. Sort them in ascending order.
    5. Return it as a list of doubles In Java, with Streams you can do:
    public List<Double> applyOperations(List<Integer> ints){
      return ints.stream()
                 .filter(a->a%2==0)
                 .distinct()
                 .map(Math::sqrt)
                 .sorted()
                 .collect(Collectors.toList());
    }
    

    versus

    public List<Double> applyOperations(List<Integer> ints){
      Set<Integer> evenNumbers=new HashSet<>();
      for(Integer i:ints){
        if(i%2==0){
          evenNumbers.add(i);
        }
      }
      List<Double> doubles = new ArrayList<>();
      for(Integer i:evenNumbers) {
        doubles.add(Math.sqrt(i));
      }
      Collections.sort(doubles);
      return doubles;
    }
    

    The first one is much more readable and elegant than the latter one.