Several months ago, I attended PyCon Thailand 2018 to give a talk on Coconut, a function superset of Python for functional programming.





The following is a brief afterthought

about functional programming in Python.

Although we do not use Coconut in production, I still believe that it is an important project that identifies the shortcomings in writing functional style code in Python. It is not uncommon to hear that, with first-class functions, Python qualifies as a functional programming language. There is some truth to the statement. However, only a handful of people would disagree that writing functional code in Python is not ergonomic or even Pythonic (read: idiomatic). Python certainly allows you to write functional code, but it does not make it easy for you to do so. I would like to argue that the latter is more important when we would like to call a language functional, which makes Python not a functional programming language.





To unpack ‘functionalness’ further, we need to pin down what is it that makes a functional language functional. The essence of functional programming is the absence of mutability

It may thus sound paradoxical that having first-class functions does not make a language a functional in and of itself. Only to the extent that it helps us programme without states, it should then be considered a functional feature. Indeed, it is not difficult to imagine a programme written with many layers of higher-order functions only to perform mutation in every layer. Such programmes cannot be considered to be functional. There is nothing paradoxical about this if we do not make the mistake of thinking that functional programming is about programming with functions, as we hear so often.



In the talk, I claimed that Haskell is the gold standard for functional programming. Not only does Haskell make it easy to write stateless programmes, it goes one step further by making it really hard to mutate variables. However, we do not need to go to such extremes in order to write functional code. Clojure should be considered an extremely good functional programming language for its immutable-first approach (and Lisp obviously rocks!). In particular, it is convenient and idiomatic to have no mutations without making it hard to mutate variables. Python can never be like Haskell, but one can dream of having nice immutable data structures. After all, it is easier to be “consenting adults” when immutability is the default.





Is Python’s future functional?

Despite the constant surge of FP popularity, Python has been stubbornly resistant towards it. In one of his famous weblogs, Guido went so far as considering to remove `lambda`. Furthermore, the removal `reduce` would not have been so alarming if it weren’t for the former BDFL saying that it is hard to understand. Such mindset is quite the opposite to that of some FP enthusiasts that challenge us to learn higher-level abstractions (higher than `reduce`!). I find this perspective rather refreshing. Finally, it is not entirely accurate to say that Python has not adopted any functional features. The recent addition of `dataclass` in Python 3.7 and assignment expressions in Python 3.8 are clearly welcomed from an FP point of view.

Tags: