# Python as functional programming language

**URL:** <https://discuss.python.org/t/python-as-functional-programming-language/38402>\
**Category:** Python Help\
**Created:** [November 10, 2023, 4:56pm UTC](https://discuss.python.org/t/python-as-functional-programming-language/38402 "2023-11-10T16:56:05Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![capymind](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/capymind/32/15179_2.png) [@capymind](https://discuss.python.org/u/capymind)\
**Post date:** [November 10, 2023, 4:56pm UTC](https://discuss.python.org/t/python-as-functional-programming-language/38402/1 "2023-11-10T16:56:05Z")

</div>

Hi everyone.  
I am a kind of python novice, sorry for dumb question here in advance…

I recently watched a few conference talks about functional programming.  
(for example, Scott Wlaschin’s Domain Modeling Made Functional, Composition, Functional design pattern etc using F#)

Without jargons (functor, monoid, monads etc.), the basic concepts and approaches are very attractive for me and make me not to be scared about type systems…So I want to give a try using Python in a kind of functional way.

[Python’s official website’s FAQ says](https://docs.python.org/3/faq/general.html#what-is-python)

> Python is an interpreted, interactive, object-oriented programming language. It incorporates modules, exceptions, dynamic typing, very high level dynamic data types, and classes. It supports multiple programming paradigms beyond object-oriented programming, such as procedural and functional programming.

Although Python is not designed for “functional programming languages” at first (to be honest I only have shallow understanding about difference in approach, philosophy, toolkit between OOP, and FP…), Is it okay and possible(even recommended sometimes) to write software fully in functional way using Python?

Thanks for reading this (dumb) question

---

<div class="post-metadata">

**Author:** ![hansgeunsmeyer](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/hansgeunsmeyer/32/15188_2.png) [@hansgeunsmeyer](https://discuss.python.org/u/hansgeunsmeyer)\
**Post date:** [November 10, 2023, 6:02pm UTC](https://discuss.python.org/t/python-as-functional-programming-language/38402/2 "2023-11-10T18:02:16Z")

</div>

> [@capymind](#):
>
> Is it okay and possible(even recommended sometimes) to write software fully in functional way using Python?

Is it possible? - It depends on what you mean by “functional”. If you want to be “strictly” or “purely” functional, it’s not possible. But it’s definitely possible to apply a functional style. Perhaps the single most important thing there is avoiding side-effects in functions. Functions with side-effects often are troublesome and make analyzing programs a lot harder, so this is sth that is good to always apply, imo.  
Avoiding statefullness is also sth that I think should generally be applied - again as far as possible. But here the question again is - how far do you want to go? (Python generators and coroutines for instance are very useful but maintain state.)

Is it okay? – Nobody is going to forbid you (I hope) 🙂

If you want to look at examples:

- The pandas APIs for the most part apply (and invite) a functional programming style; the pyspark API is similar.
- In the stdlib `functools` and `itertools` use a functional style (see docs - itertools explicitly mentions it’s inspired by Haskell); functools is a bunch of convenience functions to create higher-order functions

---

<div class="post-metadata">

**Author:** ![kknechtel](https://avatars.discourse-cdn.com/v4/letter/k/e47c2d/32.png) [@kknechtel](https://discuss.python.org/u/kknechtel)\
**Post date:** [November 10, 2023, 6:29pm UTC](https://discuss.python.org/t/python-as-functional-programming-language/38402/3 "2023-11-10T18:29:57Z")

</div>

Python is described as an object-oriented language (and, in my view, it takes this idea more seriously than many other languages like Java that are commonly held up as archetypes of “object-oriented languages”); but it is still designed very much as a _pragmatic_ language that supports multiple programming paradigms and allows for writing code in different styles. In that regard I think it is similar to C++ - only, far more pleasant to use 😉

- Because of Python’s commitment to the “everything is an object” principle of OO, functions (as well as other “callables”, such as classes) are first-class objects. This makes it natural to design and use higher-order functions.

- Python has a lambda (anonymous function) syntax, using the keyword `lambda`. It is restricted: the body of a lambda must be a single _expression_. (However, Python expressions can have side effects, and there is no general way to prevent this.) This syntax produces a function object (the same type as the `def` statement does); in the corresponding bytecode, the result of the expression is `return`ed.

- The decorator mechanism is implemented using higher-order functions, in fact. For example:

```auto
def spam(func):
    return lambda: ' '.join(func() for _ in range(10))

@spam
def what_the_knights_say():
    return 'Ni!'

# The `@call_twice_and_sum` before the function is roughly equivalent to doing
# `what_the_knights_say = spam(what_the_knights_say)` afterwards.

```

- As mentioned, the standard library `functools` and `itertools` are invaluable here. In particular, `functools.reduce` implements a fold (a left fold, if I’m thinking clearly). `map` and `filter` are builtins, and there is a basic list-comprehension syntax that generalizes to set and tuple comprehensions and generator expressions. Most evaluation in Python is eager, but there are several lazy constructs available. Typically we use generator expressions to create generators (a kind of lazy iterable), and functionality from `itertools` is designed to accommodate lazy iterables.

- Function composition is not supported out of the box, but it’s easy enough to implement simple cases using the above tools, and there are third-party packages for more robust solutions.

It is a maxim of Pythonistas that “practicality beats purity”. I personally have a fair affinity for functional style, and use list comprehensions in places that many other developers would write an explicit `for` loop. I even advocate for teaching list comprehensions to beginners first, as I sincerely believe they are easier to understand and analyze for most common cases than explicit iteration. However, when I write code I don’t try to avoid side effects and I certainly don’t succeed in doing so. Nor do I try to implement monads etc. or find myself wanting them. In the Python world, the assumption of imperative style for I/O is rarely questioned; it’s generally considered abusive to run a list comprehension (and discard the result) simply to cause I/O as a side effect, for example.

---

<div class="post-metadata">

**Author:** ![Tinche](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/tinche/32/12507_2.png) [@Tinche](https://discuss.python.org/u/Tinche)\
**Post date:** [November 10, 2023, 9:40pm UTC](https://discuss.python.org/t/python-as-functional-programming-language/38402/4 "2023-11-10T21:40:20Z")

</div>

> [@capymind](#):
>
> Although Python is not designed for “functional programming languages” at first (to be honest I only have shallow understanding about difference in approach, philosophy, toolkit between OOP, and FP…), Is it okay and possible(even recommended sometimes) to write software fully in functional way using Python?

My entire Python career and open source oeuvre (finally a chance to use this word) is based on prioritizing functions and function composition over subclassing and OOP, so it’s indeed possible albeit going against the grain somewhat.

That said, you probably won’t find a ton of support for monads and stuff like that. But just favoring functions as first class objects, falling back to classes when you must, can get you very far.

---

<div class="post-metadata">

**Author:** ![capymind](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/capymind/32/15179_2.png) [@capymind](https://discuss.python.org/u/capymind)\
**Post date:** [November 11, 2023, 4:19am UTC](https://discuss.python.org/t/python-as-functional-programming-language/38402/5 "2023-11-11T04:19:03Z")

</div>

I really appreciate you for sharing your opinions.  
Thanks for kind reply. It helps a lot for me.

> But it’s definitely possible to apply a functional style.

Yes, I will try to follow a functional style as possible as I can!

---

<div class="post-metadata">

**Author:** ![capymind](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/capymind/32/15179_2.png) [@capymind](https://discuss.python.org/u/capymind)\
**Post date:** [November 11, 2023, 4:31am UTC](https://discuss.python.org/t/python-as-functional-programming-language/38402/6 "2023-11-11T04:31:59Z")

</div>

Thanks for your kind and helpful comments! It’s awesome.  
The fact that function in python is first-class as you mentioned make me think it can be possible to write code in functional way.

> [@kknechtel](#):
>
> Function composition is not supported out of the box, but it’s easy enough to implement simple cases using the above tools, and there are third-party packages for more robust solutions.

Yeah… composition is key to functional programming I think.  
Composing functions, Composing types(algebraic type system?) bla bla…

It’s mind-blowing experience for me to watch pipeline-oriented and railway-oriented programming talks in Youtube (it’s all about composing functions), and see Rust’s official books about error and null? handling such as `Result`, `Option`.

I found the open source projects related to above things such as

- [GitHub - InvestmentSystems/function-pipe: Tools for extended function composition and pipelines in Python](https://github.com/InvestmentSystems/function-pipe)
- [GitHub - dry-python/returns: Make your functions return something meaningful, typed, and safe!](https://github.com/dry-python/returns)
- [GitHub - ForeverWintr/metafunctions: metafunctions is a function composition library for python.](https://github.com/ForeverWintr/metafunctions)

and many others.

I am a quite novice, so all thoses are not easy for me to understanding implementations and I want to build it by myself using plain, standard library python as possible as I can. I hope that It can be valuable for me to learn basic and core concepts about programming and python itself.

Anyway, thanks for your reply. I have learned a lot from you!!

---

<div class="post-metadata">

**Author:** ![capymind](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/capymind/32/15179_2.png) [@capymind](https://discuss.python.org/u/capymind)\
**Post date:** [November 11, 2023, 4:42am UTC](https://discuss.python.org/t/python-as-functional-programming-language/38402/7 "2023-11-11T04:42:42Z")

</div>

Hi, thanks for answering my (dumb) question.

My primary language is definitely not English.  
So I checked to oxford learner’s dictionary… Cool!  
I envy you for making open source oeuvre, I hope I can do it like you in the future.

> [@Tinche](#):
>
> so it’s indeed possible albeit going against the grain somewhat.

It’s totally understandable although it’s sad for me.

> [@Tinche](#):
>
> That said, you probably won’t find a ton of support for monads and stuff like that. But just favoring functions as first class objects, falling back to classes when you must, can get you very far.

Oh… I see. I wrote down your saying in my engineering daybook…!

Thanks again for sharing your thoughts.

---

<div class="post-metadata">

**Author:** ![onePythonUser](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/onepythonuser/32/19158_2.png) [@onePythonUser](https://discuss.python.org/u/onePythonUser)\
**Post date:** [November 11, 2023, 7:35pm UTC](https://discuss.python.org/t/python-as-functional-programming-language/38402/8 "2023-11-11T19:35:38Z")

</div>

Hello,

I have actually written embedded SW for microcontrollers using ‘C’. Now that I am learning Python,  
it appears that there is a strong emphasis for the OOP approach (especially for the application of the Tkinter module - I am sure it applies to other modules and Python in general). The main difference that I notice is that for python, you generally are strongly encouraged to create classes for everything (objects - inheritance, composition, etc.) with an emphasis on encapsulation.

With procedural programming for embedded applications, I never considered this in general. Writing programs for small embedded applications was generally written in a linear, procedural way. The closest I came to creating an object was creating C structures when I wanted to create multiple one to a few bit flags from one 16-bit structure (no reason to use a 16 bit/8 bit variable for example, if the flag’s value is only a ‘1’ or a ‘0’). Embedded applications tend to be memory (quantity) sensitive.

So, in a nutshell, kind of, in functional/procedural programming, we don’t worry about classes/encapsulation.

If you want to learn functional/procedural programming, try learning ‘C’.

---

<div class="post-metadata">

**Author:** ![defjaf](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/defjaf/32/12838_2.png) [@defjaf](https://discuss.python.org/u/defjaf)\
**Post date:** [November 11, 2023, 9:17pm UTC](https://discuss.python.org/t/python-as-functional-programming-language/38402/9 "2023-11-11T21:17:17Z")

</div>

Functional programming and procedural programming are _different_ paradigms:

> **[Procedural programming](https://en.m.wikipedia.org/wiki/Procedural_programming)**
>
> Procedural programming is a programming paradigm, derived from imperative programming, based on the concept of the procedure call. Procedures (a type of routine or subroutine) simply contain a series of computational steps to be carried out. Any given procedure might be called at any point during a program's execution, including by other procedures or itself. The first major procedural programming languages appeared c. 1957–1964, including Fortran, ALGOL, COBOL, PL/I and BASIC. Pascal an Compu...

> **[Functional programming](https://en.m.wikipedia.org/wiki/Functional_programming)**
>
> In computer science, functional programming is a programming paradigm where programs are constructed by applying and composing functions. It is a declarative programming paradigm in which function definitions are trees of expressions that map values to other values, rather than a sequence of imperative statements which update the running state of the program.
> In functional programming, functions are treated as first-class citizens, meaning that they can be bound to names (including local identif...

---

<div class="post-metadata">

**Author:** ![jamestwebber](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/jamestwebber/32/12799_2.png) [@jamestwebber](https://discuss.python.org/u/jamestwebber)\
**Post date:** [November 11, 2023, 9:17pm UTC](https://discuss.python.org/t/python-as-functional-programming-language/38402/10 "2023-11-11T21:17:53Z")

</div>

And C is definitely one of them and not the other.

---

<div class="post-metadata">

**Author:** ![Ardenine](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/ardenine/32/15025_2.png) [@Ardenine](https://discuss.python.org/u/Ardenine)\
**Post date:** [November 13, 2023, 10:22am UTC](https://discuss.python.org/t/python-as-functional-programming-language/38402/11 "2023-11-13T10:22:04Z")

</div>

> [@capymind](#):
>
> Is it okay and possible(even recommended sometimes) to write software fully in functional way using Python?

IMO  
Python is so powerful you can use everytime and everywhere a functional style, that’s one of the most impressive skills this languages has.  
Anyway, if you know OOP you’d probably never use a fully-functional paradigm approach (with Python), because of encapsulation, design patterns, low-level abstraction, etc.

---

<div class="post-metadata">

**Author:** ![sanderr](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/sanderr/32/9401_2.png) [@sanderr](https://discuss.python.org/u/sanderr)\
**Post date:** [November 13, 2023, 10:40am UTC](https://discuss.python.org/t/python-as-functional-programming-language/38402/12 "2023-11-13T10:40:10Z")

</div>

I typically try to use a functional programming style in Python as much as possible. But I think it is important not to force it. As others have already mentioned, `itertools` and `functools` are your friend. Iterators (although they’re stateful) can also support a functional programming style (just be aware of the iteration side effect). And try to limit side effects and make them explicit in docstrings. Some other things that have not been mentioned yet that fit well in the functional programming style in my opinion:

- `more-itertools`, more functions like the ones in `itertools`
- Frozen dataclasses (`dataclass` package) are (pseudo) immutable
- If you’re using type annotations, use the abstract types from `collections.abc` (e.g. `Sequence`) for function parameters rather than the concrete built-ins (e.g. `list`) to communicate clearly to the users of your functions that arguments will not be mutated.

These present a nice toolbox for functional programming, but in my opinion the other side is just as important: don’t force it. Python is not a purely functional programming language, and though it pains me sometimes, I will prefer an imperative style over a functional one in places where it just fits the language better. A good example are the built-in collection types (list, set, dict). They don’t have a functional manipulation API (at least not without creating an expensive copy), these operations have an inherent side effect. This makes it difficult to construct e.g. a dict by folding (`functools.reduce`) over another iterable. In these situations I will typically opt for a for loop, because it’s just more natural and more ideomatic, even if it still bothers me every time I have to do so.

So my advice would be to use the tools that are available and you’ll be able to use a functional programming style for a large part of your code. But whenever it feels like you have to go against the grain of the language itself, just make your peace with the imperative style and don’t force it.

---

<div class="post-metadata">

**Author:** ![capymind](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/capymind/32/15179_2.png) [@capymind](https://discuss.python.org/u/capymind)\
**Post date:** [November 13, 2023, 11:08am UTC](https://discuss.python.org/t/python-as-functional-programming-language/38402/13 "2023-11-13T11:08:58Z")

</div>

Thanks for sharing your opinion!  
I totally agreed with you that Python is so versatile, (making me lost sometimes…)

I know same problem can be solved using OOP if well coded, but that’s hard for me now.  
Maybe I am not good at OOP in python way. I think I have to put my efforts more deliberately into reading open source projects.

---

<div class="post-metadata">

**Author:** ![capymind](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/capymind/32/15179_2.png) [@capymind](https://discuss.python.org/u/capymind)\
**Post date:** [November 13, 2023, 11:17am UTC](https://discuss.python.org/t/python-as-functional-programming-language/38402/14 "2023-11-13T11:17:46Z")

</div>

Although I don’t get 100% understanding in your comment (becuase of my lack of python experience and skill issues), I get to the point of what you said in general.

I will write your saying below in my engineering daybook by hand.

> [@sanderr](#):
>
> So my advice would be to use the tools that are available and you’ll be able to use a functional programming style for a large part of your code. But whenever it feels like you have to go against the grain of the language itself, just make your peace with the imperative style and don’t force it.

It’ll take some time for me to get good taste on code written in pythonic way.

Thanks a lot! Your comment helps me a lot.

---

<div class="post-metadata">

**Author:** ![capymind](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/capymind/32/15179_2.png) [@capymind](https://discuss.python.org/u/capymind)\
**Post date:** [November 13, 2023, 12:31pm UTC](https://discuss.python.org/t/python-as-functional-programming-language/38402/15 "2023-11-13T12:31:07Z")

</div>

Thanks for sharing your experiences !!

> [@onePythonUser](#):
>
> try learning ‘C’.

I have tried to learn C many times because Python is 'C’Python (in addition to pypy, rustpython etc…) with always resulting in failure…

However, I will try it again someday…

---

<div class="post-metadata">

**Author:** ![fungi](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/fungi/32/5963_2.png) [@fungi](https://discuss.python.org/u/fungi)\
**Post date:** [November 13, 2023, 2:40pm UTC](https://discuss.python.org/t/python-as-functional-programming-language/38402/16 "2023-11-13T14:40:58Z")

</div>

As others have said, you won’t be able to do “pure” functional  
programming in Python the way you can in a language designed  
specifically for it, e.g. LISP. I’m not sure that really matters  
much for the utility of the language, though, and in many cases  
being able to mix in constructs that aren’t purely functional opens  
up the possibility to create superior solutions…

I started learning rudimentary computer programming in 1980. I’ve  
had no formal training, but simply used the tools available to me in  
order to solve problems that needed solving. The first languages I  
picked up were essentially procedural in nature, interpreters that  
came with my computer’s operating system. Later as I needed the  
performance boost of compiled programs, I experimented with  
functional programming because those were some of the compilers I  
could get my hands on. Over time, as portability became a concern  
for me I switched languages more and started to write in some that  
leaned into object oriented design.

I never really thought about procedural vs. functional vs. object  
oriented design paradigms back then, I simply looked at examples of  
source code similar to what I wanted to accomplish, played around  
with them until I gained an understanding of how they worked, and  
internalized that knowledge. These days Python is my go-to language,  
and a major reason is that it can be used in any of those ways (and  
more). You’re not limited to using one specific kind of programming,  
even within the same body of source code.

While the vast majority of problems you’ll encounter can be solved  
with a program written in any of those styles, no one style is  
superior to the others, and different styles are often better for  
different kinds of tasks. Unless your field is actually language  
theory though, my recommendation is to not worry too much about what  
style you’re writing in. Learn to use the language hands-on through  
solving problems that need solving, and when you come across a  
construct that you don’t understand play around with it until it  
makes sense to you.

As you learn, you’ll find cleaner and more elegant solutions to  
problems. Sometimes that will look “functional” from an academic  
perspective, sometimes it might look “procedural” or “object  
oriented” or a mix of those and more. You’ll internalize the  
algorithms, data models and relationships that work well in  
different situations, but you won’t really waste time thinking about  
whether what you’ve written is “proper” functional style. Making  
software that works as intended and is easy for others to understand  
is usually far more important than language theory.

---

<div class="post-metadata">

**Author:** ![ppentchev](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/ppentchev/32/11028_2.png) [@ppentchev](https://discuss.python.org/u/ppentchev)\
**Post date:** [November 14, 2023, 12:03am UTC](https://discuss.python.org/t/python-as-functional-programming-language/38402/17 "2023-11-14T00:03:36Z")

</div>

I completely agree with the balanced opinions above: it is completely possible (and quite easy) to write parts of your Python program in a functional style, but if one clings blindly to the ways things are done in languages where the compilers/interpreters are specifically designed for that, the resulting code may turn out to be a) difficult to read by others, and b) inefficient. @sanderr did an excellent “pros and cons” list; I’d just like to add that the expensive copies problem does not only affect lists and dictionaries, but also immutable values. I love dataclasses, I love frozen dataclasses with a passion, but the compiler is simply not designed to optimize for methods that consume the original object and return a slightly modified version - the original object still remains in memory for a while, the modified version is a copy. If one tries to write a complex program with thousands of such consumed-and-thrown-away objects, things start to pile up (of course, in a well-designed program each individual consumed object will be garbage-collected pretty quickly, but still).

Note that the above is NOT meant as a criticism of Python; as I wrote, it is not designed that way, and the things that it is designed for it does very well indeed.

---

<div class="post-metadata">

**Author:** ![majidaldo](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/majidaldo/32/12537_2.png) [@majidaldo](https://discuss.python.org/u/majidaldo)\
**Post date:** [November 14, 2023, 12:49am UTC](https://discuss.python.org/t/python-as-functional-programming-language/38402/18 "2023-11-14T00:49:02Z")

</div>

coconut, [Coconut — Coconut v3.0.3 documentation](https://coconut.readthedocs.io/en/latest/index.html), a python superset for FP,

and returns, [Features — returns 0.22.0 documentation](https://returns.readthedocs.io/en/latest/), a library that pushes the type system for FP

are the most notable in python land. both allow “practicality” by not imposing one way of programming (by virtue of being in python though).

---

<div class="post-metadata">

**Author:** ![kknechtel](https://avatars.discourse-cdn.com/v4/letter/k/e47c2d/32.png) [@kknechtel](https://discuss.python.org/u/kknechtel)\
**Post date:** [November 14, 2023, 2:37am UTC](https://discuss.python.org/t/python-as-functional-programming-language/38402/19 "2023-11-14T02:37:29Z")

</div>

> [@ppentchev](#):
>
> but the compiler is simply not designed to optimize for methods that consume the original object and return a slightly modified version - the original object still remains in memory for a while, the modified version is a copy. If one tries to write a complex program with thousands of such consumed-and-thrown-away objects, things start to pile up (of course, in a well-designed program each individual consumed object will be garbage-collected pretty quickly, but still).

This is a non-trivial problem even for languages that are explicitly designed for the paradigm. Of course, they generally do put a lot more effort into trying to solve it 😉

---

<div class="post-metadata">

**Author:** ![capymind](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/capymind/32/15179_2.png) [@capymind](https://discuss.python.org/u/capymind)\
**Post date:** [November 14, 2023, 8:32am UTC](https://discuss.python.org/t/python-as-functional-programming-language/38402/20 "2023-11-14T08:32:19Z")

</div>

Thanks for sharing your stories.  
I have learned a lot from reading your comment more than twice.  
It seems like a cheating to get invaluable lessons from others by just reading comments.  
However it’s useless if I failed to internalize good things by programming a lot with hard efforts on solving real world problems as you mentioned.

thanks, fungi.

[Next page](https://discuss.python.org/t/python-as-functional-programming-language/38402.md?page=2)
