3 ms·
I worked professionally in Haskell for a long time and I cannot disagree with you more. This is always the promise of strict functional languages but in a busin
by mlthoughts2018 8y ago
I worked professionally in Haskell for a long time and I cannot disagree with you more. This is always the promise of strict functional languages but in a business setting where the very nature of what you build has to be arbitrarily mutable at the whim of competing interests between stakeholders, engineers, customers, etc., it just doesn’t work.
You end up with the same spaghetti code messes, unexpected runtime errors, indecipherable crashes, etc. no matter what degree of strict verification tooling you use. The introduction of lazy evaluation, difficult to debug tail recursion implications on memory consumption, elevating IO into the type system, burying details deep in type class patterns, relying on dozens of special case compiler directives to enhance Haskell... it becomes the same shit code mess as any other paradigm.
- tome 8y agoInteresting. I would be interested to know more details about what you worked on and with whom. This hasn't been my experience in any of the four jobs I've used Haskell at. I don't deny that Haskell leads to spaghetti code messes, unexpected runtime errors, and indecipherable crashes, but the Java that I've previously worked with and the Python I currently work with suffer from those to a degree greater by an order of magnitude.
- mlthoughts2018 8y agoIt was first for a bank, later for a data analytics start-up, and then also for an education technology company. I had many skilled functional programmers on my team too, including a few people who had done work on GHC itself. I’ve also see code messes in many languages. It’s a business culture problem, has nothing to do with the language or paradigm. I’ll greatly dispute with about Python though. It has been a language that facilitates notably cleaner and more extensible implementations in my experience. Seen messes in Python too, but absolutely no way it’s “an order of magnitude” worse. That’s simply ridiculous. The only way that’s happening is if the programmers are exceptionally bad to the extent that it would not matter which language they used.
- tome 8y agoVery interesting. I suspect we may even have worked for the same bank! I'd love to discover how we came to such opposing conclusions. To give you a Python example, it encourages stuff like: def send_email(recipients, contents): if type(recipients) == str: send_one_email(recipients, contents) else: for recipient in recipients: send_one_email(recipient, contents) That is a flavour of convenience that people commonly implement in Python. People like it because it allows both send_email("tome", contents) and send_email(["tome", "mlthoughts2018"], contents) and saves them from typing two square brackets. The problem is when you call send_email(u"tome", contents) It tries to email "t", "o", "m", and "e". This kind of stuff is endemic in Python. Yes, this did happen in practice in a company I worked for (a company that was responsible for trading hundreds of millions of dollars of securities every day). Call the programmers exceptionally bad if you like, but they were among the brightest minds graduating in my country. It was Python that allowed them to be sloppy.
- mlthoughts2018 8y agoI disagree very much. The Pythonic way would be to do something like map(send_email, list_of_addresses), and have send_email raise an exception if not passed precisely a single string, and presumable raise exceptions when you validate that the email address is of an acceptable format, etc. It would not be Pythonic to make the function superficially handle different arities of argument through explicit handling on the list type with isinstance, precisely because you’d need to handle different meanings of different types that implement the Iterator Protocol. That’s not something Python generally encourages, it’s just a mistaken implementation. And particularly not making careless assumptions when basing branches on isinstance behavior (for example, you could always encounter custom classes that have overridden __instancecheck__ or __subclasshook__ special methods.
- tome 8y agoIt's certainly a poor use of Python's flexibility, but I've seen that kind of thing written at two completely different companies by completely different, yet smart, people so I suspect it's prevalent. Haskell does a much better job of nudging smart people to write good code. Gabriel Gonzalez explained it better than I could: http://www.haskellforall.com/2016/04/worst-practices-should-be-hard.html http://www.haskellforall.com/2016/04/worst-practices-should-...
- loup-vaillant 8y ago> in a business setting where the very nature of what you build has to be arbitrarily mutable— I just don't use Haskell there. I personally use OCaml for my data in, data out problems (compilers, generators…), but for inherently interactive and mutable stuff I just do imperative programming. Of course the type system (and the performance characteristics of the runtime!) must be suited to the problem domain. > burying details deep in type class patterns, relying on dozens of special case compiler directives to enhance Haskell... Looks like someone went overboard. I think you (your team?) should have been more conservative with the compiler directives, and less abstraction loving with the type classes.
- mlthoughts2018 8y ago> “Looks like someone went overboard.” All these things are basically bare minimum table stakes to do anything in the language at all, particularly enabling dozens of compiler directives for language feature extensions. That is Haskell 101 practically, which is actually one of the hugest problems with the language. Saying this is “overboard” in Haskell is out of touch with the practical realities of using the language.