# FP in Popular Languages and Libraries — Functional Programming Concepts

Source: https://www.geekswithgeeks.com/en/functional-programming/pr-langs

> An overview, not a ranking.

## Where the ideas show up

**JavaScript/TypeScript**: first-class functions, array methods, spread, readonly types; libraries such as Ramda, lodash/fp, fp-ts, Effect and Immer. **Python**: comprehensions, generators, `itertools` (`chain`, `islice`, `groupby`, `accumulate`), `functools` (`reduce`, `partial`, `lru_cache`), frozen dataclasses and `match`. **Java**: lambdas and the Streams API since Java 8, `Optional`, records and sealed types in newer versions. **Kotlin**: collection operations, lazy `Sequence`, data and sealed classes. **Rust**: iterators with closures, `Option`/`Result` with the `?` operator, immutable-by-default bindings. **Haskell**: pure and lazy by default, effects tracked in types. **Elixir**: immutable data, pattern matching and the `|>` pipe operator on the BEAM. Check each language's docs for the version you use.

## From concepts to real projects

FP ideas appear across languages, frontend frameworks and data pipelines, with trade-offs worth knowing.

![Four ideas: languages and libraries, frontend and pipelines, trade-offs, and a checklist.](assets/figures/functional-programming/section-8-map.svg) — Figure 8.1 — Languages, applications, trade-offs, checklist.

## itertools and functools in Python

Standard library FP tools.

```python
from functools import reduce, partial, lru_cache
from itertools import accumulate, groupby, islice, count
from operator import add

running_totals = list(accumulate([3, 1, 4, 1, 5]))     # [3, 4, 8, 9, 14]
total = reduce(add, [3, 1, 4, 1, 5], 0)                  # 14
first_squares = list(islice((n * n for n in count(1)), 5))  # [1, 4, 9, 16, 25]

words = sorted(["apple", "avocado", "banana", "blueberry", "cherry"])
by_letter = {k: list(g) for k, g in groupby(words, key=lambda w: w[0])}
# groupby only groups adjacent items, hence the sort first

to_int = partial(int, base=2)          # to_int("101") returns 5

@lru_cache(maxsize=None)
def fib(n: int) -> int:
    return n if n < 2 else fib(n - 1) + fib(n - 2)
```

## Use the idioms of the language

Bring FP concepts, not another language's syntax. Idiomatic Python favours comprehensions over chains of `map` and `lambda`; idiomatic Rust uses iterators and `?` rather than hand-written monad helpers.

**Quiz:** Which feature does Elixir provide for building pipelines?

- [ ] The `never` type
- [ ] The `?` operator
- [ ] Java Streams
- [x] The `|>` pipe operator

*Answer:* The `|>` pipe operator. Elixir pipes the previous result into the next call as its first argument.
