It's really good for boring, line of business software (BLOBS).
The vast majority of business logic can be modelled with a handful of simple types and pattern matching. Very few design patterns are needed. And if you keep to the simple parts you can even teach the syntax (just the types) to non-technical contributors in an afternoon. Then they can read it and help verify that you implemented the business process correctly.
It's also just nice for how my brain works. I like being able to substitute terms and get an equivalent program. Or that I can remember a handful of transformation rules that often get me from a first cut of a program to an efficient, fast one.
It is. But I think that, for that purpose, I like F# even better. Even beyond getting access to the .NET ecosystem, you also get some language design decisions that were specifically meant to make it easier to maintain large codebases that are shared among developers with varying skill levels.
Lack of typeclasses is a good example. Interface inheritance isn't my favorite, but after years working as the technical lead on a Scala project I've been forced to concede that haranguing people who just want to do their job and go home to their family about how to use them properly isn't a good use of anyone's time. Everyone comes out of school already knowing how to use interfaces and parametric polymorphism, and that is fine.
Anecdotally, the handful of people I've known that worked in commercial Haskell shops, after the initial honeymoon period intensified by actually finding a paying Haskell dev job, wishes they were using a more practical "happy medium" FP language. I don't know anyone that's used F# in production, but nobody I know that's worked in Elixir, erlang, or elm environments has expressed the same frustration.
As someone who has used F# in production at least in my experience running teams that do (on some very large products generating significant value to be vague about it) teams don't want to stop using it once they get over the initial hump. It's almost the opposite - they express frustration when they are required to jump to a more mainstream language. "Why when we have no issues and can do everything we want" is feedback I have received.
My opinion: If F# was on any other platform than .NET it would be a widely adopted language - the problems are cultural not technical/capability based. Not because .NET as a platform is bad technically (its gotten quite good and cross platform), but the culture in that space (typically enterprise dev shops) isn't really one of trying new things for marginal benefit - There's safety in the C# herd. There's also seems to be a reluctance for certain regions/areas (e.g. SV) to adopt .NET in general - culturally they are probably the regions more likely to adopt more niche languages and try new tech as well.
I don't think there is pressure to move F# teams off to C#. It's probably unheard of, but there is also a fact that few companies use it.
The bigger problem is that F# is even more affected by a problem that .NET suffers from in general, through no fault of its own: there is a degree of bias in the industry against .NET outside of its ecosystem (and even within it, some just skill to appreciate the tools they have) so perfectly capable and performant applications, the teams that own them are sometimes pushed to migrate to Go/TypeScript/even Java - all of which constitute a significant and equally frustrating downgrade. The most recent big example of that is Walmart forcing all ex-Jet.com teams to rewrite their F# codebase in Java, where the latter just faced with lack of understanding from Walmart's architects what their stack can even do or what it is.
Another factor is F# sometimes pushes just ever so slightly over the budget for "unconventional" - it's different enough from C-family of languages that it takes some getting used to, and has a learning curve. This combined with the fact that C# itself is very flexible and has been leaning into its functional side for a long time put F# in an awkward spot - it's not the kind of upgrade to C# that Scala or even Kotlin are to Java.
I think what will help F# is the growth of .NET adoption in the industry itself - it's just hands down better offering than most of the competition by sheer existence of ASP.NET Core and EF Core alone in the business domain, and is also a straightforward and fairly open core kind of an ecosystem - companies that use F# would likely find it much easier to contribute to F# itself or .NET runtime than companies that use Scala or Elixir or what have you. In a way, it really is just a marketing issue.
> " don't think there is pressure to move F# teams off to C#."
To clarify I didn't say the move was to C# specifically. What I meant was another tech stack often in a different problem space (e.g. frontend with Typescript, scripting with Python, etc) the staff just say F# does it for what we need as well. I agree with your point however - if you are in the F# space already and your staff are already familiar with it there's little reason to move to C# since they have the same ecosystem anyway expect maybe for some edge cases and generated code projects.
Interesting. I wonder where you met them. I've worked with tens of Haskell programmers in my career, most of whom were sad if they were required to stop working in Haskell. I've never met anyone who actively sought out a Haskell job and then subsequently wanted to stop working in Haskell.
Many of my colleagues would describe themselves as taking pay cuts to write Haskell provisioned with Nix with type-safe interop with Ruby and our frontend. If you're into it, you're into it. And it has the effect of putting absolute mutants on your team.
I am not prepared to hunt down the citation, but several years back I stumbled across a paper that was trying to compare the effectiveness of various languages for grinding out "domain logic-y" code. Among the ones they evaluated, Haskell came out on top in terms of both time to get the work done and correctness of the implementation.
IIRC this was testing with students, which would be both a strength and a weakness of the experimental design.
Let's suppose that you and I are non-technical founders of some medium-size software product.
If we were to rank the most important factors in choosing how to build our product, I think we may be able to agree that they're likely:
- The talent pool and availability of the language
- The ecosystem of libraries and ancillary tools like monitoring/debugging/observability
- The speed-of-development vs cost-of-maintenance tradeoff of the language
I will give Haskell that it can be rapidly written by those proficient, and tends to have less bugs if it compiles than many languages.
But for "what language is easy to employ and has an expansive ecosystem + tooling", I feel like you have to hand it to Java, .NET, Python, TypeScript, Go, etc...
That's shifting the goalposts somewhat! Can Haskell be used for LOB software. Yes! In fact it's the one I am most effective in for that purpose. If I was starting a startup, it would be in Haskell, no question. "Let's suppose that you and I are non-technical founders of some medium-size software product ..." Well, that's something else entirely.
I think you're taking a particular view of things that can work, but it's not the only correct view.
> The talent pool and availability of the language
There are certainly more Javascript or Python developers out there than Haskell developers, but I think it's wrong to imply that Haskell is a hard language to hire for. There are more people out there who want to work with Haskell than there are Haskell jobs, and picking Haskell can be a really great way to recruit high quality talent. It's also quite possible to train developers on Haskell. A lot of companies hire people who don't have experience with their particular language. The learning curve for Haskell may be a bit steeper, but it's certainly tractable if you are hiring people who are eager to learn.
> The ecosystem of libraries and ancillary tools like monitoring/debugging/observability
Other languages have _more_ of these, but it's not like Haskell is missing basic ecosystem things. I actually find that Haskell is pretty nice with this stuff overall. It's not quite as automatic as what you might get with running something in the JVM, but it's not that big of a lift, and for a lot of teams the marginal extra effort here is more than worth it because of the other benefits you get from Haskell.
> The speed-of-development vs cost-of-maintenance tradeoff of the language
Haskell is really excellent here in my experience. You can write unmaintainable code in any language, but Haskell gives you a lot of choice in how you build your application, and it makes refactoring a lot nicer than in any other language I've used. You don't get some of the nice IDE features to rename things or move code around automatically, but working in a large Haskell codebase you really do start to see ways that the language makes structural and architectural refactoring a lot easier.
> But for "what language is easy to employ and has an expansive ecosystem + tooling", I feel like you have to hand it to Java, .NET, Python, TypeScript, Go, etc...
Those are all perfectly good choices. I think what people tend to overlook is that Haskell is _also_ a perfectly good choice. Everything has tradeoffs, but Haskell isn't some terrible esoteric choice that forces you to leave everything practical on the table. It really is useful day to day as a general purpose language.
Haskell is a nightmare if you need truly seasoned industrial programmers.
Which supports the argument that "it's good for startups" which generally want to exploit young cheap talent. But as soon as your business starts needing industrial wizards you're out of luck.
The reasons/requirements to choose haskell are:
1. You already have a confident haskeller or two on your team, ideally senior
2. Your tech needs are vanilla and back-end heavy -- writing UIs in haskell is a nonstarter, and heaven help you if you're not doing vanilla web apis + postgres etc
3. You want primarily junior- to mid- talent (great for keeping burn low)
There are niche examples like compiler tech or provers where haskell is in fact dominant. It's also fantastic for threading and parallelism. Otherwise the claim that it's a good choice requires all three of the above to be true.
I still think this is an unnecessarily dire and antagonistic view of things.
> 1. You already have a confident haskeller or two on your team, ideally senior
There are really only three reasons any particular tech stack is ever selected for any project.
1. It's the standard at the company and you don't have a choice
2. You happen to be working in an extremely specialized field where one language is dominant (e.g. Haskell for compilers, python for AI)
3. Someone picks a language that they like and are confident in
I'd suggest that across the entire industry, (1) dominates by a large margin. It doesn't apply as much to startups though, because by definition startups aren't going to have a lot of existing code and won't have developed restrictive standards.
So yes, the biggest reason to choose Haskell is that you have a confident senior haskeller on the team.
> 2. Your tech needs are vanilla and back-end heavy -- writing UIs in haskell is a nonstarter, and heaven help you if you're not doing vanilla web apis + postgres etc
I agree with you about UIs. It's not a good experience and I wouldn't suggest Haskell for that. There are other specific areas where I wouldn't suggest it outside of a hobbyist project, like games or mobile development. There are still a lot of programs that need to be written and benefit from Haskell's strengths though, and sure, a lot of them are CRUDy web API things, because frankly that's most of all software that gets written.
> 3. You want primarily junior- to mid- talent (great for keeping burn low)
Haskell is perfectly viable if you want to hire a team of junior and mid level developers (so long as you have a more experienced person on the team to help them learn), but not exclusively useful in that situation. There are experienced Haskell developers out there, and there are a lot of highly skilled and experienced developers who are interested in- or at least willing to learn- haskell.
In general, I'd say that Haskell is a great choice for _most_ types of development, and can work for teams with a wide variety of experience levels. It's a real asset for hiring because there are more people who would like to work with Haskell than there are Haskell jobs out there, and in general I think Haskell still benefits from the python paradox (https://paulgraham.com/pypar.html) where people who know or are interested in it tend to be above average.
> Haskell is perfectly viable if you want to hire a team of junior and mid level developers
Looking beyond permanent hires-
In my python-based startup, we routinely offload work to contractors on an as-needed basis. Having a flexible staffing level saves us real dollars, and staffing flexibility delivers products to customers faster, which generates revenue dollars faster. From a financial perspective, our staffing flexibility delivers real, measurable economic gains.
Non-mainstream tools like Haskell break that model, effectively incurring an economic cost. Sure there are Haskell contractors, but their numbers are minuscule compared to python contractors. Given the enormous pool of python contractors, we cherry pick the very best who understand our business, our tech stack, and our work culture.
I’ve had good luck hiring contractors for Haskell related problems for much the same reason that hiring full time engineers to work with Haskell has gone well: the average quality of Haskell developers is high, and there are more people who want to work with Haskell than there are opportunities.
That probably wouldn’t scale up if you were hiring many tens or hundred of contractors. My experience with that degree of outsourcing hasn’t been positive irrespective of language though.
> CRUDy web API things, because frankly that's most of all software that gets written
If that statement is true (I couldn't say), I might argue it's incomplete, because the elephant in the room is JS/TS. Haskell-in-the-browser is in horrible shape, which means that options for tight integration with UI code are severely limited. If there really is endless work for UI-less, JS-foreign web tech then that's great for Haskell ... maybe.
Because ... look what you've done to have an incrementally better experience writing CRUD apps:
1. You've got existential bus risk in your senior haskeller, and you live or die by their quality and experience, which since there's strictly less of them, is probably off the beaten path.
2. You've chosen a stack that has a massively smaller hiring pool. The benefit of "oh they'll take less pay because of the shiny" is maybe great at first, but if you have any adoption and attendant perf problems, you'll need those senior devs. Even if they are willing to learn, they can't use the tools they know best so at a minimum you're losing momentum.
3. This is more typical of smaller langs but Haskell has it's own spin on it: you're risking not having library support for a million things when you need it. Haskell has the false comfort of doing C FFI well, but that just means that when your core integration stops being maintained, now your haskellers better be C-savvy as well.
> dire and antagonistic view of things
If that's true, it's because the promise is so much greater than vanilla apps. I loooove runtime languages and Haskell should be the best of them: better-than-average GC, incredible concurrency support, great FFI, flawless refactoring, perfect DSLs, solid apps. It makes it worth forcing programmers to learn an unusual language if you can really conquer anything, and for a bright moment in the 2010s it seemed like you could.
Now, Haskell has lost that momentum and mindshare to Rust. This is literally true with some core Haskell library maintainers straight-up defecting. There are signs in the Rust community now of slowing momentum, and for similar reasons. There might be a boom-bust cycle for advanced languages with shaky industry support, I don't know.
Haskell leadership needs to change. There needs to be a laser focus on tooling, on browser compilation toolchain, on industry adoption. Avoiding success at all costs was a clever idea for a minute (ok for 3 decades) but post 2010s, there seems to be an active desire to shut off industrial adoption to keep it safe for the tinkerers. (End rant)
My experience is Haskell is one of those ecosystems that has a greater talent pool than there are available positions. I feel like cost of maintenance is pretty nice because you have less bugs. You may have to roll up your sleeves and get your hands dirty to update open source libraries or make stuff that is missing, but code reliability seems to be worth it.
Not just that; the whole Cardano blockchain is running on Haskell, with 100% uptime and high trust. It’s a hugely impressive system, well worth studying.
If that's what you're looking for, why not rip out most of the language? You'll end up with something that looks a lot like Elm. You'll end up with a purely deterministic program with no i/o (albeit with a kind of crappy debugging experience).
Well because you need the rest of the language to make your program tell your system to do stuff.
Turns out `IO` is the most essential and useful bit of a Haskell program. That part can be left to the programmers. Haskell has a lot of facilities for making that nicer to work with as well.
I find that when I tell folks I work in Haskell full-time you can see their opinion of you change on their face. I'm not some kind of PhD genius programmer. I'm pretty middle-of-the-road to be honest.
It's just nice to have a language that makes the work of writing BLOBS straight-forward.
I've heard of systems like Roc + Nea taking this to the extreme [0]. Totally a way to go.
Haskell, to some extent, can help you structure your program in this way where the business logic is just simple, plain, old functional code. You can write the data marshalling, logging, and networking layers separately. There are a few ways to tackle that in Haskell in varying levels of complexity as you would expect coming from other general-purpose programming languages.
Haskell is just hard when you get to the advanced stuff. I mean beyond monads there’s the state monad, lenses, etc. a lot of these are not trivial to wrap your brain around. Like for Java head first design patterns I read it and I’m good. For monads it took me weeks to wrap my head around it and I still don’t understand every monad.
Yeah I get a bunch of basic apps can be modeled easily, you get unparalleled static safety but programmers will spend an inordinate amount of time figuring out mind bending algebraic patterns.
I think something like ocaml or f sharp are more down to earth.
The advanced parts of most languages can get hairy. Don't mistake familiarity with complexity. Even Java has hard, dense code that is difficult to work with and learn.
I tend to stay away from the advanced parts of Haskell when writing BLOBS.
The advanced stuff is there when you need to write libraries that need generic code that works with types you haven't defined yourself. You learn it as you go when you need to.
But when I'm writing BLOBS I mostly stick to using libraries and that's pretty straight-forward.
The vast majority of business logic can be modelled with a handful of simple types and pattern matching. Very few design patterns are needed. And if you keep to the simple parts you can even teach the syntax (just the types) to non-technical contributors in an afternoon. Then they can read it and help verify that you implemented the business process correctly.
It's also just nice for how my brain works. I like being able to substitute terms and get an equivalent program. Or that I can remember a handful of transformation rules that often get me from a first cut of a program to an efficient, fast one.
And it's just fun.