When I asked my current employer why they chose it, they simply responded that it attracts the "right" people. From a business perspective, any language is arbitrary. What matters is having clever people around to solve problems.
Eh. The "right" people can have perverse incentives.
My former mentor worked at a startup called Takt that billed itself as Haskell-only. It attracted all the top minds - Runar Bjarnason, who wrote a famous Scala book, worked there - and everyone was very eager to write Haskell code for a living.
The engineering team quickly went all-in on functional everything. Nix for package managers, a Haskell-to-JS transpiler for writing frontend code, immutable databases, the works. Because they eschewed all the boring technology that had been proven reliable over the years and only played with the bleeding edge in Haskell, they quickly ran into limitations of the ecosystem: performance degradations as they hit corner cases, missing functionality that needed to be patched upstream, corner cases that no tooling had existed to support it, etc. Before long, they were single-handedly supporting the broader Haskell ecosystem rather than spending cycles delivering on the business contracts they had.
This was all very fine with engineering - why not contribute upstream? Why not drive Haskell to broader adoption, which was in line with the company's values? - but management balked. They began to raise the possibility of maybe ditching their bespoke tooling and moving to something more standard. This didn't go down well - it caused a schism, where half the engineering team felt the right way forward was to double-down on the existing nascent Haskell technology and offer more support and training, and the others who just wanted to get stuff done.
Anyway, the startup failed. Turns out, when you hire for people who really believe in a programming language, you can occasionally attract zealots.
Similar experience, but Scala with pure FP (Cats) rather than Haskell.
We have
- "beautiful" code by zealots (who left) that has terrible performance. I've done two refactorings that bring > 100x performance increase.
- code by latecomers that misses the points of FP semantics and is subtly wrong.
- horrible compilation speed, therefore time-to-test, from heavy use of advanced features that add little value. The long feedback loop hurts not only productivity, also morale.
I don't think this is a programming language fail as much as it is seeing everything as nail because you chose to use only hammers. In the world of programming and technology I wished more people would look at people who invest and see that diversifying is what you need to do sometimes. Pick the immutable database but have a solid regular one along side of it in case you need to jump ship (more cost but it covers the case that the immutable database doesn't work out). This is the difference between investment and gambling. I would say to some degree they betted on immutable being the thing that would give them success instead of investing in immutable technologies that could be useful.
I agree. I like Haskell and I highly recommend learning it. But I would not choose it for production projects. I have learned the hard way to only use old, boring, well-known by the team technology when implementing software to solve real world business problems.
I think that's more true in the negative sense. It's not that it attracts the "right" people, it's that it repels the "wrong" people. There plenty of clever efficient devs working in Java or JS but they're surrounded by a sea of mediocrity.
And since the interview process is imprecise the point of being broken, it's very useful to attract the right people in the first place.
I think it was more or less the best tool for the job (according to them) back when their tech lead chose it and now they've built all their tech stack around it. I remember a blog post or interview where he said they wouldn't necessarily use OCaml if starting again right now. I don't think he was referring to going the way of Haskell either.
> From a business perspective, any language is arbitrary.
Counterpoint:
And then when the company starts growing quickly and has to hire 10 Haskell devs in 12 months, they realize its pretty much impossible to do without shelling out $200k/person.
When they do that they don’t hire devs already experienced in Haskell, they just hire smart experienced devs who are competent at building systems and can learn to build them in Haskell.
Actually from a business perspective PHP or something would be the best choice? Lots of (relatively speaking) cheap devs available at all levels. Wasn't Java designed around the idea of medicore developers not being able to mess up too badly?
Functional languages do appear to attract smart people, but I see far more people with an interest in the language than actual jobs out there. They seem more geared towards compute science (more theoretical) over software engineering (solving real world problems).
You will get slightly better people but still the wrong people.
JS is almost never the right tool for the job, Go is occasionally the right tool for the job, mainly if you need to write something that moves bytes from one fd to another without much in the way of business logic.
TBH if you are building something boring you should just use Spring w/Java or Kotlin. This will attract pragmatists that ship code that works in ways that anyone else that works with these tools will instantly understand also. In a way it attracts mediocrity but in the good way where you get nice standard code that can be maintained cheaply for a long time and it's easy to hire for the skillset.
If you are prototyping extremely quickly then maybe Ruby on Rails might be the right tool for the job (and thus attract the right kind of people).
Go attracts mediocrity and not in a good way, it also actively repels the "right
" people if you want to hire for highest intellectual horsepower for a given budget.
In the same category as Haskell you also have OCaml, the Lisps (Clojure in particular) and Erlang all of which will yield you lots of the "right" people. None of these people will be cheap but none of the good people that write the other languages are cheap either, however there is a strong correlation between interest and proficiency in these languages and high intellectual horsepower - hence "right" in this context.
Go doesn’t attract mediocrity it attracts pragmatism.
I worked on a Scala team for a couple years, had a lot of devs that were “smart”, problem was they wrote really fancy code no one could understand.
I then switched to a Go team and it was night and day. I was wildly more productive and the people in the community were not lacking intelligence.
Go prioritizes community, it believes that “us” is more impactful than “me”. This is its biggest strength, and is often lost on people looking in from the outside.
In my experience Go's relatively constrained language and standard library coupled with gofmt mean Go code written by entirely different people tends to read fairly consistently.
When worked on Go projects, I found that I was far more likely to read library code to see how to use it than other languages I used. Cannot be too "fancy" is definitely a strength of Go as a programming language.
I don’t dislike Go and have worked with it professionally on and off over the years. It occupies a weird liminal space between low level languages like C and medium level languages like Java. It was built to solve a set of in house problems that Google faced and it does so well. On the other hand if you end up needing to do lower level work the lack of power renders Go unsuitable. And if you need to do higher level work the lack of expressiveness is almost as frustrating.
> Go doesn’t attract mediocrity it attracts pragmatism.
It attracts "pragmatism" and "simplicity" in my experience, but in the prescence of cheap optimal solutions the worse alternative is chosen to preserve that pragmatic image.
Yes, if you choose Haskell, a Lisp, or something like Erlang, you can get smarter/better devs. But the flip side of that is that the types of people who tend to gravitate toward those languages are often more interested in programming for it's own sake and not the domain they're working in. So you get things like people burning hours writing their own libraries and endless tinkering with programming minutiae instead of getting sh* done.
On the other hand, a mediocre programmer who taught themselves Python, may not be winning any programming competitions, but will often have significant domain expertise and a bias toward getting things done.
You need to ask yourself whether or not the stuff you're working on really demands the absolute best programmers (it very rarely does). If it does, go with the Erlang/Haskell/Lisp crew, otherwise go with the Python/JS/Go crew.
This is where I differ. I think the Python/JS/Go crew gets you stuff that is built poorly and becomes expensive to maintain.
I much prefer the JVM and ASP.NET crew because they are 9-5 programmers, their tools aren't constantly changing so for the most part they only need to spend time actually doing work. No fighting with package managers, no updating the latest framework and solving backwards incompatibilities for weeks, no random runtime bugs and shitty native extensions that cause said runtime bugs or memory leaks outside of runtime level heap accounting, etc.
Boring tech is the way to go for 99% of problems and to me JS/Go/Python don't qualify because they break too much and require too many workarounds for too many problems. I want my programmers to be thinking about how to solve my business problem, not problems with their tools.
I was clarifying I consider them to be separate categories.
Java/.NET cultures are distinctly different to Go/JS/Python despite both categories being mainstream.
The former is old, boring and sticks to what works. They are both slow moving, have large established frameworks for each applicable domain, prioritize backwards compatibility, have highly evolved IDEs that support both the language but also the dominant frameworks etc.
The latter are easy to learn, emphasize the easy creation of new applications and libraries, move quickly/rapidly adopt new language and runtime features, don't generally care much for backwards compatibility in the library ecosystem, have many competing frameworks and libraries for everything. etc.
They are just very very different and as a result produce very different codebases that have very different tradeoffs in hiring, maintainence costs, development velocity, pivotability etc.
Sometimes those languages are the right tool for the job but IMO mostly in cases where you aren't sure what that job is. If you already know what you want to build and how to build it then the "boring" tech stack is generally the way to go in my experience.
I feel like you're just describing the JS ecosystem and for some reason included Go in the same group, even though Go's far more similar to Java than to JS.
> [...] move quickly/rapidly adopt new language and runtime features, don't generally care much for backwards compatibility in the library ecosystem, have many competing frameworks and libraries for everything. etc.
None of this applies to Go and in fact, Java is much worse when it comes to churn than Go is. Just look at how many companies are stuck on Java 8. Go updates are fearless - there's no reason not to run the newest version available.
> [...] move quickly/rapidly adopt new language and runtime features,
Go 1.0 was released almost exactly 10 years ago ([1]). Since, there have been *zero* major language changes. The changes that did happen were small, typically to address inconsistencies or small inconveniences. Though, there is one big change coming in this month's release - generics.
Python came out in like the early 90s I think when the Berlin wall hadn't been knocked down for all that long. It is OLD and battle tested by many many high profile companies. Granted, sometimes it isn't the right tool and the JVM is. Same is true in reverse as Java has significantly more boiler plate than Python. I do agree Python has changed more over time.
In JVM land almost all code is implemented in managed code. This means the likelihood of severe (runtime degrading) bugs is greatly reduced.
It also means in practice you can just step into any arbitrary library code using an interactive debugger to fully follow the flow of execution.
Contrast that to Python where every library worth using is actually written in C against the CPython interpreter itself. This means a few things:
Broadly speaking you have just extended the exposure of the core runtime by the amount of code you have loaded in native extensions, meaning more bugs, more severe vulnerabilities and generally a bad day.
It also means that code is "invisible" to the runtime. Python has pretty poor tooling anyway but what little tooling is has becomes useless once your problems venture into C extensions and you end up having to drop down into GDB to work out what is going on. This is made harder by the fact that Python doesn't really play that nicely vith the Valgrind toolkit in my experience making use after free/leaks/etc and other nasty bugs harder to debug than straight C code.
Finally it also means you can't just pick up and move your Python code to a different runtime despite them being available. Unlike Java which will mostly run just fine on Hotspot or J9/other proprietary JVM your Python code is actually now CPython code. In practice I guess this isn't a big deal but it's worth mentioning.
TLDR: Python is old, Java is stable. There is a difference.
Usually it's not, but you just described the problem when it does. i.e 90%+ of Python users couldn't actually debug a C extension. I would argue closer to 99% which is insane when you consider the prevalence of them and how critical they are to the Python ecosystem.
You don't seem to be getting it. Nearly every Python program is composed of about 99% C these days, especially because Python slants heavily towards data science now.
pandas? numpy? tensorflow? pytorch? All native extensions. All the fast encoders/decoders for various file formats etc are all native extensions. Talk to message queue or anything else that requires fast I/O? Probably also C. Python itself is so slow that it's only really used as glue for these very fast libraries.
So it's not about control it's about actually being able to understand the tools you are using. If you are using this stack but don't know C then you don't really understand the software you are using.
Again, contrast to Java where as long as you know Java you can probably most libraries in common use with a few exceptions. The main exceptions are crypto, compression libs and stuff like Netty.
Oh I get it and use those technologies often and so do many coworkers, but it is irrelevant to me what they're written in as they just work fine for 99.99% of users it would seem.
When you say a Java programmer knows the entire system, where do you draw the line? The stack system of the JVM? The assembly I assume it later runs, the machine language? Honestly, unless you're running Forth on a very simple chip, I don't think you can possibly hold the entire system in your head at one time.
I draw the line where it crosses into understanding a language other than the runtime language. You don't really need to understand anything more than pure Java to understand 99.99% of popular Java libraries (I already listed the exceptions).
You don't even need to understand JVM bytecode (though that can really help for performance optimisation).
You can't use almost any meaningful library without running into a C extension in Python-land and that is what I have a serious issue with. (same goes for Ruby and JS though I guess)
I prefer Javascript/Go/Python because most of my code is actually doing something instead of just conforming to a Gang Of Four pattern designed to paper over the shortcomings of my tool.
I too want my programmers to be thinking about and solving my business problems, not writing boilerplate.
Do you prefer your English communication from people with limited English language proficiency, because they have things to say without attention to grammar, precision, and logical structuring?
Lack of understanding of nuance works about as well in programming languages as it does in English - it's very limited and causes issues, which often the low vocab user is simply not aware of. But the issues exist nonetheless.
Essentially you are arguing for a low level of education in the craft of programming, and this is why many (experienced/career professional) people tend often select against users coming from those languages.
Another poster just down agrees with you, but notice they mention they started with Python, which is a beginner language with limited detail, and can't grok why they need to learn more to use Java and why it's worth it. I agree, they can't understand why, but that doesn't mean there aren't valid reasons. It just means they have more to learn, and 'don't know what they don't know' (yet, hopefully).
To borrow your language metaphor, I find it's more like dealing with people who are capable of communicating complex ideas with simple vocabulary, versus people who can only communicate complex ideas using extremely technical jargon.
I think you hit the nail on the head. As someone who started the bulk of my programming in Python, I found learning Java to be an excercise in frustration as there is so much you have to learn about design patterns and all of that mess. It seems to come up 500x more than in Python which is like here are a bunch of high level data structures and objects and how to use them, so go have fun.
How do you open a file and print "hello world" these days? It was at least a screen full of code the last time I looked at Java, but that was a while ago.
This sounds like less a problem with Java or Kotlin and more a problem with the development team. If you're dealing with a bunch of new developers who just barely read the GoF book and think it's a prescriptive guide to all things code, you're going to end up with a lot of boilerplate. But if you turn a bunch of new developers loose in any language without supervision, they're going to build something bad.
There's nothing in the languages themselves that forces you to use inappropriate design patterns, and as the parent mentions, modern Java and Kotlin have improved a ton in reducing boilerplate. I'm not actually sure what it is that you think they're missing that Python or JavaScript have, unless it's just that you prefer dynamic typing.
The issue here is the experience level of the devs. These sorts of conversations should have people declare their years of programming experience at a minimum, it helps to understand perspectives better.
> I prefer Javascript/Go/Python because most of my code is actually doing something instead of just conforming to a Gang Of Four pattern designed to paper over the shortcomings of my tool.
Which shortcomings of Java/Kotlin are you referring to? What features are both present in all of JavaScript/Go/Python and absent from Java/Kotlin that have any relevance to the Gang of Four patterns?
> What features are both present in all of JavaScript/Go/Python and absent from Java/Kotlin that have any relevance to the Gang of Four patterns?
For example:
1. Being able to define a top-level function
2. Being able to return a function
These either shoehorn every codebase into OOP or force the usage of design patterns.
Mind you, it's possible that if you're writing strictly modern Java/Kotlin/whatnot then these are fixed/irrelevant, but that doesn't erase the billions of overengineered lines of code out there.
From [1]:
> Abstract factory adds another level of abstraction to factory method. While factory method abstracts the way objects are created, abstract factory abstracts how the factories are created. The factories in turn abstracts the way objects are created. You will often hear the abstract factory design pattern referred to as a “factory of factories“.
This type of insanity is exactly what the parent is referring to. Layers of needless abstractions that paper over the lack of basic features every other language has.
No, it just means the people that tend to be attracted to these types of languages.
Easy to get started languages that hide much of the inner workings from you as a dev.
I don't believe Go belongs in that category at all, mind you. And I'm not convinced that the fairly major internet presences using it heavily would put it in that bracket either.
I concede (having a fair amount of past experience of functional programming languages, including Orwell, which influenced Haskell) that choosing a functional programming language for development helps you pre-select people who are well-educated in CS concepts. But I am far from convinced that it's an approach that is particularly likely to lead to a crack team of business-focussed developers. It's just as likely to lead to a herd of cats.
Haskell hides far more of the inner workings than Python, JS or Go. There's a huge gap between the semantics of a non-strict, pure functional language and the actual execution model.
I've picked up F# out of a need to get things done.
I got sick of learning framework after framework just to keep relevant. F# is niche so it moves a little slower.
The results have been fantastic. Not only can I solve business problems faster, I'm happier with the resulting code. It's easier to read, test and alter.
I've found some languages a nightmare to work with. Specifically Perl and JS. I've seen brilliant code written in both but that takes more care than most put in. If you have pressure to rush and don't clean up it's just a mess.
"But the flip side of that is that the types of people who tend to gravitate toward those languages are often more interested in programming for it's own sake and not the domain they're working in. So you get things like people burning hours writing their own libraries and endless tinkering with programming minutiae instead of getting sh* done."
Don't agree with everything, but this part is a very good point.
>Go attracts mediocrity and not in a good way, it also actively repels the "right " people if you want to hire for highest intellectual horsepower for a given budget.
This is painting with a pretty broad brush. I like Haskell (and first learned it before it was cool, in the early 2000s), but I also enjoy coding in Go. Not everyone is strongly driven by choice of programming language in their job search. If you do hire someone who desperately wants to write Haskell code, you might find that they spend more time tinkering with advanced Haskell features than they do adding business value.
What exactly did Dijkstra say about Cobol Programmers?
In 1975, Edsgar Dijkstra famously proclaimed that “The use of COBOL cripples the mind; its teaching should, therefore, be regarded as a criminal offence[sic].” This undoubtedly led to the decline of teaching COBOL in universities, but it remained the dominant business language.
> If you are prototyping extremely quickly then maybe Ruby on Rails might be the right tool for the job (and thus attract the right kind of people).
I am puzzled by this because my early experience of Ruby On Rails (and I mean early -- 2005) is that every Rails developer I encountered knew much less than they were letting on.
> Go attracts mediocrity and not in a good way, it also actively repels the "right " people if you want to hire for highest intellectual horsepower for a given budget.
I really think this needs backing up with at the very least a juicy horror story! I'm not convinced by this at all.
For context I worked with Go extensively for about 5 years. I tried very hard to like it because I have immense respect for folks on the core team.
I even wrote some pretty good code in it.
However a few things became very clear to me over time.
1. Go is -not- a general purpose language. It lacks expressiveness necessary for this purpose which leads to overly hard to follow and refactor business logic, repetitive and error-prone (hah) error handling. Poor/inconsistent null handling. Highly variable quality standard library (some stuff is amazing like it's HTTP and TLS stacks). This leads it to be very good at one thing and one thing only, network servers, preferably operating at the protocol level. I think if you want to write a custom DNS, TFTP, or other simple network protocol and you cbf using Rust then Go is a great choice.
2. Go is easily picked up but very hard to master and the reward for mastery is much lower than languages that have similar learning curves. I would say I got very close to mastery but gave up short of the goal. Some things that come to mind here are handling of channels especially in select statements is much more nuanced than most would imagine, hell channels in general are -very- subtle. Subtle is never a word I want to hear when talking about a tech that I'm expected to support and mentor juniors to use.
3. Go leads to masses of very poor quality code that becomes extremely expensive to refactor, in large part due to language design decisions. However it's also a follow on effect of the above point but that applies equally to Python, JS, Ruby etc. What makes Go unique in this regard is that it is already a very verbose language but goes further to have a poor module system and structural typing system that makes code inflexible.
4. The ecosystem lacks high quality frameworks ala Spring that can be used to build applications in such a way that knowledge of structure and style are portable across codebases/companies/etc. Go (like JS) favours a smaller composable library approach which lends itself much better to highly experienced developers than beginners that really do need the help because they are yet to develop good taste. Unfortunately Go mainly caters to beginners so this is a fundamental impedance mismatch between the ecosystem and the users.
5. It actively repels experienced engineers. This is probably the controversial point but it holds true among my social group which I would consider to all be A++ engineers both in intellectual capacity but also real world effectiveness (i.e these guys build the stuff you rely on every day).
Why is this so? Well it boils down to that bit about mastery no being rewarding. Even in Java which is admittedly probably the most boring language on the planet there is a very rewarding payout for sticking with the language for a decade and getting exceedingly good at it, you have all the primitives at your fingertips, real threads, powerful reflection, metaprogramming and runtime introspection. What does Go offer? M:N coroutine model, pretty basic profiling capabilities, really shitty (and slow) reflection, runtime with almost no knobs to apply workload specific optimisations, etc. In short for all that time investment to fully peak out you are only marginally better than the next mediocre dev. TLDR: The ceiling is low, you end up surrounded my mediocrity, it's hard to effect change in large codebases as a result, Java/.NET/other langs don't suffer anywhere near as badly as such Go is avoided.
I could go on but these are the main points.
Also I could just be jaded old and grumpy but whatever, this is how I feel about it and everyone is free to be wrong on the Internet.
> Also I could just be jaded old and grumpy but whatever, this is how I feel about it and everyone is free to be wrong on the Internet.
No -- this is interesting. I also think point 3 and 5 probably informed and explain the new generics design, which seems intended to reward perseverance.
I didn't find channels difficult, but then I have some Occam, CSP and PVM experience, and some message-passing parallel language design experience too (albeit all academically, including 27 years ago in my final degree assignment)
I do think you are right there and that generics will have a significant (and likley highly positive) impact on Go.
Much of the code I wrote in large applications amounted to writing application specific data-structures that had no business being application specific. However due to Go restricting generic capability to language level features and reflection being far too slow it lead to a lot of it sadly. One of the reasons I love the JVM ecosystem so much is access to the `java.collections` library which is definitely 1st class among standard libraries.
I haven't kept up with Go development but I hope they are going to revamp the stdlib with generics powered structures etc. Seeing people use the stdlib linkedlist implementation always caused me to start questioning my life decisions.
As for channels I think basic usage is straight forward. Where things become complicated is differences between buffered vs unbuffered channels and how combining those in select statements etc makes for some interesting interactions. Which is what I find egregious, something that looks and feels simple until it's not.
That's one of my gripes with the language too. Due to the lack of generics, Go programmers just use pointers to indicate nullability - not exactly the right approach. Thankfully, it's still an improvement over Java, as non-nullable pass-by-value semantics are the default, so if you want a pointer you have to explicitly define one.
I have my fingers crossed that once generics land, the ecosystem switches over to some sort of an Option type.
> have a poor module system
I'm curious, what's poor about it?
> runtime with almost no knobs to apply workload specific optimisations, etc
The approach Go takes is that the GC should "just work" for all workloads. Obviously, this will never be 100% optimal for any given workload, but you know... tradeoffs.
That said, the knobs you're looking for do exist, but they are in the language itself. Unlike Java, Go makes writing GC-friendly code easy.
> Even in Java [...] you have all the primitives at your fingertips, real threads, powerful reflection, metaprogramming and runtime introspection.
Aren't "real threads" strictly worse than green threads?
> powerful reflection, metaprogramming
Those are misfeatures, especially metaprogramming.
And yet there are hardly any software written in Haskell or Ocaml that are widely used or have any notable positive impact on the modern digital world, compared to those written in languages like Go, C++ or Python.
edit: ps: Big fan of OCaml, but have since moved on to Go and Python for getting things done in the real world.
OCaml is mostly used in speciality applications. I have a few friends that work on flight control software for satellites and their stuff is all OCaml which is apparently not that uncommon in their field.
That said none of them knew OCaml before joining said company and thus none were hired because of it... so that does somewhat invalidate the "right" people argument but I guess if you are doing literal rocket science I think that is pretty self-selecting for smart folk lol.
> And yet there are hardly any software written in Haskell or Ocaml that are widely used or have any notable positive impact on the modern digital world,
It's used in supply chain management at target.
IIRC at Starbucks too.
Oh, and ever use Facebook chat? Haskell is running over your messages to filter out spam.
JS is one of the most successful programming languages in history. Millions of JS programmers solve real world problems every single day. It might not be the right tool foryou of course but that has nothing to do with JS itself.
Spring relies heavily on the more powerful features of the Java runtime which aren't available in Go, it wouldn't be possible to port it as-is. You could definitely come up with a set of existing Go libraries that implement all the core functionality of a Spring up in a cohesive way. Almost every large company I have been at has done exactly that however none has caught on in the same way Spring has.
Spring hasn't "fixed" Java development however but rather provided a consistent framework that has stood the test of time. It still has flaws but it's been around for long enough that nearly every conceivable issue you could run into already has a well known solution.
The end result is you spend very little time fixing Java or Spring problems.
In Go land however there isn't much in the way of consistent and/or well integrated ecosystems. You end up stitching everything together yourself and as a result can run into all sorts of combinatorial set of dependencies that can present effectively un-Google-able problems. Thus you spend a lot more time working out how to integrate your HTTP server, router, middlewares, tracing, logging, etc all of which are pre-solved problems with are large framework like Spring.
It wouldn't be possible to "fix" the same problems in Go unless either a new framework was developed from scratch that really took off or one of the collections of libraries was able to achieve dominance.
What runtime does Spring utilize that Go doesn't have from ... say .. the XML conf files era of Spring? I understand annotations and classpath scanning are entirely different animals.
I guess AOP magic doesn't exist either.
Json/Yaml versions of the xml era should be possible. I guess no xml namespace magic (which I hated)...but a consistent object graph specification would seem useful.
I’ll come out and say it though: Haskell is a cult. It’s best to smile and nod when you’re around the believers. They’re harmless. Ditto for rust.
It is truly astonishing how much code a determined team of haskellers can produce. I’ve been porting a codebase, line by line, to python. I’m up to 15 thousand lines.
Had to do it without being able to run the program too.
There are lots of benefits. (Ditto for being in a cult.) It’s worth knowing what they are, since they are powerful. But (hello cult) there are plenty of negatives; monads are the Aristotle philosophy equivalent of programming. Take care not to study them too closely.
> monads are the Aristotle philosophy equivalent of programming. Take care not to study them too closely.
Monads is just a pattern for composing functions that can’t be composed using “normal” function composition (because of incompatible types). That’s all it is. I never understood the fetishisation/worship of monads in the Haskell community.
That's a nice way to put it. I guess the fetishisation comes from the fact that being able to do arbitrary function compositions coincides with a fundamental mathematical structure, even if the impact on code productivity is questionable.
Wow. A whole 15 thousand lines of code, you say? Golly, that is just astonishing.
What does the lines of code have to do with Haskell? Specifically, why did you feel this was important information? What you wrote is almost a non sequitur. That Haskell programmers are efficient and the fact that your port of a Haskell code base to python has reached 15KLOC are two completely orthogonal pieces of information.
You probably didn't have to do it without running the program.
Dang. I'm pretty deep into Rust (working on a very large production codebase) and was hoping it was real. The book even says, in the section on Async, that Async is a cult and you should avoid it. My people!
It's an expressive, pure, statically typed functional programming language with a large enough package registry, community and optimized enough runtime/compiler.
Breaking down the benefits of each:
- Expressive: you can model things with greater fidelity
- Pure: you know when your code performs side effects, so you're in for fewer surprises
- Statically typed: you learn about things at compile time, not in production. You also need to write fewer tests.
- Large pkg registry: fewer things to implement yourself (compared to, say, Idris)
- Large community: fewer problems you'll be the first one to discover/solve
- Optimized enough compiler: compile times can be _acceptable_
- Optimized enough runtime: your app will be fast enough without you having to care much about it
Now one point that isn't obvious from all this and that is a big selling point for my company is how much of a breeze refactoring is. Types give you more guarantees around how your code behaves, so there's classes of mistakes you can't make, and won't have to rely on a super strict test suite to prevent you from making.
Newhire submitting a PR changing 25 files all over the codebase? Business as usual.
It is very easy to build languages, dsls and compilers in. A lot of language writers at least build a first version or prototype in it. I like it because in my head, all programming is just moving data from one type to another and although this is possible in any language, Haskell and also Idris 2 fit my mental model well. Unfortunately when I have to work with other humans, Haskell never makes the cut, so I only built side projects in it.
Haskell allows to build abstractions that are less leaky than in most other languages.
Take a vector package, for example. It provides you with unboxed vectors that are structure-of-arrays by default with the interface of array-of-structures. That means you can have fast slicing operations in both dimensions - slice by field and/or by indices. Of course you can have unboxed array-of-structure arrays, if you need them, they are there too. But their use is transparent to you as user, however your choice is.
Same is for other interesting structures.
Say you wrote your parsing library. You can provide a rule to compiler such that code "(pchar c `pthen` p1) <|> (pchar c `pthen` p2)" is equivalent to "pchar c `pthen` (p1 <|> p2)" and you get left factorization for all your grammars supported by compiler.
Parallelization is often as far away as adding a par/pseq annotation.
Haskell can remove intermediate lists and fuse mapping over complex structures such as red-black trees - it is done for all of your code so when you do "fmap f (fmap g) rbTree" you will get "fmap (f . g) rbTree" and compiler will try to get you that code by transforming your code where "fmap f" can be pretty far away from "fmap g rbTree".
The pattern matching checks are awesome - compiler will warn you if you wrote more general check before more specific one. The absence of this in C++ made my life a little bit more interesting than is comfortable for me.
In short, most of the time you can write code however you want or need and compiler will support you. As if you are "team programming" with a bunch of smart people - the compiler's authors.
Something Haskell programmers commonly experience is that their programs typically work the first time they compile, due to the type system. I was skeptical of this but I've experienced it myself too -- it's kind of fun! What this means is that you spent most of your time thinking about how to express your code elegantly in the type system, but once you do it usually just works. That's a huge practical benefit you don't see in other languages without such an expressive type system.
It's a pure functional language. You can do functional programming in many languages, but Haskell enforces it by design. From what I've seen of the type system, it's quite nice as well.
Functional programming allows a great deal of confidence in your code,
I like the separation between pure and impure code. In his Haskell class Eric Meijer said that pure code are like islands and monadic code is like the ocean, and as programmers we decide how much of a system is pure code.
Sorry for being off topic: the new M1 Macs seem to take some of the pain out of large runtimes for compile/build in languages like Haskell and Swift. I don’t have any benchmarks, this is just very noticeable when I am coding.
If we focus only on the benefits, her are two basic but distinguishing features that make it a very pleasant and productive language in my experience:
- knowing through the type systems that a function’s result depends only on its parameters makes testing more reliable
- the syntax and type inference makes it possible to write down many algorithms extremely tersely, which is also helpful in getting the implementation right
This also provides maintenance benefits. It's not _quite_ that if it compiles (after you make whatever change you wanted to) that it's correct, but it's not far off either.
Sadly, there is not an obvious metric through which this can be answered, but the type system is much more advanced than that of C++ or Java, and as such you can be more precise about the inputs and outputs of a piece of code.
As long as take advantage of the type system, the compiler tends to permit far fewer programs that compile, but do the wrong thing, than is the case in C++/Java. You will notice you spend more time editing code to make it compile, and less time debugging code that does compile.
Rust should not be grouped with C++ or Java, as its type system is essentially that of Haskell with the addition of lifetimes. The developer experience is similar in that you tend to spend more time getting code to compile, and less time debugging.
For your good old boring business software - ADTs and patter matching combo is, IMO, the most visible, practical benefit over "traditional" languages used in the industry. And something I miss the most when not writing in Haskell.
There were some practical reasons for this, but at the end of the day: if you're going to spend thousands of hours developing something, you might as well choose a language that you find beautiful and enjoy working in.
Because some people know it, like it, and because they can. It’s like asking why Facebook still uses PHP. But also, every language has something it’s particularly skilled at. There are still business applications out there in COBOL because there are some features hard to replicate in modern ones. No language ever dies.
I chose it due to the type system. Nearly every piece of data is optional. I need to compose these pieces of data to form a full set and apply that set of rules to a system. Haskell made a lot of things work out really well:
* embedded DSL for describing things with minimal syntax
* types to enforce my invariants
* immutable data + STM to protect my shared data structures
* multithreaded/async code is easy to work with
* deterministic outputs given inputs
but it was headaches in a lot of ways:
* exceptions - still not sure I’ve handled all exceptions gracefully
* culture - most teammates are intimidated by Haskell (and types)
* ecosystem is behind (Rust has exponential usb acceleration vs Haskell’s constant pace)
While I’m proud of the outcome I would have chosen differently now that I’ve seen the other side and have the project done. The inertia I was fighting required far too much energy
I once used it for mathematical code in my thesis. Basically I had everything written with C++ code but it just didn't work. Also tried Matlab but I'm just not made to use it efficiently, so I tried Haskell for interfacing with the GNU GSL library. In the end I changed back to C++ but it helped me a great deal to understand what I was doing and to clean things up. Some nice features include obviously dealing only with constant expressions and being forced to write only mathematical transformations. A bit unexpected was that you can actually swap variable declarations, declaration order doesn't seem to matter much. Quite a big pain relieve when dealing with a lot of variables.
Actually ImplicitCAD is written in Haskell which implements CSG (very tricky to efficiently implement)
At my last job, we had a Python codebase that had grown large and unwieldy. We wanted a language with stronger compile-time guarantees and better concurrency support. After evaluating several options the team at the time settled on Haskell and it's still used on all our kiosks to perform tasks including interfacing with the credit card reader: https://www.youtube.com/watch?v=O-z8hDXIQSg
A lot of this discussion has devolved into the management side of choosing a language and strayed from the realistic side. But insofar as to why people would choose Haskell...
Haskell is fast, compiled, type safe, memory optimized, allows concurrency and parallelism. The use cases where you'll see using Haskell will generally be companies like financial sector where very fast and error free execution directly translates to making more money, e.g. dark pool front running trading algorithms. Generally you don't hear it extolled because of who is using it and the secrecy around what it's being used for, e.g. competitive advantage.
Outside of that you'll probably only see it in academia because of a lot of the reasons listed in the replies. In my opinion its a harder language to learn because it really is just lambda calculus translated to a programming language.
Learning Haskell was a joy and it made me a better software developer. However I don’t reach for it when developing production software. The advantages doesn’t outweigh the disadvantages (compared with using more mainstream languages). I also highly recommend learning Agda/Idris/Coq/Lean/F*. They are to Haskell what Haskell is to mainstream languages. Learning them will make you a much better developer. Even if you never use them for production code.
Haskell is the Mercedes Benz of modern PL. There are more advanced/esoteric languages, and there are less advanced/esoteric languages, but in general features developed, explored, and tinkered with in Haskell trickle down to other languages.
It offers less and less practical benefits over other languages because other languages evolve to where Haskell has been.
Haskell is correct, and it forces you to be correct and enforces a kind of clarity of thought that is seldom required from other languages. I think it's something you have to discover for yourself. If you don't see Typescript as strictly better than Javascript, you're probably not going to see the benefits of Haskell over any other language.
All that said, we have to ask ourselves which areas of computing Haskell can be profitably used in to gain the kind of critical mass that other languages have:
- Early programming, analysis, data science, etc -> Python is a better fit because it's easier to pick up, easier to understand, even though it's less correct. People discover libraries about checking types at runtime before they discover then can check them at compile time. Python has long since started it's evolution w/ the typing module.
- Web -> JS, because it's basically the only option. Projects like Elm and Purescript have made small dents, but the most successful cultural descendant of Haskell (if you can call it that) is Typescript.
- Startups -> Ruby/Rails, Django, NestJS, etc. win over Haskell here because you don't need to be right to have a successful startup, you need to find customers and after that product-market fit. Your startup could be airflow+google sheets with all-manual validation and still succeed over the most carefully crafted and bullet proof Haskell code.
- Safety critical systems -> Often are required to be realtime and it's easier to get to the safety requirements in other low level languages with strict procedure/process/standards and guaranteed realtime-capable OSes and tooling rather than using Haskell.
I've written about Haskell in the past (excuse the title):
Yes. On this study: A comparative study of programming languages in Rosetta code they show that Haskell programs are (brief) less lines of code to achieve the same goal.
Binary size is small..
And very important to me they could be executed even years after they were first uploaded to Rosetta code.
A very good study and the researches gave an entertaining talk on it, that I can't find now.
I'm of the opinion that trying it out for yourself is not a waste of time. I'm sure several other commenters share that opinion, and I'm sure several others do not.
The tone of the original question reads to me as though the asker is asking to be convinced by evangelists to give the technology a chance. Ultimately though, just listing technical benefits of the language is unlikely to be as effective as one might rationally expect, given that humans — which certainly includes programmers — are less rational than they would like to admit.