I strongly agree with the premise of this article, which is why I am surprised that the author moved away from Haskell to Python.
For some time now it’s felt clear (or at least extremely) compelling that agents need fast compile times in order to be effective, especially when you’re working in parallel. But the other thing that has felt just as obvious is that agents need strong type systems and narrow guardrails in order to constrain their outputs. These two things felt clear enough to me that, like the author, I wanted to choose a language ecosystem that maximized them. There _are_ languages that both have expressive type systems _and_ fast compile times. I wonder if the author investigated any of them, before deciding that no compilation time at all was acceptable.
In my case I landed in OCaml. I think there are other options in the space—Go if you want less typing but faster compiles; Rust if you want more types but slower compiles. My mostly vibes-based evaluation landed on OCaml, and I’ve been pretty happy with the results.
same argument to migrate from Haskell applies to Ruby as well.
& ultimately this is why Java/JVM keeps winning & to a lesser extent Typescript.
you benefit from the robustness of the JVM, compilation is fast, the language is fast enough.
to apply to Javascript/Typescript - good enough, fast enough though will not reach performance of JVM.
The justification in TFA smell like premature optimization. A nominal bottleneck is just that-nominal. It’s a good thing to keep in your back pocket but you generally don’t want to expend extra effort optimizing something until you have to.
I suspect that the cost of long compilation times (preLLM even) was actually quite high and the author is discounting/excluding those other factors and focusing on LLM feedback loops primarily as their justification.
As an aside short feedback loops are important, but the article ignores one major reason why: humans learn most effectively when the time between action and feedback is reduced because the contents of our working memory degrades over time (take the explanation with a grain of salt). LLM has no such restriction, so the only thing that matters is that the codegen can keep up with the demands from the actual product.
I'm not trying to be reductive but the article's a lot of words for "We're vibecoding our app now and the glorious (almost almighty) Haskell compiler is too slow for the agent to iterate it's mistakes until it gets it right."
The article makes a convincing argument that Haskell compilation is too slow for the fast code generation of AI. But python?
I have yet to experience a RHEL major version change that did not blow up all my tiny simplistic python scripts. I see the following options for using python: * run inside the container it was developed in * build your own python interpreter and environment and libraries and never use python pieces from the OS (i.e., act like a container without using one) * keep different versions of the code for different OS versions and use AI to rewrite all the code for the new OS version
Start to consider third party dependencies, and none of those feels tractable without an AI assist.
I've dabbled in C device driver code and kernel version differences were my only problem, not C. My perl scripts never break. My bash scripts rarely break. My dabbling in erlang didn't suffer from language version differences. My little elisp hasn't broken. Only python has inflicted this level of version pain. I have a colleague who says java has the same version pain as python, and from what I've seen from Jenkins maintenance he may be right, but I don't have colleagues who want to read java code, so I haven't written my own.
I am surprised by this take, honestly.
We're a Haskell shop (and have been for over 10 years now) and are finding agentic development with Haskell to work pretty damn well.
Cold compile times in Haskell are painful indeed. Our development practices don't really cause us to do that much - even with agents.
It's unclear to me if the development practices at Scarf that cause them to hit this pain often are worth it if it means giving up Haskell because the compile times are too bad. Maybe they are, but I don't think so.
For what it's worth, I've been using Haskell in production at Bitnomial, a financial exchange, and LLMs + Haskell is an extremely productive combo.
Since Opus 4.6, LLMs have been pretty clever at using fancy types with libraries like Servant and Beam. The expressiveness of the types, combined with feedback from the compiler, means that agents converge quickly to something that works. I don't think I've noticed agents having to run the compiler so often that compilation speed is an issue.
> Now there is a third place: code generation time. The model can often avoid the mistake before the compiler ever sees the code.
This is doing a lot of heavy lifting here. How do you even know a mistake has been "avoided", and safely, for that matter? The kinds of mistakes the AI will miss are the worst kind: subtle logical mistakes, buried inconspicuously within boilerplate code, hard to detect or reason about, until one day you wake up to find that your database has been replaced by a rickroll video.
Also, it's odd that they moved from Haskell to completely untyped python ... python may be no Haskell when it comes to type safety, but typing+mypy/mypyc goes a very long way.
I like this article, but I would take some issue with the concept of the percentage of time taken up being a major issue.
If you go from taking 2 days to write some code and 20 minutes to type check (which does seem long, don't get me wrong, but still) to 10 minutes to prompt some code and 20 minutes to type check, that percentage increase to me isn't enough to justify switching.
You're still almost 2 days ahead, and converting those 20 minutes to 20 seconds are not going to make you ship a feature appreciably faster. But those types stand strong and I don't believe they can yet be replaced by an LLM believing they're correct.
Having said that, I also think that Haskell should massively speed things up. Having strong types if nothing else should surely produce some amazing type-checking speed wins.
This is a good post. AI has changed the programming language trade-offs and, as someone running a company that uses both Haskell and Python, I hope that Haskell can adapt to this new era.
I would like to add one additional observation, since we have been using both Haskell and Python in production for a long time:
Haskell excels at platform work, while Python excels at product work.
Our infrastructure teams work in Haskell (and also Rust nowadays), while our product teams work in Python. This gives us the best of both worlds (in my opinion): fast and rock-solid infrastructure on the platform side, and fast development speed and quick iteration cycles on the product side.
This setup has worked well for years for us, but it remains to be seen how and if this is going to change as well in the new AI era.
OCaml is such an obvious solution to their problem that I'm shocked it wasn't even mentioned. You get fast compile times without sacrificing type safety.
I am increasingly wondering if we are in a post-language world in terms of development. Why would I ask an agent to write a server in anything other than the most efficient language, although efficiency can take several forms: runtime, token usage during development, and wall clock dev time (affected by slow compile times for example).
My intuition is that type-safe languages with fast compilers are the best option. Maybe Go? I personally prefer Java just due to my experience running it in production, but am not sure there's many arguments for it over Go in a greenfield application. The other candidate would be Rust, but I worry about token efficiency and tool performance, I suspect it's not worth it for the runtime improvements.
All that being said, in this article switching to Python seems like a wild choice. Relatively poor performance, no compile time checking at all. Python's big selling point was developer ergonomics, which seems largely irrelevant now.
These are all just thoughts at the moment, I should try to find some evidence one way or another.
I find the need for type systems is less important now. and thats me saying this after 15 years of coding in Java, Scala, Kotlin, Typescript.
Now I am using Elixir and incredibly surprised by how little I need static types. They are useful, but less needed now.
Never could believe I would say that. But I'm the most productive I ever been.
I get bugs of course, but they are related to queues lengths, retries, api errors, memory usage, performance, ... Bugs related to incompatible types are rare.
I write a ton of Python code. Modifying code without static types is difficult and error prone. If a function needs a new argument, all the callers have to pass it and all of their callers recursively. Maybe the calling function is just a function pointer that has been passed around and not searchable. I love Python for small tasks and tasks that are not critical if they fail.
I'm not a Haskell developer and I hadn't heard of this company "Scarf" before.
As much as I respect this guy who tried to work and push an alternative ecosystem, it's hard for me to shake off the impression that, rather than due to Haskell compile time, he moved to python because it's easier to find developers for it and it's the de facto scripting language for LLMs.
No problem about that, of course. Running a company is hard enough, I think that passion and idealism for a language/platform/technology out of aesthetic appreciation can only go so far and after a certain age just making money and reaching your professional objectives count more.
> The important metric: how long does your entire development feedback cycle take, and what portion of that time is spent waiting on your compiler?
> So far, we haven’t lost much in the switch. The type safety we gave up hasn’t been noticeable in any concrete way yet, especially considering our test coverage has never been better.
Moving to Python means you'll have quicker compile times but now you'll need a bigger test suite which will take longer to run to get feedback after code edits? In TypeScript, you can compile and execute without waiting on type checking, an option like that would help?
The whole article feels like a rationalisation for vibe coding your product from now on.
The author talks about how Haskell needs to catch up to stay relevant in "the AI era."
> That means taking AI seriously as a first-class user of the ecosystem.
Honestly for me any time a language or a tool markets itself as "for the AI era" or takes agents seriously as first class users, I run. It's a bad smell for me.
I'm happy that there are things like Haskell that are still focussed on correctness and sanity, and not pandering to the AI psychosis driven on by the market.
I am really disturbed by this ideological framing of "it's the AI era now" "we have to let the agents run" "speed, speed, speed" "if you don't learn to engineer with random garbage, you will be left behind!!"
Some of us will need to leave the cult of the empire of AI and live in caves like the desert fathers, committed to actually crafting correct things.
Haskell definitely needs to improve a lot of things, but moving to python is obviously a mistake for most cases. Golang is probably the best language for LLM things, it's got reasonably strong types, compiles very fast, and is simple. Much nicer to work with than Rust for example. But these days most code should probably be golang or rust if you're not building a webui.
I am writing couple of State machines and DSL in Haskell.
Haskell is great, once you write code, chance of certain kind of bugs appearing is very low.
Biggest problem i've is i develop on Apple Silicon and can't cross compile to x84 linux which is most common deploy platform for servers
Compare this is to Go, which is what i use for almost everything else, cross compile, copy to server and there you go! So simple.
this causes a lot of pain and suffering and slow development loop in Haskell.
I'd use Haskell for more things if someone solves this issue.
Please haskell community, come up with a way to solve this issue. It wouldn't be a problem if i've to install a JVM like we've for Java.
I've been a power user of LLMs for software development for a while now, and I've found two things to be true:
- The benefits of more "extreme" type systems are more accessible and valuable than ever. I have a fairly involved project built on Lean that I hope to open source this month, and it's been a joy to work in even for uses outside of mathematics.
- Readability, build time, infra complexity, and everything that affects your speed after finishing your implementation--these things now matter more than ever.
It's sort of a dual ergonomics problem, in some sense. And given that, the author's lament makes complete sense to me, especially:
"An AI-enabled Haskell ecosystem would ask different questions. How do we make Haskell easier for agents to use well? How do we get more high-quality Haskell examples into model training data? 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?"
Note that Scarf is not moving away from Haskell for performance-sensitive applications [0], which was the immediate question I had reading this.
[0]: https://discourse.haskell.org/t/after-7-years-in-production-...
Interesting. The major factor seems to be the latency of change-compile-test cycle.
I wonder if one of the reasons I've been getting such excellent results from LLMs with Clojure could be that they can immediately try things out in the running REPL. Rebuilding my entire application from scratch takes minutes, while connecting to a running system through nREPL and compiling single functions or namespaces takes less than a second.
> The type system caught real bugs.
> The model can often avoid the mistake before the compiler ever sees the code.
> The type safety we gave up hasn’t been noticeable in any concrete way yet [...]
> Type safety can be a huge advantage for LLM-generated code if the compiler is helping the agent converge quickly.
Well, good to have this question cleared up once and for all :-)
If loop time is a concern, I am surprised the author does not mention tests. Is it still worth it to wait for your test suite to run when an LLM can get it right quick ?
Edit: I dont quite buy that argument, in case it was not clear.
Edit2: oh, is it specifically about incremental compile time? In which case I understand that tests can be run piece-wise quick indeed.
Very surprised about this decision. I use strict languages much more with LLMs and they improve quality a lot. Working on a big python codebase is very painful with an LLM.
It remains to be seen if agentic development really provide an advantage, especially when you see the extraordinary fall in reliability of products and infra managed by early adopters. Development time is hardly the bottleneck in my company for example.
Also I assume the cost of development skyrocketed so much over the months that our company started implementing drastic cost reductiom measures everywhere that seem to mitigate any improvement we've had.
Even without considering vibecoding, compile time and compiler/lsp memory usage are my main concerns with Haskell. In fact, I'd say they're even more of an issue if you're going without LLM's since they affect human beings ;)
I don't have the experience, how high are Haskell compile times such that a switch like this is worth it? I have some experience with generated Python, Rust, and TypeScript, and I have not found that compile time is enough of a concern that it would offset additional safety of a stronger type system. Like some of the siblings I'm now starting to do experiments with Lean and other tools to get even stronger assurance about system behavior.
That's a very fair point, and Rust shares this fundamental issue as well.
That's where one better appreciate the work being done in Zig to get incremental compilation in milliseconds.
The choice of Python is quite interesting, and a big swing in the other direction.
This is the silliest take I’ve ever read. Strong type systems are an AI’s best friend.
Oh wow, Haskell to Python. Interesting. They must have really wanted to preserve cascaded dependency headaches.
___
Please don't let your kernel panic, I'm being sarcastic. You never know the level of emotional attachment some HN people have to their tooling...
I'm curious about the choice of Python, rather than TypeScript.
I find Ruby a very beautiful language, and Rails is an excellent web framework, but I need typed functions, record types and sum types.
They help not just with correctness, but also as living documentation that lets me understand AI generated code. TypeScript provides discriminated union, but not exhaustive pattern-matching, and its syntax is a bit verbose, but since I'm no longer writing most of the code myself, I can live with it.
However I can't imagine using Python or any other dynamic language going forward. There is likely good reason for you to choose it, and I'm curious to know what that is.
I wonder what will happen when LLM providers stop operating at loss. The whole claim of us being in AI era falls flat after realising that.
Every time I see a post like this it somehow turns into a conversation about AI. Are there any studies on this? How much better are typed languages for LLMs. I would expect the amount of data and scaling laws to have more of an effect on an LLMs coding capabilities than the language itself.
LLMs are heavily trained on Python.
We at Cachix have also moved on from Haskell about two years ago and I'm sure someone is going to make a comeback with a language that takes the lessons from it but starts from skratch.
We need more general purpose Elm languages in the space.
I feel there is something missing here. The narrative here suggests that the author's LLMs are generating perfect Haskell code that just needs to be rubber stamped by the compiler for execution. But, oh, that takes too long.
I'm skeptical; I would think that the problem would actually be that mistakes in a large body of Haskell code would be difficult to fix: that massaging the generated slop into compiling ranges from unpleasantly time consuming to intractable.
Might the author be hiding the honest statement of the problem: that he would rather move fast and break things as a slop artist, but the guard rails are too rigid in Haskell?
I was expecting yet another moving from Haskell into Rust article, instead they went to Python.
Who cares about performance.
Hey Avi - didn't know you were an HNer fun to see you / your co on here :)
I am absolutely baffled at the idea that LLMs mean you need less automated verification of correctness.
This is quite insane to me. If I compare the output of LLMs for python vs statically typed languages it's really not a good choice to go the python route. It consistently produce relatively garbage code along actually good code. My experience has that the better static typing you have the better the code becomes.
LLMs have made me move away more from python rather than into it. I'm very surprised by this experiences of the author. The article is all over the place as well. Going basically all in on Python because it is apparently better than Haskell for LLM use and than agreeing with someone that says Rust is the best.
Languages designers will have to make a choice whether to continue to design for humans or for big slop machines. The design goals are not compatible. This is obvious. I don't understand how anyone can miss such an obvious point.
Another obvious point is that an industry that runs on code slop will stagnate in terms of language an human tooling design.
I’ve been running my company on Haskell for a similar length of time.
Long compile times can be an issue, but it’s an issue that can be managed.
Would I scrap Haskell in favour of Python, now in the age of agentic coding?
No. No I would not.
Very interesting! I honestly would have expected the opposite: I was optimistic about strongly functional languages in the age of AI. The more modular and side-effect-free your code is, the easier it should be to constrain changes, catch slop, and reduce LLMisms like spooky hacks-at-a-distance.
It looks like the issues are in the compiler and documentation so hopefully it’s fixable… I write in Python every day but I do miss smarter languages and I hope AI doesn’t fully obliterate them.
The development workflow is changing, and Haskell as a language doesn't fit that new workflow anymore. The traditional strong type system basically forced you to spend a long time thinking before writing code. The upside is that this makes the code more logical and robust. But it's the exact opposite of the AI loop. It's not that the type system is wrong—it's that the toolchain that comes with a strong type system has itself become a bottleneck.
With AI coding emerging, a single person can now churn out 100,000 or 200,000 lines. And realistically, from my experience, once you go past 40,000 lines, it's hard to memorize everything. So what do you do? Human coding shifts toward writing tests and gates, and once you feel comfortable that things are safe, you add more features.
AI coding takes this to an even more extreme level. Learning Haskell is great for learning domain modeling—I learned domain modeling through Haskell myself. But now that AI has become genuinely useful, it seems like a fundamental shift in workflow is happening.
Realistically, for commercial competitiveness, the domain of code black boxes is getting larger. The number of lines a single person has to manage is increasing, but their cognitive limits haven't changed. Even the amount of background knowledge required keeps growing.
In that sense, I agree with the author's point. It's not that Python is a better language than Haskell, so people switched—it's that Python has almost no build-up process and it serves as the standard interface for AI models.
The value of a language as a product doesn't come from the compiler's excellence. It comes from its users.
Avi Press's article ultimately reflects the reality that if you can't stay ahead throughout the entire lifecycle, you'll fall behind your competitors.
Maybe I'm just echoing my own thoughts, but it's reassuring to see that a well-known programmer thinks similarly to me.
Finally...
Wow. Not a Haskell user, but a big user of other languages with expressive type systems (mostly Scala; some Rust). My experience is the complete opposite. I can't imagine using a language without a good type system to catch all the junk the LLM produces. In fact I thought people would move away from languages from poor type systems, like Python, given the cost of using languages with expressive type systems has decreased with LLMs.