Even things like tail call elimination, he said, would just encourage people to use more recursion, when iteration was easier to read, and in places where TCE would work, the programmer could obviously convert it to iteration himself and should do so for code clarity.
I like Python, and I like a lot of things about functional programming, so it wasn't the answer I was hoping for. Unless Guido has had a change of heart since then, I wouldn't pin my hopes on Python ever becoming a first-rate functional programming language. It's first rate at the things Guido values.
Decorators are another example of functional programming added to Python, but with a pythonic syntax.
Python supports both imperative, OO and functional idioms, but generally only prefers one of them for a specific task. For example loops are preferred to recursive functions when appropriate. Objects are preferred to closures for mutable state, so mutation of captures variables has not been supported (support have been added recently with nonlocal, but it has clearly not been a priority).
Python is interesting because it is multiparadigm while trying to avoid fragmentation where you can solve the same problem in totally different styles.
There's a quote from Guido about private attribute access where he said, "We're all adults", and that leaving the open is beneficial.
Recursion is another tool that he should let us adults use if it solves a problem better and TCE is lovely feature to have. Frankly, if you're using recursion, you either just learned it in a CompSci class or you know what you're doing. Either way, daddy Guido shouldn't tell us no :).
Anyway, at the very least there's two camps. On the one side, you have the hardcore Scheme folks whose conception of functional programming is "if I can't figure out how to write it with tail recursion it must not be computable". On the other side you have the Haskell folks whose conception of functional programming is "a monad is just a monoid in the category of endofunctors, what's the problem?"
Somewhere in between are people who actually get things done.
I started doing a lot of programming in CoffeeScript a few months ago, and between the JS underpinnings and the CS syntax you can do things that would just be painful in Python.
Aside from mutability, though, tuples can do pretty much anything lists can, and usually a bit more efficiently.
Immutable dicts can have stuff added and removed in O(log n) time, without affecting previous versions.
Scala's immutable vectors can have appending/prepending/concatenation/splitting/insertion/deletion in O(log n) time, without affecting previous versions. it's log base 32, so for any arrays using integer indexes, it'll never go above ~7, so it's basically constant.
Basically, you get (almost) the performance of mutable data structures, except you don't mess up the old versions of the thing every time you change something. It's really pretty incredible, the performance characteristics people manage to get with structural sharing: http://www.scala-lang.org/docu/files/collections-api/collect...
The new ConcurrentTrie is also a great addition to 2.10.
here are some different ways to implement functional sequence operations without native python syntax like `yield`:
https://github.com/dustingetz/sandbox/blob/master/etc/lazy.p... https://github.com/dustingetz/sandbox/blob/master/etc/map.py
and an unfinished, sloppy impl of monads in python with lots of minor errors:
http://www.dustingetz.com/2012/04/07/dustins-awesome-monad-t...