After 7 years in production, Scarf has reluctantly moved away from Haskell
23 points by ucirello
23 points by ucirello
Haskell to Python is a hell of a switch. Going from advanced type system, no NULL, and compile time checks to a dynamic language without those no doubt feels freeing at first. However, as the amount of Python grows surely the runtime errors will start to creep in. Even if they're quick to fix, they still happen in production first. I'm surprised that they didn't try to retain at least some of what Haskell offers by using a faster compiler like OCaml or Go—it probably doesn't matter much to the LLM what language it has to generate.
Haskell to Python is a hell of a switch.
Indeed. If that's a viable switch for them, it makes me wonder what they wanted to get from using Haskell in the first place. I mean, when they can afford to throw away most of the things that make Haskell Haskell, maybe they weren't relying on those things.
I write Ruby and rust. I am much more confident in the rust LLMs write than the Ruby.
Compile times might be slow, but when you lose a robust type system you need to rely more on testing edge cases to exhaustion . Which starts out fine enough but it's easy for suites to spiral out of control. 10min is annoying, 30 is insufferable, an hour or more and when you hit a flappy test and have to restart it you'll be clawing at your face.
It's not inevitable, but having both high confidence exhaustive tests AND a test suite that's fast requires intentional energy, time and therefore dollars.
Also im not suggesting types replace tests (I write plenty of tests in rust). Also the python type story is better than Ruby so who knows. It's probably easier to hire python devs than Haskell.
A runtime error is a bug. I have been using Emacs for many years without encountering a runtime error. The idea that software written without static type checking somehow has to have bugs is disproven by reality.
That is a weird argument... I wrote a good share of emacs configs and modules. Emacs is a big runtime, and more often than not I found myself trying to guess the shape of the expected input structure the runtime expects from me. And it's common for many dynamically typed languages. One needs to write the code, and then run it, trying to catch the unhappy path (or by having good test coverage). Python is not an exception, and mypy doesn't always save us there.
I'm just pointing out that static typing fans have this idée fixe that programs written in dynamically-typed languages somehow invariably suffer from runtime errors -- which is simply not borne out in reality.
Static types don't eliminate bugs they reduce surface area by making certain invalid state impossible to represent.
You can write rigorous programs in dynamic languages, but it requires writing defensively and takes skill to do well. Presumably you possess that skill.
I'm on a team that writes highly rigorous bash (not a joke). And Rust. It's possible to be productive on both. But I can tell you which PRs are a lot easier to review,
It reflects my experienced reality. For 10 years I worked on multiple Ruby on Rails projects in multiple companies and they all had a constant background of runtime errors, often related to nil. We would fix gem them, but it was relentless. Some projects were worse than others. All projects had tests and were developed in an environment that valued quality, not a move fast and break things attitude. In the statically typed projects I've worked on since then unhandled errors are vastly less common.
Instead of reducing this article down to "AI whining," I'll focus on other aspects I see here.
This is coming from someone that is an active participant in the Haskell Foundation, so not a simple user of Haskell. One of the famous mantras of Haskell has been "avoid success at all costs" (which should be read as avoiding "success at all costs", not avoiding success in general). Haskell has always had this academic lean to it instead of focusing on pure pragmatics and serious applications (as opposed to Rust, for instance). The author believes the writing is on the wall that the future success and penetration of programming languages depends heavily on AI-based workflows and how the language, its tooling, and its public literature empower those workflows. I can see why that argument is being made.
But.
I also see that all of his suggested improvements to the language for helping AI workflows would also directly help human developers. There's no reason AI need to be the crux of the argument.
I'm a hobbyist Haskell developer. I use AI workflows at $JOB because I am essentially required to. In my free time I love to write code myself, and Haskell is a wonderful language to write personal code in and feel a tingling sense of pride of craft. ("Oh! What if I refactor my monad transformer stack approach to effectful types instead?") I'd of course love to see better tooling, caching, documentation, examples, up to date libraries, etc, but for ME as a human developer not AI. If it also helps AI workflows that's a great bonus.
He mentions that industrial users of Haskell (like his company) have been asking for this sort of work to be prioritised for a while - the idea is that AI's made it urgent rather than nice-to-have.
tl;dr: predictably spends one or two paragraphs talking about actual problems and then seven moaning about how some of the community has anti-ai sentiments
tl;dr: predictably spends one or two paragraphs talking about actual problems and then seven moaning about how some of the community has anti-ai sentiments
At the time of writing your comment is sitting as +38, but it's just... factually wrong? Like, I get it, you probably don't like/use LLMs, and don't want other people to use LLMs, but does that mean the way you engage is by posting an incorrect summary to mislead people?
Here are essentially the only two paragraphs which are talking about anti-AI sentiment in the community:
And yet, when AI comes up in Haskell spaces, the conversation often seems more focused on restriction than enablement. I understand why people have concerns. There should be norms. There should be disclosure. It is reasonable to ask people to say when code was AI-assisted, what models were involved, and how it was reviewed.
But there is a strong cohort in the camp of "do not use LLMs," or even "we do not want to support workflows that involve LLMs," which I believe is the wrong side of history. I predict it will prove bad for the language’s ecosystem.
Is this "moaning"? It's trying to establish middle-ground.
On "one or two paragraphs talking about actual problems", here are some paragraphs with mentions of real problems:
The biggest ones were compilation time and ecosystem friction. We spent a lot of time optimizing builds, caches, Nix, developer environments, CI, and all the other machinery you end up needing around a serious Haskell codebase
If you are working on one thing at a time, maybe you pay the cold build cost once and then keep going. But increasingly, that is not how I want to work. I want to spin up multiple worktrees [..]
[..] caching is never perfect, and the amount of effort required to make it feel good enough is itself part of the problem [..]
If everything is cached and you make a small change, you can often get a very fast compile. Sometimes the loop is 20 seconds and that feels great. But that is the best case [..]
From customer call -> ticket filed -> PR opened -> PR reviewed and iterated -> merged -> deployed, we can sometimes have bug fixes live before I get off the call with a customer [with Python]. Resisting this kind of productivity is not an option anymore.
How can we scale reviews? How do we make library docs full of copy-pastable, realistic examples, not just beautiful types? How do we make project bootstrap fast? How do we make error messages more agent-friendly? How do we reduce cold build times? How do we make common industrial patterns obvious to a model that is trying to help?
Yeah… sounds like a good thing for Haskell if this ends up being their Bun moment.
Out of the loop; What was the Bun problem? Any links?
https://lobste.rs/s/6rkdik/rewriting_bun_rust
Bun, a JavaScript runtime, has been rewritten in Rust, being previously written in Zig. There are two links: perspectives of the CEO of Bun and of the BDFL of Zig.
An article full of fallacies written by someone undergoing AI psychosis. Bit sad to read, tbh.
Just to summarize: This person has a working code base in Haskell. He was gifted by the Machine God a magic box which can solve any problems with code.
Compiler slow -> We need to rewrite our working code base in Python?????
There's not much of value to be taken from this article, except for the compilation times (which are far from an unknown, see https://blog.haskell.org/what-would-you-see-changed-in-haskell/).
I'm just astounded by the fact that he is holding the "magic box" wrong. Thanks to ai the effort to maintaining a private fork is gotten really low, so just go and fix the issues you see in the compiler?
Can relate, I have a similar challenge with Rust, compile times are becoming more annoying than they used to be. I have considered OCaml. The ecosystem isn't comparable to Rust, but AI is also pretty good at filling in the library gaps quickly. I haven't made the change, but we'll see over time.
The model can often avoid the mistake before the compiler ever sees the code. And as the models get better, the relative value of catching every possible issue at compile time changes.
This is not to say type safety has become worthless. But the cost of typechecking matters much more now. If an LLM can produce a working implementation in a few minutes, but your compile step takes dramatically longer, then your language and build system have become a bottleneck in the development loop.
This is the complete opposite of my experience. What am I missing?
LLMs can write "correct" code if you mean code that's hard to find bugs in — sometimes though it's because it's unintelligible and overly complicated. If by "correct" you mean understandable, reviewable and verifiably correct, then no, AI sucks balls. Types in a way force some degree of intelligibility, it rejects the kinds of slop an LLM would naturally spurt out, forcing it into rewrite it a couple of times before, and making me review something much cleaner. For me, types were only good.
About compile iterations being slow: I get it, Haskell can take some minutes for a (warm) build after a change. But in what universe you're producing so much code that this is the bottleneck of your development?
This is interesting because there's some overlap between what could benefit regular users and LLMs writing code.
I spent some time fiddling with Haskell as a hobbyist, rather than an industrial user, and I found the tooling alright. Some bits could improve (essentially, for anything you try to do that the community's answer is "Nix"), and I would welcome those improvements even if I'm not using AI.
What I don't really see is the value in focusing on improving the experience around using AI tools. If people are just using agents to get things done and then reviewing the output, why do they care about the language itself? It seems to me that in a context where people consider that the code is less important than the outcome, using a language like Haskell just adds unnecessary complexity.