Granted, it would be unusual to see all, or even most, of those in one place, but they see use enough that calling python bad a functional programming is a little odd. I'd say it's pretty good at functional work in the small while somewhat ill suited in the large.
There's a much better discussion over here
http://stackoverflow.com/questions/1017621/why-isnt-python-v...
If you define "functional style" as writing Lisp or Haskell programs using Python syntax, I agree they look horrendous.
Here's my favored source (in the Standard Library) https://docs.python.org/2/library/collections.html#collectio...
> and what do you do when every third party library you interact with uses mutable ones?
That's situational; which library are you having a problem with? I haven't really had that problem (okay, sometimes the tooling around web frameworks do stupid things, but that's not common).
Note that just because something is mutable doesn't mean you have to mutate it. Yes, Python doesn't as widely enforce non-mutation as Haskell, OCaml, etc., but that doesn't mean that suddenly all the Python programmers lost their minds and started mutating all the things. We're not savages.
I agree, and I don't mutate it, but my third party libraries and my collegues functions will. Not all of them, but enough to introduce annoying bugs.
You've claimed that third party libraries and your colleague's functions will mutate the data structures you pass them, but this has very rarely been my experience.
[EDIT: I shouldn't impugn my coworkers: I had trouble resisting the siren call of side effecting functions!]
Sadly I've seen functional operations like map/filter/reduce etc discouraged in (commercial) projects I've worked on, though I guess there's a bit of an argument there for debugability (make it a word?) since hunting down side effects may be more onerous?
[fn(a) for a in seq]
for example or [a for a in seq if pred(a)]
and so map and filter are 'old'-style and deprecated. But I have to agree, I think that's not a clear benefit. For example map(fn, seq)
and filter(pred, seq)
are clearer. Once you get more complex, however, the comprehension syntax does shine.Comprehensions don't help at all with reduce, of course, which has been tidied out of __builtins__ now.
Are map and filter more concise? Yeah but only in this case. If you would need to do some processing, they would get messy fast because of a lambda.
On the second point. I agree. Python's lambdas are a code-smell, for me. Which I don't say lightly, I'm a Scheme/Lisp guy deep down. But they fundamentally work against the aesthetics of the Python language, imho. A local function declaration is much less fragile.
But I would say that as code complexity increases, in my experience, comprehensions don't last long either. They've a narrow range of applicability before you get a big block of spaghetti code. Then it is much better to define a local function and, essentially, 'map' it (even if that 'map' is done as comprehension). Of course, YMMV.
>> x = 5
>> [x for x in range(10)]
>> x # => 9 Python 2.7.10 ...
>>> a = 3
>>> [a for a in range(10)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> a
9
>>> a = 3
>>> list(a for a in range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> a
3
Guido called it Python's 'dirty little secret'. It is fixed in Py3 though. (defmacro dict-comp
[bindings & body]
`(into {} (for ~bindings (do ~@body))))[0]: http://python-history.blogspot.hu/2009/04/origins-of-pythons...
[1]: https://docs.python.org/3.2/library/functools.html#functools...
I've written tens of thousands of lines of code in a functional style in Python, and while it's different from Scheme and takes a little getting used to, Python is a very capable programming language for functional programming.
It does lack tail call optimization, but I think you'd find that even in Scheme, most times where you would write a recursive function, you should be writing something with one of the higher-order functions. 99.9% of recursive functions contain a buggy hand-rolled implementation of map, reduce, or filter. Scheme is a more academic language, so it makes sense for them to include this feature, which gives language users the same power as the language creators. But Python is intended for professional development and as such, it makes sense to force users into a better style.
[1] http://learnyousomeerlang.com/recursion [2] http://www.fastcompany.com/3026758/inside-erlang-the-rare-pr...
From your sarcastic tone it seems like you take issue with something you think I've said, but since your post is unrelated to anything I actually said, I can only guess that you've inferred some meaning that isn't there.
Sometimes, it's just the clearer way to get the job done. I realize it is these days considered "un-Pythonic" to consider there to be more than one way to do something, but that is in fact one of the reasons why I no longer use Python. The attitude of its creator and its community have shifted against creative solutions and I have no use for that attitude in a technology field.
> The point is, the idea that it's somehow "unprofessional" to write a recursive function is an absurd assertion.
...which is why I didn't say that. What I said was, "[E]ven in Scheme, most times where you would write a recursive function, you should be writing something with one of the higher-order functions. 99.9% of recursive functions contain a buggy hand-rolled implementation of map, reduce, or filter."
There are certainly cases where writing a recursive function is cleaner, and I would never say it's "unprofessional" to write a recursive function. However, I've debugged enough Scheme to know that if you're writing a recursive function you're probably reimplementing one of the core higher-order functions, and in doing so you're increasing your chance of bugs. You're also making your code less composable. If you're not experience enough with Scheme to have recognized this fact yet, you're probably not experienced enough to recognize exceptions to the rule.
> Many, many functional languages beyond just "academic" ones use recursion as a standard idiom, and using that to dismiss Scheme is itself an inflammatory statement especially on a site that is literally running on top of a Scheme derivative.
Scheme is my favored language for personal projects. I write more Python because there's more work available for Python, but when it has been my choice I've chosen Scheme. The reason I've written so much Python in a functional style was because I learned that style from Scheme. So if you think I'm dismissing Scheme, you're hilariously wrong. My statement isn't inflammatory; you became inflamed all on your own.
> I realize it is these days considered "un-Pythonic" to consider there to be more than one way to do something, but that is in fact one of the reasons why I no longer use Python. The attitude of its creator and its community have shifted against creative solutions and I have no use for that attitude in a technology field.
Cool. I thought I was the one being inflammatory.
It seems that you saw me say, "Scheme is a more academic language" and decided to take offense to that. Well, news flash, Scheme was designed at the MIT AI Lab. It's an academic language. That doesn't mean it's a "toy language" or that it's only an academic language; I didn't say either of those things. It's also ridiculous that you needed to bring Erlang into the conversation to defend Scheme: Scheme has plenty of history of professional use at both HP and Sun and is perfectly well respected in its own right.
Please try to learn something from this experience.
reduce = 0
is valid. But really it doesn't matter.