You can't just blindly pretend any future versions of all your dependencies will work without updating your code. APIs change.
If you have a risk of arbitrary changes in APIs happening in any minor update, your infrastructure and dependency management are fundamentally flawed and ongoing development will always be difficult. There is nothing unique to Haskell about this, it's just software development 101, separating interface from implementation and all that jazz.
There does seem to be a surprising... I'm not sure how to describe it, maybe a lack of respect?... for this principle in parts of the Haskell community, given the same community's obvious general preference for correctness and being sure everything fits together in a controlled way.
Of course sometimes you want to make major changes to an API and maybe they break backward compatibility, but usually that is a Big Deal in software development, it doesn't normally just get done in some quick point release along with a couple of bug fixes and a security patch.
I had constant problems with pip. Because it will blindly install the latest 'foo' dependency even though the API changed and now my app is broken.
Not that I'm doubting you, but I do find that experience surprising. I work with Python all the time, on different kinds of projects but typically always using pip for package management, and I can't immediately think of a single time that's happened to me. Of course, you can also tell pip to install only within a specific version range if you ever need to.
Perhaps my initial choice was words was poor. Allow me to clarify: I don't think it matters very much what level of version numbering indicates a breaking change, because the main problem is how often those breaking changes happen. I've used libraries that have had a total of zero breaking API changes over a period of years in professional production code written in many other languages. In Haskell, I seem to have run into one ever-changing package or another via Cabal every time I've tried to do something moderately serious in the language. Given the emphasis on relatively small, general and highly reusable parts in Haskell code, I find this surprising, and unless I've been remarkably unlucky in the projects/packages I've tried, it must be a significant drag on development efficiency.
There are some parts of the ecosystem that are incredibly stable (base, containers, parsec) and some aren't (lens). Of course, a lot of new hotness winds up being somewhat experimental, and so we're stuck with bad decisions made early on or wind up faced with the choice of when to cause breakage - in which case "earlier is better" might not be wrong... there have been some efforts to isolate more stable subsets, where that's wanted.
Fair point, though I'd suggest that it's not just general/utilitarian/language support areas like lenses where rapid evolution happens, but also quite a few of the practical, real world things like dealing with comms protocols or user interfaces. This is true to some extent for every mainstream language I know as well, but I think perhaps because Haskell's ecosystem isn't as large and there aren't as many (or sometimes any) ready-made alternatives, you feel the effect more when you run into it. For better or worse, I think this rapid evolution does lend some weight to claims that Haskell isn't ready for use on most mainstream projects yet and to the idea that it's more of an academic's or theoretician's language, even if a few such people happen to work in industrial software development rather than in research now.
I suppose it's a similar situation to what we see in web development. There are always people who want to push the envelope with the latest HTML7/CSS5/SomethingScript technologies, and it's helpful for advancing the state of the art for some people to do that. At the same time, if you're trying to build real web sites for paying clients, what you really need is solid foundations that are as standardised and portable as possible.
"general/utilitarian/language support areas like lenses where rapid evolution happens"
Oh, no question. It just was an example I had off the top of my head of somewhere there has been a lot of instability recently.
"For better or worse, I think this rapid evolution does lend some weight to claims that Haskell isn't ready for use on most mainstream projects yet and to the idea that it's more of an academic's or theoretician's language, even if a few such people happen to work in industrial software development rather than in research now."
To an extent, but I'm not sure I accept the dichotomy. The great thing about Haskell over HTML7/CSS5/SomethingScript is that the people doing experimental stuff are doing it in the same language you're working in, and it will bleed directly back into "things that are stable enough to use" as they get stable. The thing that Haskell-in-industry has over academia is that those experimental innovations scratch itches found by people working in industry. The presence of Haskell in academia means those industrial innovators have more things to reach for. Where it works, it works very well. Because the Haskell community is small, we don't have the large mass of stable libraries that something like Python has, but how much that matters depends both on how stable you need things and on what you need in the first place.
"At the same time, if you're trying to build real web sites for paying clients, what you really need is solid foundations that are as standardised and portable as possible."
Absolutely. If you need things stable, stick to stable packages. There are efforts (stackage, Haskell Platform) toward making this easy. If you need things stable, and you have needs that stable libraries don't meet, and it doesn't make sense for you to get involved in maintaining less stable libraries, then Haskell is probably not a good fit for your project.
That is the most elaborate strawman I have seen in a while. You are now literally saying "haskell is dumb because they do what I think they should do. They should do what they already do instead."
>If you have a risk of arbitrary changes in APIs happening in any minor update
You don't. API changes require changing the major version. Read the PVP.
>There is nothing unique to Haskell about this
Precisely my point.
>Of course, you can also tell pip to install only within a specific version range if you ever need to.
That is the most elaborate strawman I have seen in a while. You are now literally saying "haskell is dumb because they do what I think they should do. They should do what they already do instead."
No, I'm not literally saying any such thing.
There are two points here. One is whether or not your version numbering scheme and package/dependency management tools systematically track breaking changes. The other is how often breaking changes happen.
As far as I'm aware, Haskell doesn't generally have a big problem with the first point. As you say, PVP takes care of that as long as people follow it.
But breaking changes, even if properly acknowledged, seem to happen with amazing (not in a good way) frequency in the Haskell ecosystem. No doubt there's some variation between packages, but I'm another example of someone whose early experiments with the language proved very frustrating because of the constant maintenance headaches with Cabal etc.
If your complaint is "some haskell libraries move too fast for my liking" then you should say that in the first place. If you frame your complaint as "cabal sux and everything else solves this wtf is wrong with you guys" then you have to reasonably expect that is what people will respond to.
My point is that the Haskell community seems (or at least parts of it seem) more tolerant of frequent API changes, including backwards-incompatible ones, than we would normally see in mainstream programming languages. I think this is a drag on development efficiency.
You wrote yourself, "having working code spontaneously break is very bad". You can protect against dependencies breaking by adding upper limits on version numbers for your dependencies, but that doesn't fix the problem, it just conceals it, and it has a cost: every time someone makes a breaking change in a library API, everyone using that library needs to check through what actually changed to see whether it affects their particular situation and then update their dependency management again.
In my original post, I never even mentioned version numbering schemes, and in two different posts now I've reiterated that this isn't what I'm concerned about.
I wasn't having a dig at Cabal for how it supports controlled dependencies either, nor suggesting that other package managers do that job better. That would be like blaming the UI for every bug in software because the UI is where the consequences of bugs are visible to the user. Cabal isn't the problem, the implied need to use certain features of Cabal routinely because otherwise things will break is the problem.
I wasn't even objecting to Haskell libraries developing "too fast for my liking". I think the innovations coming out of the Haskell community are some of the most interesting and promising ideas in the programming world right now, and in general I'm a big fan. I'm just saying that, other things being equal, breaking changes in APIs are undesirable, and that the Haskell ecosystem seems a lot more tolerant of such changes than most, whether because of that desire to move forward quickly or otherwise. That's great in a research language, but I don't think it is helpful for mainstream industrial development, because it does have practical consequences particularly in terms of maintenance overheads.
>You can protect against dependencies breaking by adding upper limits
As every sane system does. So again, why are you acting like this is a haskell thing?
>but that doesn't fix the problem
Yes it does.
>every time someone makes a breaking change in a library API, everyone using that library needs to check through what actually changed to see whether it affects their particular situation
That is the case no matter what. If I write an SSL application in C, I need to pay attention if a new version of openssl comes out. Once again, this isn't even remotely a haskell issue.
>but I don't think it is helpful for mainstream industrial development
You are not required to update to every new version that is released. If you do not want to track the bleeding edge then don't. That's why we have upper bounds.
If you have a risk of arbitrary changes in APIs happening in any minor update, your infrastructure and dependency management are fundamentally flawed and ongoing development will always be difficult. There is nothing unique to Haskell about this, it's just software development 101, separating interface from implementation and all that jazz.
There does seem to be a surprising... I'm not sure how to describe it, maybe a lack of respect?... for this principle in parts of the Haskell community, given the same community's obvious general preference for correctness and being sure everything fits together in a controlled way.
Of course sometimes you want to make major changes to an API and maybe they break backward compatibility, but usually that is a Big Deal in software development, it doesn't normally just get done in some quick point release along with a couple of bug fixes and a security patch.
I had constant problems with pip. Because it will blindly install the latest 'foo' dependency even though the API changed and now my app is broken.
Not that I'm doubting you, but I do find that experience surprising. I work with Python all the time, on different kinds of projects but typically always using pip for package management, and I can't immediately think of a single time that's happened to me. Of course, you can also tell pip to install only within a specific version range if you ever need to.