7 ms·
Why learning Haskell/Python makes you a worse programmer (2006)
- iofj 11y agoI do actually experience this : functional style is shorter, more effective, and more bugfree, and you can do it even in Go (if you're willing to copy bits to compensate for lack of generics). However, there is a large class of programmers that will kill you on the code review if they see this. Mostly I think it's for lack of understanding, or I've gotten comments complaining exactly that it's not imperative code. Unless you're willing to educate your colleagues, the post may have a point : learning functional style will improve your programs but seriously increase your frustrations.
- elcapitan 11y agoThe post sounds like an instance of solving the wrong problem. If you can write more concise, elegant and bug-free code, but all your colleagues can't deal with it and want to stick with their stuff, you're probably in the wrong place. On the other hand: Python doesn't exactly impress me as a particularly "functional" language. The examples are not as straightforward as the Haskell examples. Python uses a weird mix of OOP, imperative and functional programming, and this creates mental strain for everybody who has to read it. When I switch from Ruby to Python, I usually enjoy the simple imperative-pseudo-code like way of how the most idiomatic code there works. Then when I go back to Ruby I'm happy to use idiomatic metaprogramming, chained blocks of code etc. The same is true for Go and probably part of the current fascination of the dev community with the language (because it's proud of constraining complexity of expression).
- accountt 11y ago> Python uses a weird mix of OOP, imperative and functional programming, and this creates mental strain for everybody who has to read it. I used to think so until I came across Oz. It's Prolog, Lisp and Python all in one nice package :) Granted, it's more of an educational language, still though, Oz is a mind-stretcher.
- falcolas 11y ago> and this creates mental strain for everybody who has to read it. Really? I find it just the opposite. List comprehensions are broadly welcomed instead of one- or two-line for loops, lambdas are quite useful in the right context (such as sorting, list comprehensions, etc), and functions are a first class citizen, and easily used (and recognized) as such. It just lets me use the right tool for the job, without having to switch languages. And since the functional bits have been baked in for so long, it's easy to do. And let's be fair, you can't say that there's cognitive overhead to functional programming in Python while claiming Ruby does not. Both languages have nearly identical capabilities in this regard (though, I do miss Ruby's multi-expresssion lambdas when in Python).
- contravariant 11y agoBy now you can do better in c#. You can do the following, for instance: mylist.Select(item => item.description) .Where(descr => descr != "") .Aggregate(a,b => a + "\n" + b) Edit: I guess those features weren't available at the time of this article? Haven't used c# for long enough to be sure.
- kidmenot 11y agoCorrect, in 2006 there were no LINQ, extension methods and a number of other great improvements which kind of makes the article less valuable. Not that it was terribly valuable to begin with: as a programmer, using the language at hand to write code that 1) works and 2) is as clear as possible is exactly your job. Emulating other languages because of feature envy is really stupid, the first C# snippet is a prime example of this. I would not want to work with someone who deliberately makes the code harder to read in order to mimic his/her own favorite language. Every language has its idioms, just learn them and quit bitching. As a side note, the example chosen was particularly poor because, if the collection contains a huge number of items, concatenating them without a StringBuilder in .NET land is a terribile idea.
- lawl 11y agoI know this is 10 years old, So the more interesting thing to me is that these days you can do this functional style in most languages, even Java! foo.stream().filter(s -> !s.isEmpty()).collect(Collectors.joining("\n")); So I'd say it didn't make them a worse programmer, it's just that the languages were/are behind. Edit: Yup, forgot to map the description, but I'll leave it now.
- d--b 11y agoor in C#: string.Join("\n", foo.Select(x => x.Description()).Where(x => x != ""))
- teh64 11y agoYou forgot the map operation (and I would also filter out nulls): (just to be pedantic) foo.stream() .filter(s -> s != null) .map(s -> s.description()) .filter(s -> !s.isEmpty()) .collect(Collectors.joining("\n"));
- dozzie 11y ago> [M]y experience with Haskell means that I now see potential bugs everywhere in imperative code. [...] Now I know there are other ways of doing these things, I find it difficult to be satisfied with any of the code I write. I am constantly aware that I am writing traps that other people are likely to fall in. Good. That's exactly what it was supposed to do to your mind. Now you need to learn to live with this awareness, and you need to learn how to minimize the amount of traps you leave behind. > I also find C# code very ugly compared to both Python and Haskell. On the visual level, the mandatory use of braces everywhere [...] makes code contain a lot of line noise and empty space, and combined with the verbosity of the libraries and type declarations etc, you find that a page of C# hardly does anything. Learn two or three more languages and you'll find that this visual clutter hardly matters. What's important is how much can you do with the same amount of statements and expressions (I find Paul Graham's proposition that this is related to the count of AST nodes appealing). > 2. Using functional style obfuscates your code when using other languages. This sounds like the really old programming joke: "good programmer can write in Fortran in any language". Some constructs are not a good fit for some languages. I avoid map(), filter(), and reduce() in Python like the plague, but I find list comprehensions appropriate. You need to learn to switch between paradigms and sets of idioms, not to cram the same set everywhere.
- douche 11y ago> > I also find C# code very ugly compared to both Python and Haskell. On the visual level, the mandatory use of braces everywhere [...] makes code contain a lot of line noise and empty space, and combined with the verbosity of the libraries and type declarations etc, you find that a page of C# hardly does anything. > Learn two or three more languages and you'll find that this visual clutter hardly matters. What's important is how much can you do with the same amount of statements and expressions (I find Paul Graham's proposition that this is related to the count of AST nodes appealing). I would agree that if you follow the official Microsoft C# style conventions, you end up with some ugly looking, noisy code. I am not a fan of sticking opening braces on their own line, or forcing a newline between closing braces and else, catch, finally keywords. It is just a waste of too much vertical space, for questionable benefit.
- d--b 11y agoWhere it does make you a worse programmer however, is when you don't realize that using the join method on an iterator means that you are going to concatenate a whole lot of strings, while in most cases, you actually could know the size of the final string from the beginning, and you don't need to allocate a whole bunch of arrays in the process. These idioms have a complete disregard towards performance.
- victorNicollet 11y agoMany operations are optimized for typical use cases, for instance calling C# `string.Join` on short iterators will allocate no memory beyond that of the final string. The definition of "short" may be obscure (result is less than ~350 characters), but the optimization exists and is documented for anyone who cares enough about the tools in their toolbox. I do agree with your general point, though. I remember a one-line change in a Haskell function that led to a 10x increase in performance: https://news.ycombinator.com/item?id=6912474 https://news.ycombinator.com/item?id=6912474
- Singletoned 11y ago> These idioms have a complete disregard towards performance. As they should. "Premature optimization is the root of all evil".
- thejaredhooper 11y agoThe actual quote is "premature emphasis on efficiency is a big mistake which may well be the source of most programming complexity and grief." The 'summarized' catch-phrase always bothers me; the choice between optimized code and inefficient code is always clear to me.
- user51442 11y agoThe "premature optimization" quote is from Knuth's Turing Award lecture: http://delivery.acm.org/10.1145/370000/361612/a1974-knuth.pdf http://delivery.acm.org/10.1145/370000/361612/a1974-knuth.pd... "The real problem is that programmers have spent far too much time worrying about efficiency in the wrong places and at the wrong times; premature optimization is the root of all evil (or at least most of it) in programming."
- bad_user 11y agoHaskell and Python are two languages that couldn't be more different. Are there developers that prefer both and constantly switch between them? Besides the obvious that Python has one or two cool libraries, why would anybody willingly do that?
- lmm 11y agoThey both allow you to naturally express idiomatic-functional code (in their own ways) in a way that you can't (or couldn't until recently) in C#/Java/etc. The Python and Haskell versions of the method example from the post look much more similar to each other than either does to the C# version. There was a time when I wrote Python and ML and switched between them. Python had good library support and was slightly faster to write (I was fearless back then, but it seemed to work out ok), particularly for basic CRUD-type tasks. For cases of more involved business logic (really, any business logic at all) I needed higher correctness guarantees and would switch to ML. It worked well enough.
- rprospero 11y agoHello, I'm that guy who voluntarily writes a mixture of Python and Haskell in his day job. For me, it's about recognizing the strengths in both languages. You mentioned Python having "one or two cool libraries", but that's quite an understatement if you're doing any sort of numerical work. NumPy and SciPy are incredibly powerful, fast, and consistent. While hMatrix and Accelerate are both wonderful packages and have made some great progress, they don't have nearly the community support that Numpy does. On the reverse side, when I'm dealing with any sort of interactive system (e.g. Web Scraper or Motor Controller), I immediately reach for Haskell, since it makes those kinds of applications so much easier. For me it's mostly about just finding the right tool for the job. And trying to avoid any job where the right tool is Fortran.
- exDM69 11y ago> On the reverse side, when I'm dealing with any sort of interactive system (e.g. Web Scraper or Motor Controller), I immediately reach for Haskell, since it makes those kinds of applications so much easier. I find this a bit surprising... can you tell a bit more about these projects? I tend to do the opposite, I reach for Python when I need interactive stuff or need to interface with the "real world" more (network connections, etc). And I use Haskell when I have projects that have well defined inputs and outputs.
- tominous 11y agoI feel the author's pain. I had a short consulting gig recently where I was asked to speed up a simulation job written in Python by a mechanical engineer. Smart guy but not a programmer, so the script was full of global variables, side effects and imperative loops. I parallelised the script, which is pretty easy in Python but involved refactoring into a more pure functional style. I abstracted out the algorithms and added in some persistent memoization as a bonus. It was clean and did what they needed, but... unfortunately was now completely unintelligible to the engineer who wrote it. When I was asked back 6 months later to help again, they had reverted to using and modifying the old script. This time I kept the changes to the absolute minimum.
- adrianN 11y agoYou lost the opportunity for recurring jobs every six months.
- jarcane 11y agoI know exactly how he feels. This is basically the experience I had when I moved from Python to functional languages and it finally "clicked" how much more productive I could be in a Lisp or an ML. Where I differ somewhat is that for me, it saved programming as I knew it. I wouldn't be a programmer right now if it weren't for discovering Lisps and MLs. I fecking hated writing spaghetti OOP and tedious imperative loops. Mainstream programming languages are built on the lowest common denominator and the result is that as a younger person looking at the possibility of getting into computers as a career, I was scared off by the amount of willful tedium that seemed to define professional coding at the time. Today I work in a Clojure shop, and if I didn't, I'd be very wary of looking for employers that expected me to use inferior tools simply because they did not understand more efficient functional ones. It reminds me of some of the terrible kitchens I used to work at where I'd be expected to do things like cut meat with a cheap paring knife because the employer felt that a real chef's knife was "unnecessary" or "too expensive". I quit those jobs, and frankly, I wonder at programmers who don't have the same respect for their craft when it comes to programming tools.
- na85 11y agoThe smugness of Haskell evangelists is what keeps me from using it. I swear, the first rule of Haskell is to never shut the fuck up about Haskell.
- MustardTiger 11y agoI too like to punish myself in a futile attempt to spite people who don't even know I exist, much less that I am trying to spite them. That'll teach them to like something!
- eru 11y agoYou might want to look into OCaml. The language is not as nice as Haskell, but they also have less zealots.
- lmm 11y agoI never wanted to be like that, but it wears you down constantly seeing people complaining about problems that are trivial, or going gaga over some "new" feature in a trendy language that's a trivial special case of something Haskell has had for 20 years. You get tired of telling people the same thing every day and it never gets any better. Eventually you start just treating the superiority of Haskell as fact, because it's too tiresome to be constantly pretending that other options have their merits when you know they don't.
- dozzie 11y agoActually, much better approach is to shut the fsck up and write something useful. Funny how Erlang crowd doesn't show that much of smugness when it comes to parallel/concurrent programming. I've only seen two Haskell programs that were at least remotely useful to me (one being Pandoc), and then again, those programs had awful size of the binary and atrocious memory requirements.
- lmm 11y agoI do (well Scala rather than Haskell); I write useful programs and am paid well for it. But it's still frustrating to see the sheer wastefulness of so much of the wider industry.
- deleted 11y ago[deleted]
- UK-AL 11y agoThe comparisons with c# in this article is 10 years out date, so they are no longer relevant.
- lawlessone 11y agoI finally have an excuse.
- lostcolony 11y agoIt's like why becoming fluent in a second speaking language makes you a 'worse' speaker in your native tongue. You sometimes confuse idioms and terms, and sometimes you find yourself frustrated when trying to find a word in one language, when the perfect word exists in the other. (Tongue-in-cheek, if not apparent)
- draw_down 11y agoWell, "writing traps that other people are likely to fall in" does sound bad. I'm not sure I understand why that would be made excusable due to... knowing a couple other languages and that they exist?
- maze-le 11y agoI don't know how it is with you, but I think I have learned a lot by learning Haskell - and I think it has made me a better programmer. I have to say, I am in no way fluent in Haskell (anymore), and I prefer erlang as the functional PL of my choice (better libraries, more open community). I had a series of courses about concurrent programming at the University, with a Focus on programming in Haskell. Learning Haskell has taught me 2 things, and I am immenseley gratful that it did: * The power of abstractions * The power of types. The second point is absoluteley incredible in Haskell. With proper reasoning about your datatypes, the implementation almost becomes an afterthought. I never had that insight when I was using Java, C or another statically typed language. Also: I think if this aricle would be written today, the authour wouldn't be so frustrated. Many functional concepts have influenced other languages in the last 10 years (especially C#).
- SAI_Peregrinus 11y agoHaskell may not be the best in production, but it's amazing for learning computer science. It's also pretty good for learning quite a bit of intermediate and advanced programming. The concepts and styles of thinking it teaches can be applied elsewhere to great effect.
- progman 11y ago> Further, my experience with Haskell means that I now see potential bugs everywhere in imperative code. ... I am constantly aware that I am writing traps that other people are likely to fall in. Did that not make him a _better_ programmer? Did he actually mean "Why learning Haskell/Python makes you a worse _feeling_ programmer"?
- agentultra 11y agoThink that's tough? Try learning formal methods and how to design software to be correct by construction. Haskell would be an easy sell. But regardless of language few seem capable of catching errors in logic -- the kind that lead to race-conditions, starvation, dog-piling, cache misses, consistency errors, etc. The kinds of errors whose frequency and impact we are ill suited to estimate. "Bah, that could only happen for 1 in 100k requests." Now your system is serving 3M requests a second. It's very likely you'll be seeing that error. Don't be discouraged though. You might read about a new distributed lock in an important open source cloud orchestration framework that the public is building service infrastructure on and not find a single executable specification. Doesn't mean you can't write one and submit a pull request when you inevitably find errors in it. You just have to keep such alien super powers under wraps. Similarly if your goal is to write more Haskell at your job: just find opportunities to use it. Preferably ones where you can keep the secret of the sausage to yourself. When your bosses and colleagues begin to wonder how you consistently kick butt you can tell them. Then they might want to learn too. At least that's the story I tell myself. Most people are happy in their own instance on Plato's cave. If you bring in new ideas you might be ousted from the group. Or fired. Just keep doing the best mediocre job you can and try not to think about it too hard!