Programming and thinking the functional way
11–20 of 86 posts
Re: Programming and thinking the functional way
#12It boils down to the choice between these two alternatives: 1) If it's simple to imagine the computer doing something, it should be easy to program. 2) If it's simple to analyze something mathematically, it should be easy to program. The first path leads to C-style programming with pointers and loops. The second path leads to lazy pure functional programming and beyond. Personally, I'm in the first camp. Small functi…
Re: Programming and thinking the functional way
#13Writing quicksort non-functionally doesn't HAVE to be unreadable. Not that I disagree with Haskell being great and all, I just think it's important to realize that imperative != ugly code. public class QS { public List Quicksort (List l, Comparator comp) { if (l.size() lesser = new ArrayList (); List greater = new ArrayList (); T pivot = l.get(0); for (T t: l) { if (comp.compare(pivot, t) out = new ArrayList (); out.…
Re: Programming and thinking the functional way
#14It boils down to the choice between these two alternatives: 1) If it's simple to imagine the computer doing something, it should be easy to program. 2) If it's simple to analyze something mathematically, it should be easy to program. The first path leads to C-style programming with pointers and loops. The second path leads to lazy pure functional programming and beyond. Personally, I'm in the first camp. Small functi…
Most of that has to do with optimizing for reuse and proper type inference. It's a cheat to expose the Haskell subtyping relation for more leverage.
A better way to understand lenses should be to consider a package like lens-family-core which keeps to its roots.
Re: Programming and thinking the functional way
#15"Wow. i's and j's all the way, what is this? Why is it so long compared to the Haskell example? This looks like comparing C and assembly 30 years ago! And in some respects, it is the same leap." I don't think this is a fair comment considering the in-place Haskell implementation isn't incredibly readable either.
Re: Programming and thinking the functional way
#16It boils down to the choice between these two alternatives: 1) If it's simple to imagine the computer doing something, it should be easy to program. 2) If it's simple to analyze something mathematically, it should be easy to program. The first path leads to C-style programming with pointers and loops. The second path leads to lazy pure functional programming and beyond. Personally, I'm in the first camp. Small functi…
Cf http://ro-che.info/articles/2014-04-24-lens-unidiomatic.html
Re: Programming and thinking the functional way
#17Creating an entire class for the Java version is kind of a disingenuous comparison.
Re: Programming and thinking the functional way
#18The good:
1) The definition of the algorithm is clear. It shows "how quicksort works."
2) It's trivial to see (and prove) that the function will terminate, and almost as trivial to prove that it will result in a sorted list. So, it is easy to show correctness.
3) The polymorphism makes this an easily reusable function right out of the box.
The bad:
1) That implementation is very inefficient. At a glance I think it would be O(n^2) time. (Edit: this is misleading, because it's only O(n^2) in the same way that quicksort is always O(n^2). It is inefficient in terms of memory usage, though. And possibly other ways; for instance, I'm not sure how laziness would affect this. But I don't want to be spreading FUD...)
2) The "efficient" implementation given at the bottom is just as inscrutable as any other quicksort implementation I've seen. More so because of the monadic code, single-letter variables (pr?) and opaque library function calls (unsafePartition?) being made. And I'm not even sure that it would work on a list, although since V.Vector appears to be a type class, perhaps list is an instance of it.
3) Both the efficient and inefficient implementations are concise in large part because of their use of library functions. This is often a good thing: Haskell provides a great way to abstract things because of its parametric and ad-hoc polymorphism, and allows for a lot of reusable code. But it comes at a cost too, which is that the actual instructions you're giving to the machine are very far removed from what the computer is doing. Who knows how much code is actually executed, how deep the rabbit hole goes, to translate those beautiful 4 lines into actual machine instructions? With Java, it's precisely visible what the machine is doing to execute your code. This is much less the case with Haskell.
I suppose you could say (broadly) that functional languages excel at expressing what your program should do, while imperative languages excel at expressing how your program should do it. There are cases when you care more about the former, and cases when you care more about the latter. The reason I take issue with the quicksort example, is that list-sorting is a case where you definitely care more about the how than the what.
-------------------
EDIT, since two people called me out on it: It was an overstatement on my part to say that it's "precisely visible" what your Java code will translate to, but to suggest the two languages have the same degree of abstraction from the CPU is ridiculous. The code translation from Java to bytecode is quite straightforward, because most of the optimization occurs at runtime with JIT. There is a reasonably direct relationship between the code you write, the bytecode it gets translated into, and the instructions executed at runtime. At the end of the day, Java code consists of a series of instructions for the computer to follow, while on the other hand in Haskell, you aren't even technically giving instructions at all -- you're just writing equations. Compiled Haskell code is completely inscrutable.
Also, I should note that I am an enthusiastic Haskell hobbyist, and write it on almost a daily basis. Although I might not come across it here, I am a huge fan of the language; outside of the languages I use at work, by far the one I use most is haskell.
Re: Programming and thinking the functional way
#19The Java example builds up a straw man. Never underestimate your readers!
Re: Programming and thinking the functional way
#20It boils down to the choice between these two alternatives: 1) If it's simple to imagine the computer doing something, it should be easy to program. 2) If it's simple to analyze something mathematically, it should be easy to program. The first path leads to C-style programming with pointers and loops. The second path leads to lazy pure functional programming and beyond. Personally, I'm in the first camp. Small functi…
You make it sound like we've figured out how to write imperative large programs in a readable way.