We're trying to avoid programming language flamewars here, among other kinds of flamewar.
And I would argue that concurrency, at least, has no business in a textbook for true beginners.
Why on earth not? Lots of people begin by wanting to program a simple real time game and concurrency of some kind is absolutely required to do that.
Concurrency not being a first class feature of most mainstream programming languages and frameworks and being clunky in most of the rest is one of the biggest failures of language design in my opinion.
And lots of people program Arduinos and similar kit as their first attempt at coding now, are you going to tell them not to use concurrency?
It does not have the strong type guarantees of the ML or Haskell families; functional code in Python is fragile and complex.
Python lambdas, like those in virtually all functional languages, are a single expression.
Python expressions are somewhat limited (at least if one avoids non-idiomatic, and often somewhat ugly constructs) because Python isn’t a purely expression-oriented language, and the Pythonic way to do certain things involves statements. [0]
> no tail call elimination
True, then again, TCO has a clarity cost and lots of lisp family languages have either no TCO or self-call-only TCO, or kinda-self-call-only-TCO-via-explicit-recursion-constructs.
Python is metaprogrammable enough that you can do TCO via decorators (a couple of ways; I’ve seen mutual [1] and self-call-only done via stack frame manipulation decorators, and self-call only done even more efficiently via a bytecode injection decorator.)
> and hardly and FP in the standard library.
Not sure if you mean hardly any use of of support for; if the latter, it is simply wrong, if the former, I haven’t read much of the stdlib source code but who cares?
> It does not have the strong type guarantees of the ML or Haskell families
Which in turn don’t have the metaprogramming capacities of the Smalltalk-descended line of dynamic OO languages. Its not ignoring things to make choices that have tradeoffs.
[0] but note that this is mostly about idiomatic, not functional limitations, there is very little if anything that idiomatically uses multiple statements in python that can’t be done in a single expression using only language-level expression elements plus built-in and stdlib functions
[1] that is, general but all participating functions must be decorated.
It progressively deemphasized some popular FP patterns (largely in favor of comprehensions, which have also been adopted in many newer functional languages.)