6 ms·
So I felt really torn with this. I applaud the author for introducing Python devs to FP; I love functional programming. Python was one of the things that opened
by dev360 13y ago
So I felt really torn with this. I applaud the author for introducing Python devs to FP; I love functional programming. Python was one of the things that opened my eyes to FP with its cute little m/r syntax and for that I'm forever grateful.
Over the years, I have found that python code that people write to solve problems will fall in roughly four categories: a) completely ignorant and inefficient code; b) concise, idiomatic python code with a focus on readability; c) fancy functional code where the author is showing off their FP savvy (peppered with recursion and m/r); and d) raw, boring C-influenced code that looks primitive and boring to read, but is incredibly efficient and algorithmically sound. As much as I used to love going for b), I then prided myself for writing c). But last few years I have realized how under performing c) is for most serious work, so I tend to avoid it and try to strike a balance between d) and b), but preferably the latter. To write code in c) and tell yourself, well the data size will never be so great that the stack will blow, or memory will suffer, is in many ways just like avoiding null checks all together and saying to yourself your data will always have perfect integrity... e.g. any sane person will tell you that you cannot rely on this mindset in the long run.
So, for me at least it comes down to this: to try to pretend that you can write FP code effectively in Python is an exercise in futility. FP is more than writing a map and reduce. If thats your basis of reasoning, yeah I agree take that and run with it - I find m/r to be a neat syntax to use here and there in your program but its really challenging to write a whole program in python that is composed of several chained map / reduce functions to a large extent because things are not oriented around generators by default.. I'm not saying its impossible, just that it goes against the grain. I also argue that recursion and guard expressions (and lazy evaluation) are at the heart of the FP paradigm and if you want to do it right, then its just retarded to sit and do this in Python when there is no tail recursion.. how are you going to appreciate this concept when its so limiting?? If you want to muse yourself and marvel at pretty code, write it like this and have fun with it, but please pick another language if you want to actually ship production code.
And ... so sorry to piss on the parade.
- tome 13y agoYour comment is very close to how I feel. I spend significant effort trying to shoehorn FP concepts into Python, because I wanted to use FP but was forced to use Python. In the end I decided to quit my job so I could use Haskell instead. Programming FP in an actual FP language is much more satisfactory!
- tomrod 13y agoI'm very much working on leaving the first category. That's the problem I guess with teaching oneself a language with no code review.
- sixbrx 13y agoYeah, i gave up on doing fp (or any mathematics) in python when I got surprised by this: >>> monomials = [lambda x: x(star)(star)i for i in [1,2,3]] #(not sure how to escape stars for exponentiation properly, whatever) Those all end up being the same monomial because the integer i is captured by address and not given a new binding for every iteration. Very surprising, and an accident waiting to happen for anyone used to dealing with integers by value (hard to say that with a straight face). The hackish workaround is "lambda x,i=i: x(star)(star)i" but I'd forget it all the time.
- tome 13y agoWoah, I was aware of the name capture problem in closures, but I hadn't realised this was one of the consequences. That's very unfortunate.
- zanny 13y agoThis is just like how python default values are global variables that if you modify over time (ie, def foo(x = []): x.append(0), the second iteration x would be [0,0], because it is only initialized once.