4 ms·
It's a shame that someone can become so misguided about functional programming. Functional programming isn't about destroying readability. It's actually the opp
by ebingdom 5y ago
It's a shame that someone can become so misguided about functional programming. Functional programming isn't about destroying readability. It's actually the opposite; it enhances the ability to reason about code by (a) being disciplined about where side effects are allowed to happen, and (b) leveraging reusable abstractions for common patterns (e.g., transforming each element of a list, building a generic container that can be used for arbitrary types without sacrificing type safety, etc.) rather than re-inventing them every time with copying and pasting. Generally, functional programs are safer and shorter than their procedural/OOP alternatives, which is a good thing. Less code means fewer places for bugs to hide.
- ramenmeal 5y agoIn this article, which code sample would you say is more readable? The imperative style or the functional style?
- viraptor 5y agoTheory vs practice for the specific language. Here, the extra signatures and unnatural patterns destroy the readability. It could still be better though if you have, for example a number of pipelines for your data. There, the reuse of Sort/Group/Frobnicate/... in close by blocks would actually be nicer. But yeah - the more extra syntax is required for those pattern, the worse they are in practice. (or, the more things you have to abstract in a small range to make it useful)
- ebingdom 5y agoI would say the imperative version is easier to read in this article. The functional version doesn't really illustrate the benefits of functional programming very well, IMHO. I think there are two issues that reduce the effectiveness of the example: 1. Both examples contain a bunch of extra logic that has nothing to do with the difference between the two styles. For example, the code that converts users to that `UserLevelPoints` struct takes up a lot of space in both examples and is essentially the same in both. I think it would have been better (for pedagogical purposes) to just return the users (or perhaps a simpler struct containing a level and a user). 2. Both examples still have all the verbosity that is typical of imperative code, since it's still Go after all. If one were to write the same function in a syntax which was designed for functional programming, the result might look something like this: topUser = head . sortBy points topUserPerLevel = topUser . values . groupBy level I find this vastly quicker to read and understand than either of the examples in the article. But that relies on me knowing the functional-optimized syntax (e.g., that the `.` operator is just function composition), and for most imperative programmers that is the main hurdle. Since I am familiar with both styles, I can tell you that this would take me about 6 seconds to understand, whereas understanding each of the examples in the article took me at least a minute to even read the code, let alone understand it—and if there were bugs I wouldn't have noticed. In contrast, with the simple functional version I provided, I can read it in seconds and be reasonably confident that it is correct (assuming all the pieces fit together in a valid way, which a type checker can check for me). If the unfamiliar syntax prevents you from grokking the example I provided, it's reasonable to assume it's just some clever code golf that should be discouraged in production code. But please resist that temptation; this is actually what good code looks like. It's simple, not repetitive, and there aren't many places for bugs to hide.
- cle 5y agoOne person's readable code is another person's unreadable mess. It depends on what kind of program you're writing. The fact that functional programming emphasizes "abstraction" so much means that, by definition, you're further away from what's actually happening. So looking at some declarative code it's not immediately obvious what the computer will actually do. The kinds of programs I write require me to care about that deeply. So when I see declarative code all I see is a giant question mark as I wonder what in the world the computer will actually be doing when it executes that code. Anyway, my point isn't that one is better than the other, it's that it depends on what you're doing. For some of us, the higher levels of abstraction are actually less readable.
- ebingdom 5y agoI think this is a reasonable point, and of course you could take it further and say that assembly language is better than functional programming when you're doing work that requires you to reason about what the CPU is doing exactly. But I would argue that the majority of Go programs should not require the programmer to follow the intimate details of a program's execution when trying to understand the business logic. The fact that the language has a garbage collector would suggest that it was designed for programs where some details can be hidden away. So I agree with your general point, but I am somewhat skeptical about its application to Go.
- nexuist 5y agoIf the lack of abstraction is a requirement, why use a language like Go at all? Shouldn't you be using C for these sort of projects?
- cultofmetatron 5y agozig is also a really good contender in this space as well. it also maps fairly cleanly to assembly while providing a bit more safety.
- kaba0 5y agoThe only thing that makes programming any useful program even remotely possible is abstractions. The human brain simply breaks down even at the fraction of the complexity of any non-trivial app. There is wrong abstraction, and over-abstraction that can obscure a codebase, but it is orthogonal. And no, you can’t write simpler code, there is essential complexity, that can’t be reduced. Also, it’s kind of laughable to think that writing code in a high level language with a runtime, GC, etc, you have any idea what will happen at execution.
- mappu 5y agoAll true, but the dichotomy here isn't between functional and imperative - it's between imperative, and a mix of both.
- amw-zero 5y ago> it enhances the ability to reason about code In your opinion. > Generally, functional programs are safer and shorter than their procedural/OOP alternatives Please provide any evidence that this is true, especially the ‘safe’ part. Any study I’ve read says there’s almost no effect on language choice at all on bug rate.
- ebingdom 5y ago> > it enhances the ability to reason about code > In your opinion. Correct. But my opinion is informed by years of experience with functional programming, procedural programming, and OOP (each). > Please provide any evidence that this is true, especially the ‘safe’ part. Any study I’ve read says there’s almost no effect on language choice at all on bug rate. Sure, here is a paper which provides the evidence you're looking for: "A Large Scale Study of Programming Languages and Code Quality in Github" (https://dl.acm.org/doi/10.1145/2635868.2635922 https://dl.acm.org/doi/10.1145/2635868.2635922). That paper concludes: > The data indicates functional languages are better than procedural languages; it suggests that strong typing is better than weak typing; that static typing is better than dynamic; and that managed memory usage is better than unmanaged. I personally don't trust academic studies on programming language effectiveness, since they often contradict each other (e.g., https://arxiv.org/abs/1901.10220 https://arxiv.org/abs/1901.10220 contradicts the paper I cited above). But if you're looking for a peer-reviewed paper, there you go. Choosing the right paradigm absolutely has an effect on the bug rate. If you have to write more code, repeat code, or deal with low-level details irrelevant to the problem at hand, you are going to make more mistakes. On top of that, functional languages often have better type systems than procedural/OOP ones, which helps with bug catching that much more. Taking this to extreme, with dependent type systems you can actually verify arbitrary mathematical properties of your programs. How much experience do you have with functional programming? I have professional and academic experience with both functional programming and OOP, and everyone I've met with that experience agrees about the trade-offs I've been discussing in my comments.