The interesting part here is how much this is a social issue, not a technical one.
C/C++ has a ton of build systems, many of which are much more powerful than Rust’s cargo, and Cargo doesn’t have any features that a C/C++ build system couldn’t copy (I wouldn’t be surprised if someone cloned Cargo already). But only Rust users enjoy the simplicity and consistency of having cargo build/run/test/doc work for basically every library, because everyone somehow agreed to use cargo and not a dozen different build systems and non-portable package managers and snowflake project layouts.
To clarify (I am involved with the project), while build2 aims to be for C/C++ what Cargo is for Rust, it’s by no means a carbon copy of it or copies any unique to Cargo features (at least that I am aware of). The biggest difference is probably the fact that build2 comes with a lot more powerful, general-purpose build system and which is not lumped together with the package manager. It’s also not meant as a C/C++-only toolchain and there is support for other languages, for example Bash and Rust (though Rust support is still pretty nascent).
I’m happy that it is. I am aware of a few cargo-alikes that copied very well known flaws of cargo because of uncritical treatment of the source material :).
I think this is coming if Rust were to be used for more complex projects. You can already see this in the arguably two most high-profile Rust projects: Firefox and Linux. Both of them, AFAIK, have to work around Cargo rather than “enjoying its simplicity and consistency”.
Cargo is an ok package manager (though with some serious limitations, like bool-only dependency configuration) but a really primitive build system with the two unfortunately lumped together.
It might also be that Rust hasn’t had to deal with enough specialised cases yet. I was looking the other day at cargo-raze and it’s clearly a lot of work to implement cargo’s intent while supporting a very different build strategy.
Oh, you can run into unsupported scenarios in the first 5 minutes of using it. Cargo is missing lots of things that would be considered absolutely basic in other build systems, e.g. you can’t run any custom commands after the executables are built. You can’t set rpath or make a proper solib. No way to install a man page. It took 59 versions before Cargo could even strip binaries!
And yet, there are nearly ninety thousand libraries and programs using Cargo.
A bit of a counter-example here is IDE support, specifically the bit where there’s a type-checker running inside an IDE which informs completion and automated refactors. IntelliJ more or less solved this problem for Java since before I even started programming. And then for a very long-time we have a weird split between Java/C# world which had everything, and everything else, where the state-of-the-art were Vim+ctags.
We are finally closing the gap here with LSP, but, darn, it took way too long. And all “modern” languages like Go, Rust, and Swift missed the boat actually, and are struggling to retro-fit IDE tooling.
Another counter-example is the section on package managers. Ruby adopted bundler and upstreamed it to stdlib, and the community adopted it universally. Bundling Ruby is very easy and straightforward today, and there are no competing standards. This happened when the language was somewhere around 20 years old.
Once you’ve worked with one of these newer languages, it can be quite daunting to try and learn an older one. Take Haskell for example which I recently spent some time with. There are two package managers (cabal and stack), a half dozen formatters that have wildly different takes, and even though the author praises hackage there’s a competitor in stackage. Oh, and use of nix is popular in the haskell community if the decisions weren’t complex enough for you. At least there’s only one main LSP implementation, but that speaks more to how LSP is newer. And then you get to the lack of a standard library, compiler extensions, and differing support for the multiple supported GHC versions.
When you want to learn a language, picking through all of this development environment complexity comes at a cost. Just getting started with a working environment took me much longer than I desired to spend.
This is something that’s incredibly difficult to counter once you’ve spent a lot of time with a language.
As a compiler maintainer, when a newbie comes into the chat, I sit down and take notes, because I know that it’s literally impossible for me to clear my mind and re-approach the perspective they have.
I’m not sure this distinction matters in practice and telling this to new users is unlikely to be clear.
Why do they both exist? Do they both still need to exist? If I’m uploading a package do I upload to both? Why do they display documentation differently? Can I or should I use both at once?
I’m not expecting answers to these questions, but that they even can be asked points to a problem with the bifurcation. So they don’t compete, but they kinda duplicate each other? And in doing so, don’t they cause fragmentation and confusion?
[Stackage is] A distribution of compatible Haskell packages from Hackage that build together
Stackage is a curated subset of Hackage. It exists because some people wanted a curated subset of Hackage containing only one specific version of each package that is known to be compatible with all the others.
Do they both still need to exist?
I’m not sure about need to, but if you want to guarantee you can never run into a problem with incompatible packages, or you want some modicum of guarantee that a package you are using is maintained, you might benefit from Stackage.
There are some slight rendering differences, but it’s pretty much the same. Historically there were some bigger differences because I think Stackage adopted a new format before Hackage. Still, what was the problem with that?
Can I or should I use both at once?
It doesn’t make sense to use Hackage at the same time as a subset of it. That’s still just Hackage!
So they don’t compete, but they kinda duplicate each other?
They don’t duplicate each other. Hackage is the “master collection” and Stackage is the “curated subset”.
And in doing so, don’t they cause fragmentation
Not really. The packages on Stackage are also on Hackage.
and confusion?
Clearly it causes some confusion. Whether that’s a price worth paying for the benefit Stackage provides is a different question. My hunch is “yes”.
The person you are replying to explained what the problem was and it’s also sort of what my article is about.
All of these little things might all make sense in the path dependent way they were arrived at, but they are just more things to learn for a new comer. And these things are hard to change retroactively, because the community understands them and who wants to change really.
And that is what can make older languages feel confusing and complicated to new comers and have them show up on the dread list.
I apologise if I gave the impression that I disagree with anything you’ve said here. That was not my intention. @adamcstephens asked some questions and said “I’m not expecting answers to these questions”. I thought I would defy his expectation and answer! Perhaps I misinterpreted. “I’m not expecting answers to these questions” might have meant “these questions are merely rhetorical to highlight the problem” rather than “I can’t imagine anyone will take the time to actually help me by answering”. Perhaps erring on the side of the latter came off as defensive. Again, that was not my intention. I just thought it would be helpful to answer!
They were rhetorical, though I’m not sure your clarifications convinced me personally that they both need to exist. I’m generally of the “improve the one way” mindset instead of reproducing the wheel slightly differently.
That’s fine when the decision is a single person’s to take. When it’s a group of people who disagree it’s much harder. Haskell has been around a lot longer than Rust, so it doesn’t surprise me that it has some fractures here and there. I would be interested to see if Rust has some means of avoiding fractures, or whether they arise inevitably given any degree of success over a long period.
Isn’t that the whole point of this post? That older languages don’t have the benefits of previous work to build on? All I was doing was reinforcing the authors post with an example.
All I was doing was reinforcing the authors post with an example.
This reply makes me think that I am communicating very poorly, so I will bow out and do some self-reflection about how I can communicate better in future.
You can’t upload to Stackage. If you author packages you always upload to Hackage, that’s where they go.
Hackage is also where to look for packages if you want npm-style latest of everything and everything there is. New users coming from those kind of ecosystems don’t need to care about Stackage at all.
This is definitely true. When I started with C++, there was basically no help beyond the compiler itself. Although C++ actually has a decent standard library. But, integrating packages for example, you had no help.
I think we need way more language-oriented tooling though. Like, for example, generating inverted call hierarchies (granted lots of languages do have that). Or being able to search along specific code paths for certain method calls with certain method parameters (this one I’ve never seen).
Basically, for code literally just being logic, we don’t have a lot of great tools for working with logic itself.
Or being able to search along specific code paths for certain method calls with certain method parameters (this one I’ve never seen).
This sounds like a cool idea. Do you mean in a way that defines a type and finding its implementation like, “show me things that look like (String, (String) -> Bool) -> String”?
My day job and most of my personal public code is in Java, and I couldn’t agree more. The saddest part is that a lot of people who work in Java don’t realize how bad some parts of the tooling are–I’ve had people try to tell me that Maven plus an IDE isn’t a massive PITA. I like IDEs, for the record, Intellij is so powerful, but its integration with Maven can be weird, and it makes several things more painful than they should be. I recommend any Java developer spend at least a little time working with npm or cargo to understand the problems with Maven.
I suspect that much of the progress that we’ve had is due to the isolation and naming of individual tools within language-specific toolboxes, and the realization that some tools are instantiations of patterns which could be built for nearly any language. For example, you mention “linting” and “fuzzing”; I think that the idea of “a linter” or “a fuzzer” is the actual quantum of progress.
Put it in perspective against the rest. Most dreaded langs are actually what runs the Internet, but see very little corporate-sponsored marketing, or usage in some popular niche fields such as ML and data science.
There’s a whole new tribe of programmers, coming out of bootcamps, who know of anything else. SO engagement is dominated by newcomers asking questions. I barely saw stars about cobol
Adding “How many languages are you proficient in?” (or some better phrased version) might be a good way to get to the bottom of this. You could drill into questions like do newbies like their first language and what languages do experienced programmers enjoy.
I do agree when I think about the people I know. As they get more experienced they start leaning away from JS towards TS.
I wonder if survey responders lumped TS/JS together in their head? I don’t mind working TS these days, but I ran across an older JS codebase at work recently and it’s a nightmare.
Java has has backing of many major corps, none of them oracle. Even Sun, the former owner, was small potatoes here. Every Enterprise product used Java for years and IBM and Google both put a lot of weight there for a long time
The interesting part here is how much this is a social issue, not a technical one.
C/C++ has a ton of build systems, many of which are much more powerful than Rust’s
cargo
, and Cargo doesn’t have any features that a C/C++ build system couldn’t copy (I wouldn’t be surprised if someone cloned Cargo already). But only Rust users enjoy the simplicity and consistency of havingcargo build/run/test/doc
work for basically every library, because everyone somehow agreed to usecargo
and not a dozen different build systems and non-portable package managers and snowflake project layouts.Build2: https://build2.org/
Outside of C/C++, there’s Alire for Ada: https://alire.ada.dev/
To clarify (I am involved with the project), while
build2
aims to be for C/C++ what Cargo is for Rust, it’s by no means a carbon copy of it or copies any unique to Cargo features (at least that I am aware of). The biggest difference is probably the fact thatbuild2
comes with a lot more powerful, general-purpose build system and which is not lumped together with the package manager. It’s also not meant as a C/C++-only toolchain and there is support for other languages, for example Bash and Rust (though Rust support is still pretty nascent).I’m happy that it is. I am aware of a few cargo-alikes that copied very well known flaws of cargo because of uncritical treatment of the source material :).
Can you enumerate on some of these flaws? I’m curious.
I think this is coming if Rust were to be used for more complex projects. You can already see this in the arguably two most high-profile Rust projects: Firefox and Linux. Both of them, AFAIK, have to work around Cargo rather than “enjoying its simplicity and consistency”.
Cargo is an ok package manager (though with some serious limitations, like bool-only dependency configuration) but a really primitive build system with the two unfortunately lumped together.
It might also be that Rust hasn’t had to deal with enough specialised cases yet. I was looking the other day at cargo-raze and it’s clearly a lot of work to implement cargo’s intent while supporting a very different build strategy.
Oh, you can run into unsupported scenarios in the first 5 minutes of using it. Cargo is missing lots of things that would be considered absolutely basic in other build systems, e.g. you can’t run any custom commands after the executables are built. You can’t set
rpath
or make a proper solib. No way to install a man page. It took 59 versions before Cargo could evenstrip
binaries!And yet, there are nearly ninety thousand libraries and programs using Cargo.
A bit of a counter-example here is IDE support, specifically the bit where there’s a type-checker running inside an IDE which informs completion and automated refactors. IntelliJ more or less solved this problem for Java since before I even started programming. And then for a very long-time we have a weird split between Java/C# world which had everything, and everything else, where the state-of-the-art were Vim+ctags.
We are finally closing the gap here with LSP, but, darn, it took way too long. And all “modern” languages like Go, Rust, and Swift missed the boat actually, and are struggling to retro-fit IDE tooling.
Another counter-example is the section on package managers. Ruby adopted bundler and upstreamed it to stdlib, and the community adopted it universally. Bundling Ruby is very easy and straightforward today, and there are no competing standards. This happened when the language was somewhere around 20 years old.
Once you’ve worked with one of these newer languages, it can be quite daunting to try and learn an older one. Take Haskell for example which I recently spent some time with. There are two package managers (cabal and stack), a half dozen formatters that have wildly different takes, and even though the author praises hackage there’s a competitor in stackage. Oh, and use of nix is popular in the haskell community if the decisions weren’t complex enough for you. At least there’s only one main LSP implementation, but that speaks more to how LSP is newer. And then you get to the lack of a standard library, compiler extensions, and differing support for the multiple supported GHC versions.
When you want to learn a language, picking through all of this development environment complexity comes at a cost. Just getting started with a working environment took me much longer than I desired to spend.
Totally agree! And people within those communities are often somewhat blind to those hurdles.
This is something that’s incredibly difficult to counter once you’ve spent a lot of time with a language.
As a compiler maintainer, when a newbie comes into the chat, I sit down and take notes, because I know that it’s literally impossible for me to clear my mind and re-approach the perspective they have.
Hackage and Stackage don’t compete, Stackage is a distribution of a subset of Hackage.
I’m not sure this distinction matters in practice and telling this to new users is unlikely to be clear.
Why do they both exist? Do they both still need to exist? If I’m uploading a package do I upload to both? Why do they display documentation differently? Can I or should I use both at once?
I’m not expecting answers to these questions, but that they even can be asked points to a problem with the bifurcation. So they don’t compete, but they kinda duplicate each other? And in doing so, don’t they cause fragmentation and confusion?
From www.stackage.org:
Stackage is a curated subset of Hackage. It exists because some people wanted a curated subset of Hackage containing only one specific version of each package that is known to be compatible with all the others.
I’m not sure about need to, but if you want to guarantee you can never run into a problem with incompatible packages, or you want some modicum of guarantee that a package you are using is maintained, you might benefit from Stackage.
Hmm, do they? Compare
There are some slight rendering differences, but it’s pretty much the same. Historically there were some bigger differences because I think Stackage adopted a new format before Hackage. Still, what was the problem with that?
It doesn’t make sense to use Hackage at the same time as a subset of it. That’s still just Hackage!
They don’t duplicate each other. Hackage is the “master collection” and Stackage is the “curated subset”.
Not really. The packages on Stackage are also on Hackage.
Clearly it causes some confusion. Whether that’s a price worth paying for the benefit Stackage provides is a different question. My hunch is “yes”.
The person you are replying to explained what the problem was and it’s also sort of what my article is about.
All of these little things might all make sense in the path dependent way they were arrived at, but they are just more things to learn for a new comer. And these things are hard to change retroactively, because the community understands them and who wants to change really.
And that is what can make older languages feel confusing and complicated to new comers and have them show up on the dread list.
I apologise if I gave the impression that I disagree with anything you’ve said here. That was not my intention. @adamcstephens asked some questions and said “I’m not expecting answers to these questions”. I thought I would defy his expectation and answer! Perhaps I misinterpreted. “I’m not expecting answers to these questions” might have meant “these questions are merely rhetorical to highlight the problem” rather than “I can’t imagine anyone will take the time to actually help me by answering”. Perhaps erring on the side of the latter came off as defensive. Again, that was not my intention. I just thought it would be helpful to answer!
They were rhetorical, though I’m not sure your clarifications convinced me personally that they both need to exist. I’m generally of the “improve the one way” mindset instead of reproducing the wheel slightly differently.
That’s fine when the decision is a single person’s to take. When it’s a group of people who disagree it’s much harder. Haskell has been around a lot longer than Rust, so it doesn’t surprise me that it has some fractures here and there. I would be interested to see if Rust has some means of avoiding fractures, or whether they arise inevitably given any degree of success over a long period.
Isn’t that the whole point of this post? That older languages don’t have the benefits of previous work to build on? All I was doing was reinforcing the authors post with an example.
This reply makes me think that I am communicating very poorly, so I will bow out and do some self-reflection about how I can communicate better in future.
Ah, that makes sense.
I interpreted them as rhetorical questions, but I can see how the other interpretation makes sense.
You can’t upload to Stackage. If you author packages you always upload to Hackage, that’s where they go.
Hackage is also where to look for packages if you want npm-style latest of everything and everything there is. New users coming from those kind of ecosystems don’t need to care about Stackage at all.
I think lisp remains a prominent exception to this rule, although it is no longer as nice (by comparison) as it (probably) used to be.
This is definitely true. When I started with C++, there was basically no help beyond the compiler itself. Although C++ actually has a decent standard library. But, integrating packages for example, you had no help.
I think we need way more language-oriented tooling though. Like, for example, generating inverted call hierarchies (granted lots of languages do have that). Or being able to search along specific code paths for certain method calls with certain method parameters (this one I’ve never seen).
Basically, for code literally just being logic, we don’t have a lot of great tools for working with logic itself.
This sounds like a cool idea. Do you mean in a way that defines a type and finding its implementation like, “show me things that look like
(String, (String) -> Bool) -> String
”?Check out Hoogle:
https://hoogle.haskell.org/
It’s a tool in the Haskell community where you can search for functions that match type signatures.
Another interesting tool around types is typed holes: basically leave a hole in your program and get suggestions of functions that can fill it in.
That’s very cool! I’d like to see that adopted in tooling to make bigger codebases easier to understand.
My day job and most of my personal public code is in Java, and I couldn’t agree more. The saddest part is that a lot of people who work in Java don’t realize how bad some parts of the tooling are–I’ve had people try to tell me that Maven plus an IDE isn’t a massive PITA. I like IDEs, for the record, Intellij is so powerful, but its integration with Maven can be weird, and it makes several things more painful than they should be. I recommend any Java developer spend at least a little time working with npm or cargo to understand the problems with Maven.
I suspect that much of the progress that we’ve had is due to the isolation and naming of individual tools within language-specific toolboxes, and the realization that some tools are instantiations of patterns which could be built for nearly any language. For example, you mention “linting” and “fuzzing”; I think that the idea of “a linter” or “a fuzzer” is the actual quantum of progress.
Thanks for reading.
Once it’s named it’s real? It’s an interesting thought.
How is the world did ruby end up in a “dreaded” list?? I presume the author doesn’t like it.
Put it in perspective against the rest. Most dreaded langs are actually what runs the Internet, but see very little corporate-sponsored marketing, or usage in some popular niche fields such as ML and data science.
Not entirely fair: JavaScript was in the loved list.
There’s a whole new tribe of programmers, coming out of bootcamps, who know of anything else. SO engagement is dominated by newcomers asking questions. I barely saw stars about cobol
Adding “How many languages are you proficient in?” (or some better phrased version) might be a good way to get to the bottom of this. You could drill into questions like do newbies like their first language and what languages do experienced programmers enjoy.
I do agree when I think about the people I know. As they get more experienced they start leaning away from JS towards TS.
I wonder if survey responders lumped TS/JS together in their head? I don’t mind working TS these days, but I ran across an older JS codebase at work recently and it’s a nightmare.
Good observation. All of them but one (Java) have not had mega-corp backing, while almost all of the loved languages have.
And that megacorp (if you mean oracle) hurts more than helps, in a lot of ways.
Java has has backing of many major corps, none of them oracle. Even Sun, the former owner, was small potatoes here. Every Enterprise product used Java for years and IBM and Google both put a lot of weight there for a long time
Usually I expect “dreaded” to be based on issue with the language or ecosystem, such as PHP or Java – or fear, such as C or C++.
“It’s kinda popular even though it has no marketing.” How did that even happen if something is dreaded?
Anyway, I’m not saying it’s not true, just that it surprised me since I’ve not encountered the people with the dread in this case.