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.
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.
- 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?"
[0]: https://discourse.haskell.org/t/after-7-years-in-production-...
> 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 :-)
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.
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.
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.
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.
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.
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.
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.
We need more general purpose Elm languages in the space.
Another obvious point is that an industry that runs on code slop will stagnate in terms of language an human tooling design.
I don't personally use Haskell for anything, but I use Lean and occasionally some other languages with expressive type systems, and like you I've found it to be a pretty great experience for working with LLMs. But I've also experienced what the author is talking about, with languages that sit at different points on the type system spectrum, regarding a languages ecosystem/infra layer becoming a bottleneck. I don't think it's ultimately about the type system but the broader ergonomics of the language/ecosystem.
So I think his criticism is less than expressive type systems are a pre-LLM concept, and more that Haskell has an individually bad "agentic coding story".
Refactoring spaghetti has become easier in the LLM era because it can just read all the code, and there is now a skill floor on the programmers that kicks in somewhere relatively high. The benefits of type systems might have suffered because of that.
One approach would be to not use LLMs.
That is: Have a Haskell base system. Have a Python "development" version on which you iterate at lightning speed. But also, in the background, moving at whatever pace it takes, have an agent running that imports all the Python development changes into the Haskell version. Have nightly builds of the Haskell version to reap its benefits (issues caught by the type system, more efficient native code). They must have continuous or nightly processes to fix bugs in the Python code anyway, there is no way that all the things they ship "while still on the call with the customer" are always tested on the full test suite and always 100% correct.
And it doesn't have to be Python/Haskell of course. The "development" version could be a (hypothetical?) interpreted Haskell. I have no idea if ghci would be useful for this. Neither do I know if the 15-minute Haskell build time is spent in the frontend (so an interpreter would have to pay that cost too) or in code generation or linking (which the interpreter wouldn't need to care about). Anyway, these are things I would think about before I did what the OP did.
I reckon language choice matters more at the edges of economic activity where a specific language feature really does make the difference in the end product, but most activity that is leveraging LLMs now is more generic enterprise SaaS software.
so does this mean that the LLM writes code that is so good that the compiler does not find any more errors?
or is it due to the nature of haskell that makes it hard to write bad code to begin with?
or just that because the haskell compiler catches more errors there is less broken haskell code for the AI to train on?
and what does that mean for the switch to python? if the python compiler/interpreter doesn't catch as many errors do we even know that the code is good?
or is this more like the belief if the LLM can generate good haskell code, surely it can also generate good python?
what's the solution here? speeding up the haskell compiler? if that were easy, would it not already have happened?
personally i still don't trust LLM code generation. i didn't learn haskell yet, but what i hear about it makes me more likely to trust that LLMs can generate good haskell code than python.
i believe the future in LLM code generation is code that can be proven to be correct. proving code correct has been a research topic at some point.
Also, for some reason Optional[T] became deprecated, just as the ecosystem finally embraced types ~3 years ago.
In fact, one my company's greenfield projects decided to use TypeScript instead of Python for the [surprisingly] more consistent tooling, and the fact that the big LLM providers all have official TypeScript SDKs anyway. Also, for agentic coding, LLMs don't seem noticeably worse at TypeScript than Python.
My experience can be summarized as:
- for some reason we need 2-3 static analysis tools just for typechecking
- no tool understands each other's comment directives
- each tool reports a different error in your codebase
- even big libraries (e.g. matplotlib) make half their functions return Any
- you'll be tempted to silence the "partially unknown type" warnings, and you'll have to do it for each tool that's running.
But I do think what benefits LLMs is the speed and accuracy of feedback. Type systems cover the accuracy part, but haskell was killing them on speed. It seems like a strange choice to go so far the other way on accuracy when there's a lot of languages in between. But I'm not familiar with the project so not in a position to call it.
It's not also really about expressiveness IMO. I've found LLMs to be best with more constrained type systems: they are better at ocaml than they are at 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 suspect you’ve nailed the answer: it’s probably not easy, although it’s also possible that it just hasn’t ever had a lot of attention paid to it because it’s been generally fast enough for their user base?
if my CEO wrote this article, I'd quit [1] in an instant
[1] "quietly" while i found gig+1. oh and the private out-of-band engineering gossip and trash talk would surely be hilarious
Optional[T] is now T | None. Means exactly the same thing but doesn't require an import. Support for the older syntax presumably won't be removed for a long while regardless.
When the potential set of behaviors you could write a program to have is infinite, but the actual behavior you want is singular, a programming language is more importantly defined by which ones it eliminates up front than which ones it lets you write (assuming it lets you write the one you want at all, but that's almost always going to be the case for most general purpose languages). Bugs are just false positives in this framing, where the program you wrote seems like the one you wanted, but there's some divergence between what you thought you were getting and what you actually got, and catching some of those up front is a huge part of why type systems are so useful.
The amount of certainty random people have that LLMs have already revolutionized software development seems to be directly proportional to the media awareness of the AI companies finance unsustainability.
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.
> 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?
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.
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.
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.
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.
But I'd look at people a bit oddly if they said: 'We didn't want to set up CI caching and compiled languages took 30 minutes per run so we changed our entire codebase to python'.
Maybe it makes sense for them, and caching across dynamically spawned VM's is admittedly a harder problem which most build systems aren't great at, but still. I can easily believe that getting build caching to be reliable would be a lot of work, but is it more work than a full rewrite of a significant codebase?
- None of us are experts in Rust, and we're all solid at Python.
- Rust felt like an under-correction for what we wanted (get all friction in front of the LLM out of the way).
- Our high-performance stuff is not being migrated at this time (Scarf Gateway), so we're just talking about basic CRUD backends here. Basically any language will work.
I read the second paragraph of linked article as saying close to the opposite of that, particularly,
"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."
In other words, LLMs are much less likely than humans to make dumb, fat-finger mistakes, and, when they do, are able to catch and fix them more quickly, ergo the value of type checking has fallen.
Everything in the prior sentence is, obviously, highly debatable. But it felt like part of the premise.
And that is not even considering how often the agent needs to run tests to get it right.
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.
> 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.
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.
- haskell exceptions and laziness are devastating for production
- too small ecosystem, had to write 10+ SDKs (now with AI that's less of an issue)
- haskell ecosystem is too fragmented due to prima donna prevalence
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.
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.
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?
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.
I would also add Kotlin, Clojure and F#.
Scala not really as the compilation is not much better, and since the Scala 3 reboot, the ecosystem doesn't seem to be doing that well.
The market opportunity for Haskell on the JVM is gone, although they are doing cool stuff with capabilities.
Regarding the first, I think you're probably right, but then again, if there is a 15-minute base cost, it's hard to amortize that through fewer incremental runs of the compiler.
(Which isn't to say that I think they are doing the right thing.)
___
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...
IMHO there are a bunch of reasons
* Scala 3 was a Python 3-esque disruptive event
* Perception as an overly-complex kitchen-sink inclusive language
* Kotlin took up the "better Java" mantle
* Rust became attractive to devs not committed to the JVM
* Go became less sucky
* SBT is disliked and Metals was buggy and unstable (and still slow)
* Suffers from the "we won't be able to find devs" problem where Kotlin, Rust and Go don't
* A bunch of community drama drove some devs away to Rust
I say this as someone using Scala 3 with ZIO effects system and Mill build tool and thinks it is fantastic.
There were other breaking changes as well.
https://docs.scala-lang.org/scala3/guides/migration/compatib...
This naturally broke all the tooling.
Then you have Metals for VSCode InteliJ plugins, while the Eclipse plugin was dropped.
InteliJ plugin is much further than Metals, however there is the conflict of interests with pushing Kotlin instead.
Meanwhile most Scala shops have pivoted to also give feature parity on modern Java, and Kotlin, thus reducing the interest in using Scala in first place.
However as mentioned, they are doing cool stuff with capabilities at EPFL for Scala 3.
https://virtuslab.com/blog/scala/introduction-to-scala-3-che...
Avi Press | July 10, 2026

—
This has been a hard post to write. I almost didn't write it at all, since I prefer to build and promote than to critique. However, I hope this post can add constructively to the discussion about Haskell’s future. I must underline that I'm not writing this criticizing Haskell from the outside. I care enough about Haskell to be honest about why Scarf has reluctantly moved away from it, in hopes it sways people in the community to take this feedback seriously.
For the last 16 years, I have been a huge fan of Haskell. It has been undeniably the most important programming language in my life. Learning it made me a much better programmer. I have advocated for it, built a company that runs on it, and I serve on the board of the Haskell Foundation and the Haskell.org committee.
I have also been open about the places where I think Haskell needs to improve.
Since Scarf launched, our backend has been built in Haskell. The main API that powers our app uses libraries like Servant, Beam on top of PostgreSQL. We also built a high-performance Haskell service for Scarf Gateway directly on top of WAI, which sits directly in the download path for a high volume of open source package traffic. These systems have real uptime requirements, contractually committed SLAs, and we have managed that successfully in production for years.
We put Haskell through a serious production test, and many of its promises held up. The code was reliable. The type system caught real bugs. The language forced us to be thoughtful about how we modelled our domain. High performance code has been generally straight-forward to achieve.
But the costs were real too. 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. For a long time, that was workable. Our team knows the language and tooling deeply. We knew where the sharp edges were, and we mostly lived with it.
Then AI changed the tradeoffs.
LLMs are now very good at writing code. They are not perfect, obviously, but they are good enough that the economics of software development have changed.
Historically, I thought about errors as something you caught in one of two places: at compile time or at runtime. Now there is a third place: code generation 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.
The important metric: how long does your entire development feedback cycle take, and what portion of that time is spent waiting on your compiler? If a human spends an hour writing some code, a long compile cycle is annoying but may be tolerable. If an agent can draft a plausible change in minutes and then spends even 15 minutes waiting for the project to build from a cold start, the compiler has now moved from being a papercut to being the dominant cost of that thread of work.
This becomes unbearable when you start using many coding agents in parallel.
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, fork off different lines of work, let agents try things, review the results, and keep the useful ones. In that world, cold start time matters a lot. If every new worktree needs a long Haskell build, or needs careful cache setup, or burns a ton of memory, then every new thread of work starts with a tax. If I want five agents exploring five branches in parallel, that tax multiplies.
People in Haskell talk a lot about caching, Nix, remote builders, and similar tools. Those tools help. We used them. But caching is never perfect, and the amount of effort required to make it feel good enough is itself part of the problem. In practice, parallel AI-assisted development wants cheap, disposable execution contexts. I want to be able to say: fork this off, try the change, run the tests, show me what happened. Our Haskell environment was not cheap enough for that style of work.
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, and the best case is not what you can optimize the whole system around. The deeper your change goes into core parts of the build plan, the less that story holds. In an agent-heavy workflow, you end up caring a lot more about the cold-start case, the average case, and the deeper-change case. The amount of engineering effort required to make the perfect-cache case happen reliably is itself part of the tax.
That became more and more painful.
At Scarf, we started doing all new API work in Python. We deployed a Python API server alongside the Haskell one, routed requests to the right place, and began moving functionality over as we touched it. New API routes go into Python, existing Haskell code keeps running, and over time the new server becomes the main path and our Haskell footprint will shrink.
That approach let us move without the risk of a dramatic cutover. It also meant we had to reimplement some core things: authentication, database access, shared models, deployment images, tests, and operational glue. Historically, that kind of setup work would have felt expensive. With LLMs, it wasn’t bad, porting existing code to a new language is quite straightforward for today’s models.
The time we got back in our development cycle, from waiting and wrestling with the toolchain has now been reallocated to shipping more features with more comprehensive testing. AI is good at writing a lot of tests. You still have to watch it, because it can absolutely write garbage and fake tests, but the loop is fast enough that this tradeoff works much better than I would have expected a few years ago.
The result is hard to capture in a single metric. PR throughput did not obviously go up. Commit volume is noisy. Lines of code is a bad proxy. Deployment count is muddy because it includes previews, infrastructure, and other noise. But the productivity change is visible in the shape of what we can now ship with high effort, with minimal oversight, and even what we can ship fully automatically. 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. Resisting this kind of productivity is not an option anymore.
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. Now when bugs do make it out, we can hotfix them at a pace I’ve never experienced before; fixes are literally one slack message away now. Our engineering team is more energized by the productivity gains and a completely new frontier of technology to wield. We are spending significantly less time thinking about the developer toolchain that we had to in the past.
Haskell is in real danger.
AI is here to stay. The people and ecosystems that use it well are going to move much faster than the people and ecosystems that do not. I do not think this is subtle anymore. A skilled AI-powered engineer can now do work in days that used to take weeks or months.
I also want to be clear about where I am saying this from. I am not outside the Haskell world throwing rocks at it. I am directly involved with language leadership via my role(s) in HF. I do have some ability to help, and I will continue to help where I can. At the same time, my spare time is greatly limited by the reality of running Scarf. I’m trying to not stand idly by, but I certainly am limited in my own ability to unilaterally change these dynamics.
There are plenty of people in the Haskell world who also see the same shift in economics, and who want Haskell to move faster to adapt to them. But net-net, the progress of the Haskell toolchain and ecosystem is not where I think it needs to be.
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.
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?
Haskell should be unusually well positioned to be relevant to AI-enabled engineers and agents. Type safety can be a huge advantage for LLM-generated code if the compiler is helping the agent converge quickly. But that is not the same thing as optimizing the language for humans writing code by hand. Agents have different bottlenecks. They are cheap at generating code and expensive when blocked. They benefit from fast feedback, clear examples, low setup friction, and errors that help them repair the code quickly.
If Haskell wants to be great in the AI era, it needs to optimize for that world on purpose.
I want Haskell to grow. I want it to matter. I want the things Haskell is good at - correctness, maintainability, compositional design, principled abstractions - to be part of the next era of software.
But these things have to be a priority. From what I can see, including Scarf's own view into open source ecosystem trends, Haskell's growth looks modest at best compared with what is happening elsewhere. I cannot share all of the underlying numbers at this time, but directionally the story is not hard to see: a lot of developer ecosystems are accelerating in the AI era, and Haskell does not feel like one of them.
The opportunity cost of this stagnation has never been higher.
The answer is to make Haskell the best version of itself for the world we are actually entering. That means taking AI seriously as a first-class user of the ecosystem. It means caring about build times, onboarding, documentation, examples, tooling, agent workflows and marketing, more than we care about type system research. It means re-allocating community efforts and even abandoning current areas of work. It means finding ways for the Haskell Foundation to collect enough money to fund and coordinate more technical work.
I know that new language features like dependent types are interesting and have their use-cases. But industrial Haskell users have been complaining about compile times and ecosystem friction for years. In the AI era, those have grown far past mere annoyances, into fundamental misalignment with the language ecosystem.
At Scarf, we hit that wall. We still respect Haskell. We still run Haskell in production. But for new product development, we have moved toward Python because it lets us move faster with the latest AI tooling that has transformed the way and speed at which we ship software.
I wish things were different, but a move like this was the clear and logical way forward for our circumstances. I hope the Haskell community treats this moment with the urgency it deserves.
But also Elixir's paradigm is not the same as lets say some PHP slinging or JS. It encourages a stricter functional style, that already makes for better code than what many people produce in languages like JS and PHP, or Python.
The smell follows you but atleast we don’t have to smell it any more. Thank you.
Im not that familiar with elixir, but erlang is hands down the best dynamic language to build systems in. It feels like they made only right decisions. I can only assume that elixir has made improvements on that.
Meanwhile java and kotlin have the least useful types I've encountered in my career. Scala has some pretty powerful stuff, but it's like the c++ of powerful types. The ergonomics aren't great. Finally, typescript has a lot of impressive typing constructs but it really falls down on the runtime side (because javascript).
The real comparison to make would be erlang/elixir vs rust or ocaml.
It's interesting in particular because the argument of the article has at its core nothing to do with coding agents:
"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."
people said the exact same thing when they moved from Haskell to Python or to JavaScript before the latest tech. Tests, tests, tests, and faster development cycles is just the language of the Agile people who have been advocating for this for decades. The people who didn't buy it never did so because the claims about development speed were wrong, they didn't buy it because they had a fundamentally different outlook about what matters in a codebase over years. I'm interested to see how this will look in three years rather than three weeks. If you're so seduced by the idea that shipping next months feature faster is so important I honestly don't know why you ever chose Haskell in the first place.
Also typescript is a better overall language than golang. More expressive types. Golang wins in performance and simplicity and raw ugliness.
Lots of modern (...3+) python code uses type hints and a type checker. It can be as strict as you'd like it to be, which is exactly how I like it. It's what pulled me away from ruby.
Meanwhile, static languages are too often a giant pain in the ass, and in return for writing a lot of annoying code, you get in return guarantees that only really apply within your process's memory. And in a microservices world... you're actually realistically using the protobuf type system. Which generates just fine for python. And then "internally" you can use python's type checking where it helps, and if it doesn't help, then for that bit of the code, simply don't use it (and write "true" python).
I also find that a HUGE problem in the world is that programmers just. can't. help. themselves. They LOVE to over-define. LOVE IT. It's a siren's song!! Static type systems are a trap for the part of our brain that loves to architect. One of my favorite things about python is that it helps programmers _let go_. Not everything needs to be an interface. It's python. Everything is already an interface. Now just write the code without all the distracting 20 layers of indirection. And if we ever need one more, it's python - it's practically already there. Just make a new type, put @property on some methods, and you're good.
Obviously there are times I'd not use python. I could foresee myself writing Rust if I had to do code where correctness was of utmost importance (like, crypto, or embedded software for a medical device where someone's ventilator is hooked up to it, or similar). But if nobody's going to die (so... medical and cryptography...) then I'm using python almost no matter what I'm doing. And I'll use numpy or write a C module if I actually end up needing true CPU-bound performance for something.
It seems the job of a senior software engineer these days is to make fun of programming languages on HN pointing out their flaws, while simultaneously keeping an eye, waiting on agents doing "thinking".
i could probably do my job and get passing (or better) perf reviews using nothing but fundamental-mode and the compiler.
"solver failed" is in theory a better error. it fails faster and is unambiguous. maybe because it's weird it is scarier? idk
the main issue is managing PVP bounds is a little hard to keep correct. but cabal also lets you "allow-newer" for duct tape.