Interesting! Excepting typescript, the “safer” languages also happen to be the ones I gravitate towards on a daily basis and actually enjoy writing programs in, while the others...
It’d be interesting to see whether programmers’ preferences uphold the division posited by the study, or whether they are widely variable—eg is it likely that if you prefer ruby you’ll also prefer typescript over JavaScript, if you prefer Haskell you’d choose clojure over c++ etc.
I think you're confusing the conclusions from the original paper with the conclusions from this paper. This paper is a reproduction of the original study, and for the most part, it is not able to reproduce the findings.
The conclusion makes it clear that this work has no aggressive intent:
Unfortunately, our work has identified numerous problems in the FSE study that invalidated its key result. Our intent is not to blame, performing statistical analysis of programming languages
based on large-scale code repositories is hard.
[...]
Acknowledgments. We thank Baishakhi Ray and Vladimir Filkov for sharing the data and code of their FSE paper. Had they not preserved the original files and part of their code, reproduction
would have been more challenging
(Edited-- I was reading the original paper, which showed good results for TypeScript; the new paper linked above refutes that result. My mistake. Thanks to the posters who corrected me!)
The winners in this paper are Clojure, Haskell, Scala.
I look forward to seeing Rust added. The authors go into substantial detail about what they consider errors, and in my personal experience Rust solves many of them. See e.g. "Some defect type like memory
error, concurrency errors also depend on language primitives."
> ...only four languages are found to have a statistically significant association with defects, and even for those the effect size is exceedingly small.
I believe you are confusing the conclusions from the original paper with the claims from this paper. I think this is the case because this paper removes TypeScript from their dataset entirely:
"4.1.2 Removal of TypeScript. In the original dataset, the first commit for TypeScript was recorded
on 2003-03-21, several years before the language was created. Upon inspection, we found that
the file extension .ts is used for XML files containing human language translations. Out of 41
projects labeled as TypeScript, only 16 contained TypeScript. This reduced the number of commits from 10,063 to an even smaller 3,782. Unfortunately, the three largest remaining projects
(typescript-node-definitions, DefinitelyTyped, and the deprecated tsd) contained only declarations and no code. They accounted for 34.6% of the remaining TypeScript commits. Given the small
size of the remaining corpus, we removed it from consideration as it is not clear that we have
sufficient data to draw useful conclusions."
This is great (to see something I know about on HN). As an undergrad at UMass (where Emery Berger teaches), I remember the exact paper they are talking about, and how it was presented at UMass (this was part of a lunch and learn with the faculty, grad, and undergrad students and the author of the original paper).
I remember Emery being quite confused at the methodology in the paper, and he was very confused with one aspect of it, which was how they came to conclude that C was more bug prone (something about void * being able to cast to everything? It was a while ago...)
Glad to see he wrote a rebuttal, a little awkward watching a professor debate with the paper's author :)
Of note is that these are all associations. It's possible the associations are all due to selection effects (or even that the "better" language are actually worse but their effects are reversed by selecting for programmers who are better).
In the early days of Python, some employers used it as a way to filter for candidates who were ahead of the curve. I believe Paul Graham mentioned Lisp being good for attracting better programmers, although I can't find the reference anymore [1]. If there's any value in this kind of filter, the effects will show up in the programmers' output.
Indeed, and in addition to selection bias towards better programmers, there is another selection bias implicit in this.
A shop that makes the decision to write their stack in Haskell do it with an intention to focus on correctness. I reckon that such companies would consequently invest in other practices like more tests, higher code coverage and more intensive code reviews resulting in code with fewer errors.
This is in stark contrast to a startup that may have hacked together a POC in Python, and once it worked, with a little bit more spit and polish put it into production.
The paper goes further though. It states: Not only is it not possible to establish a causal link between programming language and code quality based on data at hand, but even their correlation proves questionable.
I find that a surprising result! This might also call into question the theory that some languages attract better developers.
According to Coverity, the "defect density" of the Linux kernel is around 0.5 errors per 1000 lines of code, while the average of the analyzed open source projects is around 0.7. Best among the analyzed projects is Python (the language/stdlib I guess) with an error rate of 0.08.
I don’t know about relative quality but Syzkaller finds a new kernel bug every minute or two and Coverity says there are thousands of unfixed defects that their static analysis can detect.
> In the early days of Python, some employers used it as a way to filter for candidates who were ahead of the curve. I believe Paul Graham mentioned Lisp being good for attracting better programmers
Possibly "The Python Paradox" [1] and/or "Beating the Averages" [2]. (The first one, from 2004, is a bit of an odd read nowadays, since it no longer applies to Python.)
- This study tries to enhance the original work by better metrics (e.g. confusion with C/C++), using better statistics (e.g. uncertainty).
- Automatically evaluating the quality of a code is hard and time-consuming. They had to use peer review of labellisation.
- Most of the old claims are not confirmed.
- Only 2 languages in this study had both a significant impact (impact coeff) and enough fiability (p-value): Clojure and Haskell. But the impact is still small, and there may be other influencing factors.
- They propose several ways to further enhance their work (e.g. taking regression tests into account).
Selection bias? Consider the type of person likely to be attracted to languages like Haskell or Clojure.
(Note, didn't read the original study so I don't know the selection criteria. Were code samples in different languages from the same programmers compared, or were there different sets of programmers per language? My comment really only applies to the latter case.)
I can think of selection bias effects both in-favor of more defects and against it.
On one hand, Haskell or Clojure probably attract more academic types who have a reputation for (consistent with my experience) on-average worse-quality code.
On other hand, the barrier-to-entry for these languages is higher so they tend to be programmed by more experienced folks. I assume that people pick functional languages in part because they believe the functional paradigm leads to higher-quality code, so the sample probably cares more about code quality to begin with.
> - Only 2 languages in this study had both a significant impact (impact coeff) and enough fiability (p-value): Clojure and Haskell. But the impact is still small, and there may be other influencing factors.
They also found a significant positive association between C++ and bug.
They found a statistically significant correlation: not a causal relationship and the correlation was small. Using "significant" without those qualifications presents a misleading picture of the results.
One of the simplest but more important conclusions that affects me all the time... it’s easy to search for things, but hard to know whether you’ve got all the answers you want and hard to know if all the answers you got are answers you want.
6.3 Grep considered harmful
Simple analysis techniques may be too blunt to provide useful answers. This problem was compounded by the fact that the search for keywords did not look for words and instead captured substrings wholly unrelated to software defects. When the accuracy of classification is as low as 36%, it becomes difficult to argue that results with small effect sizes are meaningful as they may be indistinguishable from noise. If such classification techniques are to be employed, then a careful post hoc validation by hand should be conducted by domain experts.
One of the simplest but more important conclusions that affects me all the time... it’s easy to search for things, but hard to know whether you’ve got all the answers you want and hard to know if all the answers you got are answers you want.
Smalltalk was wonderful in this regard. If you wanted to search for how something was used, you just right-click search for "senders." If you wanted to find implementors, the same.
This big difference occurred with chains of senders. In other languages, where there's 2 or 3 ways to get to something or call something, you have this O(2^n) or O(2.5^n) blowup in the work you have to do to properly follow chains of senders. With Smalltalk, it's just O(n).
On top of that, there were tools that could let you compose really sophisticated SQL like queries of the code base, dynamically, then pop that up in a browser.
Apple didn't invent Objective-C, it just-so-happened to be the language of choice at Next, which carried on into OSX and iOS. The fact that Swift is now Apple's language of choice doesn't make analysis of Objective-C "sort of pointless", any more than e.g. Facebook creating Hack would make anything involving PHP "sort of pointless".
I disagree. If anything, they should have tested Obj-C and Swift. I would also have liked to see Scheme, Common Lisp, or something else lisp-y besides Clojure. Kotlin would have been interesting. R or Mathematica would have been fun, too.
I guess it just comes down to needing a sufficiently large corpus of code and commits and having to eventually publish.
A common thread I'm seeing in the discussion here is confusing the claims from the original paper with conclusions made by this paper. This is a replication study, and it starts by stating what the original paper found. What the original paper found is not what this paper finds. For the most part, this is a replication failure, for a myriad of reasons, including several kinds of misclassification.
From this paper:
The reanalysis failed to validate most of the claims of [18]. As Table 6(d-f) shows, the multiple steps
of data cleaning and improved statistical modeling have invalidated the significance of 7 out of 11
languages. Even when the associations are statistically significant, their practical significance is
small.
And if you do, chances are good it'll end up on GitHub.
5.3 and 5.4 really nail it, IMO.
And you can't even use bug fixes as a metric, because there's a difference between semantic bugs which will be significantly language-influenced, architectural bugs which are partly language-influenced, and user-expectation/experience bugs, which are broad-brush logical errors or misunderstandings.
(There are probably other categories, but those are the obvious ones I can think of right now.)
The real takeaway is there is as yet no objective metric for software quality.
The best a working dev shop can do is implement a small but non-trivial sample project with known-good logic in a handful of candidate languages, and see what kind of trade-offs fall out.
I'll agree with you for sure no objective metric for quality (that is broad enough to capture a satisfying amount of what we mean by quality).
I do think user experience/expectation bugs are very language dependent though. First you have the quality of the String and Datetime libraries. Ruby has all kinds of high quality string functions that are a source of pain and bugs in C.
Say your project wants to display the different between two datetimes as "5 minutes ago" or "last month" (in several languages). Saying "1.27 days ago" is correct to an extent but also not pretty. There exist high quality libraries for this, but not in every language, and a lot of devs would stumble on this feature.
The other is UI creation, I would say it is easier and faster to create a really nice UI with HTML/CSS/JS than with native Android. Maybe I'm wrong on this example but I bet there is a pair of UI frameworks where this is true.
I consider those to be bugs in the spec, not the code. I once worked at a place that simply swept those under the rug - if it worked as documented, it didn't matter how many users couldn't get it to work. The bug report was closed as "not a bug"; you can imagine how frustrating that was.
Yes, definitely. This is mostly a non-replication of the original study. I was a little disappointed that they didn't look at defects per line of code, even though that's already a fairly well-studied metric.
I think the lesson here is that you can write good or bad code in any language, but choose one that's fit for purpose. Using proper abstractions (including those builtin to languages) probably does more to reduce the incidence of bugs than anything you can do other than writing automated tests.
Emphasis on "Formal code review" which is practiced in far fewer shops than "code review".
For those who don't happen to know the difference, formal code review basically uses a check list of common best practices and possible defects to look for versus doing each code review ad-hoc.
I thrive on checklists and hate the ad-hoc way I do code reviews on my team. This sounds great, I'm going to go look for some basic formal checklists. I need language agnostic versions and/or versions for javascript, php, and python, if anyone has suggestions.
I’ve never found a book on software I agreed 100% with. Even my favorites have some bits I think are dead wrong. It doesn’t mean the other parts aren’t valuable.
It means the book has not been updated, at least in that part. And the first edition of the book was written back when computing power was seven orders of magnitude more expensive (or more). Is advice about testing from then really going to be valid now?
Reanalysis showed positive association between defects and C++, negative association for Clojure, Haskell and Ruby.
The original analysis found positive association for C++, Objective-C, C, PHP, Python, JavaScript. Negative association for TypeScript, Clojure, Scala, Haskell, Ruby.
Casual observation: adding a framework to any language seems to improve the overall code quality. It adds and teaches structure, patterns and good practices that developers usually follow.
I've seen terrible codebases written in vanilla PHP, JavaScript, Python (probably the worst ones). But I've seen very good looking, easy to understand, easy to maintain codebases written in Symfony, React and Django.
(React is an interesting case because it's not actually a framework but a view library, which doesn't force you to follow any structure to your project. But its declarative, component-based paradigm seem to help developers structuring their projects and writing simple, reusable and composable components in a good way).
I agree. Our framework, libraries, and/or interfaces can and should make a bigger difference than programming language.
If you have to use the "weird parts" of a language to get typical work done, you are doing something wrong. And if you are not using the weird parts, then programming languages look and do pretty much the same thing.
Braggings such as, "look! My language can do double recursive lambda backflips while blindfolded and chewing gum!" are mostly just 1950's car racing done in cubicles. We buy cars to get to work and shops as cheaply and conveniently as possible, not beat Fonzy.
I think it really depends on how you use the “weird parts”. Some of those let you write code much more concisely and effectively. Used in the wrong context, it’s a unnecessary distraction. It also depends on if you want to write “typical code” or code that the competition can’t match.
See Paul Graham’s essay on the Blub Paradox [0], which discusses why some languages seem to have “weird parts” from the perspective of someone who knows a less-powerful language.
You make it hard to hire if you limit the field to those who know the esoteric techniques. Programming itself is mostly a dead-end career; you either move into management or quasi-management, or face ageism on average. There is thus not a lot of incentive to "perfect the art".
In my experience productivity is strongly correlated with the quality of frameworks and libraries that are available to a language. Java as a language might be fine but batshit insane frameworks like JSF really drag your productivity down. There are also solid libraries available but they are often too complicated and hard to use. Languages built on top of the JVM often have very very thin wrappers that increase the usability hundredfold.
Unfortunately, it's the original paper that will keep getting quoted at me forever.
My favorite line from this paper is: "Correlation is not causality, but it is tempting to confuse them." I think most people believe "correlation is not causality, but most of the time it is", when in reality it is, "correlation is not causality, and almost never is." There was a great analysis of this in a book or paper I read years ago that I haven't been able to find, but the tldr is that if you have a set of events, if causality were truly common, the events would for a seized up network of causality.
I’ve read a lot of code as a consultant. The best codebase I’ve read had almost no comments and was written in erlang. Besides that every codebase I’ve read in Golang were super clear and of excellent quality for the exception of one that was written by java developers.
I can say I hated reading C because of maccros and different build systems. I hated C++ codebases because people abused generics. And I hated Java the most because of the verbosity and the directory structure and all the layers of abstractions and all the factories and all the singletons and all the...
That is always a risk if a team decides to pick up a new language but does not make the effort to learn the language properly. At work we are going through a similar Java - Go transition, so I know :(
Looking through the Python standard library or Go standard library should be a clue not to use Java idioms, but yes I realize those habits are hard to break. I have seen Java-in-Python and it is indeed painful.
The problem with reading framework and library code is that it's very coupled to what it is, so while it's interesting and valuable to read it's not really the type of code you'd see in a business app or whatever.
Yeah I've tried this several times and the code written for the std library is so different from LoB code(because the domains are so different) that you can only learn a small % of possible idioms from them.
> because of the verbosity and the directory structure and all the layers of abstractions and all the factories and all the singletons and all the
Fair, but a lot of those abstractions make life more difficult for new programmers (Why do I have to look through 12 classes to find out what this button does?), but make life much easier when you know the code base and have to maintain and extend it.
Or, legit question - is Java more prone to these types of issues due to its design?
> is Java more prone to these types of issues due to its design?
Yes. Except on the actively powerless languages (mostly C and Go), people write code on other languages with the same flexibility that all that indirection creates on Java, but they use much simpler structures.
> .. the layers of abstractions and all the factories and all the singletons and all the...
You can have that in PHP, too, when the project builds on Symfony, that is to say the style is not only dictated by the language but also on the framework used.
The problem is that "code quality" isn't just bugs per line of code. Maintainability, extensibility, readability, expressivity all factor into it.
Suppose I have to write 100,000 lines in language B to write something doable in 10,000 lines of A. Who cares if the defect rate is twice as high per line of A: I still have five times fewer defects due to ten times fewer LOC's.
Another thing to consider is the nature of defects. A defect that allows a remote execution exploit is not the same as an incorrect result being ignored and propagating to later calculations, is not the same as terminating with a diagnostic.
Very much agree. This type of analysis is hard to quantify but anecdotally I don't know many people who have written Go, Rust or Typescript that would prefer python, ruby, java, javascript or c++ for their daily work after using them.
If the defect rate is the same across languages then you're not measuring the defect rate of the programming language. You're measuring the defect rate of the developers!
Seems like they're just doing associations, and not controlling for a lot of factors. For example, you can come up with some narratives to explain a lot of these findings:
* Python, JS, PHP, Java, C++ are all very common first languages; I'd imagine the average experience level for these is dragged down a bit compared to others like Golang, Haskell, or Scala. One of the recent Stack Overflow Developer surveys found Golang use to be strongly correlated with age, and since I'm assuming bug count would negatively correlate with age you'd see a confounding factor here.
* Ruby's community has an obsessive culture towards unit testing, that could impact bug levels.
* The trade-offs that make C and C++ attractive such as memory performance are double-edged swords and will naturally correlate with more bugs. For example, I work a fair bit in embedded systems which use MISRA C out of necessity; I've also worked in large scale data processing which chooses C++ for its memory mapping performance over Java or Go. If "number of defects" is your primary measure then you're ignoring some of the reasons languages are chosen. Sometimes a language that minimizes bugs is not a viable option.
* I'd guess there is a skill correlation here: an engineer who is willing to seek out a specific less-used language and learn to use it effectively is probably more likely (not guaranteed) to do a better job than one who is just going with the default choice.
It'd be very interesting to see a regression done that accounts for these factors.
That would be interesting. I also have a feeling it would be incredibly difficult to accurately control for social differences in language communities.
Yeah you'd have to take them one-by-one and see if there is some proxy if you can't measure the behaviour directly. For example, with testing you could use code-coverage or even a binary variable for the existence of tests - not perfect, but would give better results than no control at all.
Definitely. Heck, in .NET's early days, there was a distinct difference in quality of the software and of the team using VB.net vs C#, when they were 99% the same language (they had some features unique to each, but they were very few). But C# was used a lot in new projects or by people familiar with Java while VB.net was used in VB6 migrations or teams coming from VB6. That had a drastic effect on the end result, but the language had very little to do with it.
Always remember to turn on warnings in PHP. I remember the joys of tracking down a mistyped variable name that PHP just instantiated and gave a null value to, which was then implicitly converted to empty string when the variable was used.
Last time I worked with those languages was in college 10 years ago so I didn't know portion of shooting myself in the foot was my fault versus the language.
I agree that JS is not substantially "worse" than some other languages.
Despite these three languages giving far too much freedom to the programmers (which some might even like), high-quality code can be written in all three of them, as long as intelligent and strict coding guidelines are thoroughly followed.
I always think of languages as a solution space, and some points in the space possessing bugs while others don't. A perfect language(impossible) would make it so you could write any correct version of a program in the language but not any incorrect version. And language constraints like static typing have the disadvantage that you're preventing a bunch of correct possible solutions while closing off incorrect solutions. Ideally closing off many more incorrect solutions than correct ones increasing your chance of landing in a correction solution.
And of course lots of out of band(non-language) processes and tools that influence this like unit testing/code reviews/strict coding guidelines. But it's always nicer when it's prevented at the language level as opposed to out of band.
Great linting tools available though. Can't say the same for many systems languages. And the static analysis tools for those tend to be quite expensive, bulky and slow.
Ruby's community has an obsessive culture towards unit testing, that could impact bug levels.
Like Smalltalk, they're forced to do this to catch the errors that would've been caught by type annotation. So then, could the argument be made that less stringent type annotation hurts code quality by removing effort from unit testing?
Figuratively speaking. None of the languages they test enforce any unit testing. What I'm suggesting is that since the Ruby community tends to be more obsessive about testing, that might lead to an improvement in code quality when comparing against other similar languages like PHP or JS which are less obsessive about testing. It's something you might have to control for to see the impact.
Type systems are a completely different factor; you'd have to control for that variable too to determine the impact of it. My experience with both systems makes me predict that static typing would improve code quality, but if you want to actually be scientific you'd want to add that factor to the statistical analysis to see if the data support that hypothesis. Anecdotes like personal experience don't count.
Figuratively speaking. None of the languages they test enforce any unit testing.
The trivial type-mistake "Unhandled Exceptions" in Smalltalk would leak out more often than was comfortable, if the project didn't have a good means of testing to catch those. I suspect that has something to do with the Ruby community being more obsessive about testing.
Right. This, and many others, would result in an "Unhandled Exception" notifier dialog in many versions of Smalltalk. I used to work for the company acting as the vendor of 2 (3?) commercial Smalltalks, also doing consulting work for others.
No, the behavioral test [1] one writes cannot be replaced by type checks nor does a type system reduce the need to write tests if you're doing testing correctly.
Python is a language fundamentally similar to Ruby, that has no static type checking, that's used in similar application domains, etc.... It does not have as strong a culture of unit testing as Ruby, and falls above the line (by a statistically insignificant amount) in figure 5 while Ruby is below (by a statistically significant amount).
It does not appear that the paper took automated testing into account at all. Whether greater use of automated testing in Ruby is responsible for the lower defect rate observed here relative to Python would definitely be an interesting topic for another paper.
Clojure is also dynamically typed by default and below the line. It does not have Ruby's strong unit testing culture, but it does have a design that encourages functional programming, which proponents argue reduces sources of error. It also has a culture of REPL-driven development that arguably fills some of the role of automated testing.
> Like Smalltalk, they're forced to do this to catch the errors that would've been caught by type annotation.
Very few of the unit tests I've written for Ruby/Python catch errors that would be caught by typical type system use in C/Java/etc. (Haskell, maybe, but...) The main thing I miss in dynamic languages vs. static is the more powerful automatic testing possible when test specs can leverage type information (e.g., QuickCheck/ScalaCheck), not an absence of need for testing.
I've only ever done property based testing in Scala, but I thought it was pretty popular in dynamic languages like clojure and erlang. What would prevent it from working in Ruby/Python?
Without type information already in the code (for parameters, etc.) there would be a lot more overhead in setting it up; it's possible, but higher marginal friction in the ideal case.
Plus, AFAIK, no one has written the libraries, making it even higher marginal friction in practice even more than than is true in the ideal case.
Type information generally isn’t used when doing property testing in Elixir, and Python has a very mature library too (hypothesis). If there’s a difference in popularity, it could just be culture. The Erlang/Elixir community is rather fanatical about reliability.
Hypothesis uses the same type annotations as Python's optional typechecker as a tool to select appropriate input data generators without additional test-specific description. That's a fairly common feature of property-based testing tools; I don't know for sure, but I wouldn't be surprised to find that hypothesis and mypy tend to be used in the same segments of the Python community.
We use property testing with Elixir (erlang VM) -- and it would translate perfectly well to Ruby or Python. I also think it's a community difference, not a technical one.
Yeah it's easy to see writing in dynamic languages with optional typing and static analysis tools (e.g. JS with TS/Flow, PHP with phpstan or psalm), the type analysis finds all kinds of different and subtle problems that unit tests probably wouldn't catch. Large integration tests often would, but are even harder to write exhaustive cases for.
Types just make everything easier to do right the first time.
I think you're making the same confusion a lot of other commenters have made, specifically responding to the original study as opposed to this failed replication of that study: https://news.ycombinator.com/item?id=20105150
It doesn't matter. They are looking at effects relative to the total effect of language choice, which they report as less than 1%. Instead of looking at these secondary effects, the main practical result is that language choice hardly matters.
The language is what makes me apply to work at your company with 15 years experience but paid 20% less than I would be if I had to do OO. That’s the driver.
Is the code quality better? Well maybe. Probably. But dollar for dollar you’ll do better with a good language because you’ll get much better people for your dollar.
Overall language effects do not appear to be a dominant factor in software quality. Manual memory management is error prone. Functional languages appear to produce better results than OO/imperaive ones. Static typing does not appear to play a measurable role. In fact, Clojure and Erlang were in a category of their own, beating out statically typed counterparts.
It's likely that Clojure and Erlang communities have a higher ratio of experienced developers than mainstream languages. However, this would be true for Scala and Haskell communities as well presumably. Meanwhile, the fact that experienced developers choosing these languages appear to produce better code is an interesting data point of itself.
I wonder if this lack of significant link is because number_of_bugs = time_spent_programming / time_fixing_bugs
So choice of language does affect the number of potential bugs. But this ratio of effort a programmer gives to bugs vs features is almost completely independent. Actual bugs making it past the programmer depend on how much effort the programmer cares to expend
So a safer language doesn't reduce bugs. It's like farmers with back pain from driving tractors. Giving them comfier rides doesn't reduce their pain; it just means they drive faster upto the same pain limit
If this is true, then bugs can be reduced by making bugs more painful for the programmer
But also a safer language will let the programmer drive at a higher speed, releasing a greater percentage of safe code (even if the total number of bugs is the same)
However, the base methodology appears to be really weak.
The presence of fixes doesn't necessarily reflect the presence of underlying bugs: highly conscientious projects make many "fixes" that improve the software quality against an abstract ideal without directly fixing any defect, while highly unconscientious projects don't bother fixing anything.
There are also many confounders. For example, I've seen project institute restrictions on refactoring changes in response to the huge amount of brownian-code-motion popular projects can receive, only to then have some contributors start misleading describing their commits, "by splitting this function up, we avoid the risk that someone would later introduce an overflow!".
Considering how important software quality is to contemporary engineering, including life safety critical systems, it's disappointing that we don't see more randomize studies. E.g. take a pool of developers randomly assign them to teams using different tools each to accomplish the same task, then compare the results against each other and a hidden test suite.
The most practically relevant finding of the original paper remains in effect: the choice of language has an effect of less than 1% on the bug rate[1]. The original paper explains: "With effects coding, each coefficient indicates the relative effect of the use of a particular language on the response as compared to the weighted mean of the dependent variable across all projects." So the entire discussion is on the relative effect of particular languages relative to the total effect of language choice, which is less than 1%. The original paper reported stronger relative effects for particular languages, while this one found the effects to be smaller, and in many cases they disappeared altogether, thus summarizing the effects of the languages as "exceedingly small."
So even the comparison of C++ vs. Haskell, that has ~25% difference, is within that 1%. This is similar to a study comparing the effect of running shoes on running speed that shows that Nike positively affects your running speed 25% more than Adidas, to the extent running shoes affect your speed at all, which is less than 1%.
-----
[1] One should take care not to overestimate the impact of language on defects. While these relationships are statistically significant, the effects are quite small. In the analysis of deviance... we see that activity in a project accounts for the majority of explained deviance... The next closest predictor, which accounts for less than one percent of the total deviance, is language. (https://web.cs.ucdavis.edu/~filkov/papers/lang_github.pdf)
I disagree that the combination of the two studies supports an effect of language choice on bug rate. Given that the original study showed a negative association for about half the languages; the replication has significant disagreement on about half of the original positive associations; and the extremely small associations across all languages, I think we're looking at noise.
But if we consider as the main result that the total effect of language choice is less than 1%, even "looking at noise" means looking at an effect of 0, and either way, the effect is tiny to nonexistent. So if someone had the hypothesis that the effect of language choice is large, because lack of evidence of a big effect is evidence of lack of one, this study is some evidence against such a hypothesis. That this finding agrees with the observations in the industry lends it even more credence.
If I were sitting on a thing that could decrease bugs 1% I'd be really excited. The only reason this looks like a paltry reduction is that it's hugely expensive and difficult to change languages midstream. This is evidence against a shop retraining C++ devs in Haskell (which I'm sure someone somewhere wants to do).
But if it was something like switching editor fonts? I'd do it for 1%.
Two things this studies haven't measured are time to deliver features, and the number of developers necessary. For example, if a project in Haskell can be delivered faster by a smaller team than an equivalent project in C++, that would be an important factor.
There's a concept I discovered in the realm of political science, the "fundamentally unanswerable question" - ones where it's not actually possible to generate the kinds of counterfactuals you'd need to try and run an experiment.
I think this is probably one of those. Haskell and C++ are very different languages, that are designed for very different purposes, and are popular in very different problem domains. To start with, that would make it difficult to come up with a task that wouldn't handicap one language or the other. (For example, a video game would favor C++.) Even if you found that, you'd have a hard time coming up with a good test. Under random assignment, Haskell is presumably going to be handicapped relative to C++ by the fact that most languages are imperative and use Algol-style syntax. You could try to avoid that by using participants with zero programming experience, but then you're studying learning curve for absolute beginners rather than productivity among experts. And so on and so on.
Long story short, probably best to leave this one to the spittle-flecked Internet arguments.
I really don't see how that would be the case. Both Haskell and C++ are general purpose languages, there are plenty of projects written in many overlapping domains. The test would to treat projects as black boxes, and look for trends across many projects. If you saw a trend that Haskell projects are consistently delivered faster by smaller teams, then you could make a hypothesis that Haskell is a factor. At the end of the day, we've come up with ways to test hypothesis like quantum mechanics. I'm pretty sure measuring impact of a language on software development process is a tractable problem.
Quantum mechanics is really a very different beast from the social sciences. Experimental physicists don't have to tease out any confounding effects due to the life history and social baggage that electrons bring with them to the lab.
A huge, huge, huge part of the replication crisis in social sciences is due to researchers getting overconfident about the capabilities of their experimental methods.
Measuring quality of software products is not a social science. You have clear metrics on time it takes to develop something, number of people you need to develop it, numbers of defects per project, and so on. Once you have massive amounts of data, as we now have with repositories like GitHub, it becomes possible to look for trends across languages.
I'm not saying there aren't challenges associated with measuring these things, as there obviously are, but it's certainly possible to study them. And the more studies we have, the more confidence we get regarding the effects.
But you're not just measuring the quality of software products in isolation. The whole point is to measure how a certain set of conditions, particularly the choice of an artifically constructed language that humans use, among other things, to communicate with each other, affects the result of a human enterprise that's typically performed socially.
For these kinds of research questions, human social behavior is not a distraction from the issue being studied. It's the very locus of the issue being studied.
First, we need to established whether there is something that needs to be studied or not. The idea is to look for the outliers by exemaning a large volume of projects in many different languages. If you see a correlation between a language and a result then you can mke a hypothesis that the language is a factor.
At that point you can make a further hypothesis as to whether certain languages encourage a particular kind of social behavior, or whether particular kinds of people are drawn to particular languages. And of course it could just be the technical features of the language that end up playing a role because social aspect may be consistent across languages.
You could look at the project's bug tracker, but the number of bugs in it will reflect a project's popularity more than anything else.
You could look at commit messages, as the (original) paper does (see 2.2.1 / 2.2.2 in the reproduction paper), but the heuristic they use doesn't look very reliable to me; I've seen projects where every feature implementation had to have an issue in the bug tracker and every commit implementing that feature had to reference the issue, so almost every commit would be counted as a defect by their metric.
And of course, all of that is data about known defects, and fixed (presumably) defects in the case of commits - how do you compare the number of unknown defects?
There's an underlying assumption [edit: not implying it's
yogthos' assumption, of course] that you can simply compare unrelated projects with vastly different policies and processes, and I believe that a lot more manual work is required to get reliable and comparable data.
>You could look at the project's bug tracker, but the number of bugs in it will reflect a project's popularity more than anything else.
It's a numbers game, if we look at a lot of projects written in a lot of different languages, we'll see a sample of projects with different kinds of popularity. If there is a trend associated with a particular language that's an outlier that would be an indication that the particular language may play a role.
>And of course, all of that is data about known defects, and fixed (presumably) defects in the case of commits - how do you compare the number of unknown defects?
Again, it's about trends. If you look at thousands or millions of projects these things average out across them. You can even group projects into different categories based on their domain, popularity, and so on. The underlying idea is that you should be able to see measurable trends when looking at large numbers of projects across languages. If such trends are established, then we can dig deeper and make a hypothesis as to what might be the cause.
As someone who develops mostly in C++, I can tell you that productivity is a very small concern. We are well aware that most GCed languages are significantly more productive. Virtually the only reason people use C++ nowadays is for performance (and/or footprint) (that is partly because we have seen reports that Java delivers better productivity in the early '00s, so those who care about that have switched a long time ago; in fact, the effect was so large that they didn't have a choice). Now, if someone showed that Haskell has a significantly better performance/footprint than C++ that may cause someone to shift.
Sure, in some domains you have to use specific languages because of the constraints of the domain. However, as you yourself state, a language can play a significant impact when it comes to productivity.
For example, immutability provides similar benefits to GC. Instead of the developer having to manually manage references across the project by hand, the language takes care of that work. This frees the developer from doing additional work, and removes a source of errors. This also directly leads to the ability to do local reasoning about code resulting in developers needing less context to understand code. So, if GC plays a significant enough role then it's highly likely that immutability does as well because it addresses a similar set of problems.
It would be an important factor when choosing a language obviously. If language A allows you to deliver same kinds of projects as language B, but with less people that's valuable information for the business.
Correct, this is outside the scope of the study. My point was that there are factors other than correctness that are important. Pron's comment implies that since there is practically no difference in quality shown across languages, that the language choice does not matter. However, clearly there are other factors that are important to consider.
137 comments
[ 3.3 ms ] story [ 193 ms ] threadI skimmed the paper. I misunderstood the results.
"Unfortunately, our work has identified numerous problems in the FSE study that invalidated its key result."
It’d be interesting to see whether programmers’ preferences uphold the division posited by the study, or whether they are widely variable—eg is it likely that if you prefer ruby you’ll also prefer typescript over JavaScript, if you prefer Haskell you’d choose clojure over c++ etc.
I mean, this type of study is somewhat open to interpretation. It's not like everyone should arrive to the exact same numbers..
The idea is to take a clear position, which can be attacked if wrong.
Unfortunately, our work has identified numerous problems in the FSE study that invalidated its key result. Our intent is not to blame, performing statistical analysis of programming languages based on large-scale code repositories is hard.
[...]
Acknowledgments. We thank Baishakhi Ray and Vladimir Filkov for sharing the data and code of their FSE paper. Had they not preserved the original files and part of their code, reproduction would have been more challenging
The winners in this paper are Clojure, Haskell, Scala.
I look forward to seeing Rust added. The authors go into substantial detail about what they consider errors, and in my personal experience Rust solves many of them. See e.g. "Some defect type like memory error, concurrency errors also depend on language primitives."
ETA: They actually did not assess Typescript in their reanalysis as most of the files were not actually Typescript, section 4.1.2
> ...only four languages are found to have a statistically significant association with defects, and even for those the effect size is exceedingly small.
Emphasis mine.
"4.1.2 Removal of TypeScript. In the original dataset, the first commit for TypeScript was recorded on 2003-03-21, several years before the language was created. Upon inspection, we found that the file extension .ts is used for XML files containing human language translations. Out of 41 projects labeled as TypeScript, only 16 contained TypeScript. This reduced the number of commits from 10,063 to an even smaller 3,782. Unfortunately, the three largest remaining projects (typescript-node-definitions, DefinitelyTyped, and the deprecated tsd) contained only declarations and no code. They accounted for 34.6% of the remaining TypeScript commits. Given the small size of the remaining corpus, we removed it from consideration as it is not clear that we have sufficient data to draw useful conclusions."
[1] http://www.scala-native.org
[2] https://github.com/scala-native/scala-native
I remember Emery being quite confused at the methodology in the paper, and he was very confused with one aspect of it, which was how they came to conclude that C was more bug prone (something about void * being able to cast to everything? It was a while ago...)
Glad to see he wrote a rebuttal, a little awkward watching a professor debate with the paper's author :)
In the early days of Python, some employers used it as a way to filter for candidates who were ahead of the curve. I believe Paul Graham mentioned Lisp being good for attracting better programmers, although I can't find the reference anymore [1]. If there's any value in this kind of filter, the effects will show up in the programmers' output.
1. I'm having a hard time finding references for these assertions; the best I've found is some Reddit posts and Joel Spolsky's post on finding great developers: https://www.joelonsoftware.com/2006/09/06/finding-great-deve...
A shop that makes the decision to write their stack in Haskell do it with an intention to focus on correctness. I reckon that such companies would consequently invest in other practices like more tests, higher code coverage and more intensive code reviews resulting in code with fewer errors.
This is in stark contrast to a startup that may have hacked together a POC in Python, and once it worked, with a little bit more spit and polish put it into production.
FWIW, the original authors (Ray et al) said as much.
I find that a surprising result! This might also call into question the theory that some languages attract better developers.
>Quite frankly, even if the choice of C were to do nothing but keep the C++ programmers out, that in itself would be a huge reason to use C
[1] http://harmful.cat-v.org/software/c++/linus
Possibly "The Python Paradox" [1] and/or "Beating the Averages" [2]. (The first one, from 2004, is a bit of an odd read nowadays, since it no longer applies to Python.)
[1] http://www.paulgraham.com/pypar.html [2] http://www.paulgraham.com/avg.html
- This study tries to enhance the original work by better metrics (e.g. confusion with C/C++), using better statistics (e.g. uncertainty).
- Automatically evaluating the quality of a code is hard and time-consuming. They had to use peer review of labellisation.
- Most of the old claims are not confirmed.
- Only 2 languages in this study had both a significant impact (impact coeff) and enough fiability (p-value): Clojure and Haskell. But the impact is still small, and there may be other influencing factors.
- They propose several ways to further enhance their work (e.g. taking regression tests into account).
Selection bias? Consider the type of person likely to be attracted to languages like Haskell or Clojure.
(Note, didn't read the original study so I don't know the selection criteria. Were code samples in different languages from the same programmers compared, or were there different sets of programmers per language? My comment really only applies to the latter case.)
On one hand, Haskell or Clojure probably attract more academic types who have a reputation for (consistent with my experience) on-average worse-quality code.
On other hand, the barrier-to-entry for these languages is higher so they tend to be programmed by more experienced folks. I assume that people pick functional languages in part because they believe the functional paradigm leads to higher-quality code, so the sample probably cares more about code quality to begin with.
They went to school, they where not bashed in the head with hammers.
They also found a significant positive association between C++ and bug.
6.3 Grep considered harmful
Simple analysis techniques may be too blunt to provide useful answers. This problem was compounded by the fact that the search for keywords did not look for words and instead captured substrings wholly unrelated to software defects. When the accuracy of classification is as low as 36%, it becomes difficult to argue that results with small effect sizes are meaningful as they may be indistinguishable from noise. If such classification techniques are to be employed, then a careful post hoc validation by hand should be conducted by domain experts.
Smalltalk was wonderful in this regard. If you wanted to search for how something was used, you just right-click search for "senders." If you wanted to find implementors, the same.
This big difference occurred with chains of senders. In other languages, where there's 2 or 3 ways to get to something or call something, you have this O(2^n) or O(2.5^n) blowup in the work you have to do to properly follow chains of senders. With Smalltalk, it's just O(n).
On top of that, there were tools that could let you compose really sophisticated SQL like queries of the code base, dynamically, then pop that up in a browser.
I guess it just comes down to needing a sufficiently large corpus of code and commits and having to eventually publish.
From this paper:
The reanalysis failed to validate most of the claims of [18]. As Table 6(d-f) shows, the multiple steps of data cleaning and improved statistical modeling have invalidated the significance of 7 out of 11 languages. Even when the associations are statistically significant, their practical significance is small.
The reference [18] is https://dl.acm.org/citation.cfm?doid=2635868.2635922, which is the original paper that this paper is a replication study of.
5.3 and 5.4 really nail it, IMO.
And you can't even use bug fixes as a metric, because there's a difference between semantic bugs which will be significantly language-influenced, architectural bugs which are partly language-influenced, and user-expectation/experience bugs, which are broad-brush logical errors or misunderstandings.
(There are probably other categories, but those are the obvious ones I can think of right now.)
The real takeaway is there is as yet no objective metric for software quality.
The best a working dev shop can do is implement a small but non-trivial sample project with known-good logic in a handful of candidate languages, and see what kind of trade-offs fall out.
I do think user experience/expectation bugs are very language dependent though. First you have the quality of the String and Datetime libraries. Ruby has all kinds of high quality string functions that are a source of pain and bugs in C.
Say your project wants to display the different between two datetimes as "5 minutes ago" or "last month" (in several languages). Saying "1.27 days ago" is correct to an extent but also not pretty. There exist high quality libraries for this, but not in every language, and a lot of devs would stumble on this feature.
The other is UI creation, I would say it is easier and faster to create a really nice UI with HTML/CSS/JS than with native Android. Maybe I'm wrong on this example but I bet there is a pair of UI frameworks where this is true.
I consider those to be bugs in the spec, not the code. I once worked at a place that simply swept those under the rug - if it worked as documented, it didn't matter how many users couldn't get it to work. The bug report was closed as "not a bug"; you can imagine how frustrating that was.
I think the lesson here is that you can write good or bad code in any language, but choose one that's fit for purpose. Using proper abstractions (including those builtin to languages) probably does more to reduce the incidence of bugs than anything you can do other than writing automated tests.
For those who don't happen to know the difference, formal code review basically uses a check list of common best practices and possible defects to look for versus doing each code review ad-hoc.
It's difficult for me to see how, in the era of jsfunfuzz, Csmith, AFL, and other such tools, such a source should be taken seriously.
You would be doing yourself a disservice to throw out all of Newton's results because he didn't grasp relativity.
Reanalysis showed positive association between defects and C++, negative association for Clojure, Haskell and Ruby.
The original analysis found positive association for C++, Objective-C, C, PHP, Python, JavaScript. Negative association for TypeScript, Clojure, Scala, Haskell, Ruby.
I've seen terrible codebases written in vanilla PHP, JavaScript, Python (probably the worst ones). But I've seen very good looking, easy to understand, easy to maintain codebases written in Symfony, React and Django.
(React is an interesting case because it's not actually a framework but a view library, which doesn't force you to follow any structure to your project. But its declarative, component-based paradigm seem to help developers structuring their projects and writing simple, reusable and composable components in a good way).
If you have to use the "weird parts" of a language to get typical work done, you are doing something wrong. And if you are not using the weird parts, then programming languages look and do pretty much the same thing.
Braggings such as, "look! My language can do double recursive lambda backflips while blindfolded and chewing gum!" are mostly just 1950's car racing done in cubicles. We buy cars to get to work and shops as cheaply and conveniently as possible, not beat Fonzy.
See Paul Graham’s essay on the Blub Paradox [0], which discusses why some languages seem to have “weird parts” from the perspective of someone who knows a less-powerful language.
[0] http://www.paulgraham.com/avg.html
My favorite line from this paper is: "Correlation is not causality, but it is tempting to confuse them." I think most people believe "correlation is not causality, but most of the time it is", when in reality it is, "correlation is not causality, and almost never is." There was a great analysis of this in a book or paper I read years ago that I haven't been able to find, but the tldr is that if you have a set of events, if causality were truly common, the events would for a seized up network of causality.
I can say I hated reading C because of maccros and different build systems. I hated C++ codebases because people abused generics. And I hated Java the most because of the verbosity and the directory structure and all the layers of abstractions and all the factories and all the singletons and all the...
It makes me wish the language creators wrote a single none-trivial 'this is how we intended it to look' project.
When learning a new language I find as many big projects written in it as I can and spend time exploring them.
It helps but there is often no guarantee those projects are doing it idiomatically either.
Fair, but a lot of those abstractions make life more difficult for new programmers (Why do I have to look through 12 classes to find out what this button does?), but make life much easier when you know the code base and have to maintain and extend it.
Or, legit question - is Java more prone to these types of issues due to its design?
Yes. Except on the actively powerless languages (mostly C and Go), people write code on other languages with the same flexibility that all that indirection creates on Java, but they use much simpler structures.
You can have that in PHP, too, when the project builds on Symfony, that is to say the style is not only dictated by the language but also on the framework used.
Suppose I have to write 100,000 lines in language B to write something doable in 10,000 lines of A. Who cares if the defect rate is twice as high per line of A: I still have five times fewer defects due to ten times fewer LOC's.
Another thing to consider is the nature of defects. A defect that allows a remote execution exploit is not the same as an incorrect result being ignored and propagating to later calculations, is not the same as terminating with a diagnostic.
* Python, JS, PHP, Java, C++ are all very common first languages; I'd imagine the average experience level for these is dragged down a bit compared to others like Golang, Haskell, or Scala. One of the recent Stack Overflow Developer surveys found Golang use to be strongly correlated with age, and since I'm assuming bug count would negatively correlate with age you'd see a confounding factor here.
* Ruby's community has an obsessive culture towards unit testing, that could impact bug levels.
* The trade-offs that make C and C++ attractive such as memory performance are double-edged swords and will naturally correlate with more bugs. For example, I work a fair bit in embedded systems which use MISRA C out of necessity; I've also worked in large scale data processing which chooses C++ for its memory mapping performance over Java or Go. If "number of defects" is your primary measure then you're ignoring some of the reasons languages are chosen. Sometimes a language that minimizes bugs is not a viable option.
* I'd guess there is a skill correlation here: an engineer who is willing to seek out a specific less-used language and learn to use it effectively is probably more likely (not guaranteed) to do a better job than one who is just going with the default choice.
It'd be very interesting to see a regression done that accounts for these factors.
Sure, I've seen global try/catch blocks swallowing all errors in C#/C++ code too, but definitely not as prevalent in my anecdata.
Despite these three languages giving far too much freedom to the programmers (which some might even like), high-quality code can be written in all three of them, as long as intelligent and strict coding guidelines are thoroughly followed.
And of course lots of out of band(non-language) processes and tools that influence this like unit testing/code reviews/strict coding guidelines. But it's always nicer when it's prevented at the language level as opposed to out of band.
Like Smalltalk, they're forced to do this to catch the errors that would've been caught by type annotation. So then, could the argument be made that less stringent type annotation hurts code quality by removing effort from unit testing?
Figuratively speaking. None of the languages they test enforce any unit testing. What I'm suggesting is that since the Ruby community tends to be more obsessive about testing, that might lead to an improvement in code quality when comparing against other similar languages like PHP or JS which are less obsessive about testing. It's something you might have to control for to see the impact.
Type systems are a completely different factor; you'd have to control for that variable too to determine the impact of it. My experience with both systems makes me predict that static typing would improve code quality, but if you want to actually be scientific you'd want to add that factor to the statistical analysis to see if the data support that hypothesis. Anecdotes like personal experience don't count.
The trivial type-mistake "Unhandled Exceptions" in Smalltalk would leak out more often than was comfortable, if the project didn't have a good means of testing to catch those. I suspect that has something to do with the Ruby community being more obsessive about testing.
?
MessageNotUnderstood
[1] https://twitter.com/unclebobmartin/status/113589437016571084...
It does not appear that the paper took automated testing into account at all. Whether greater use of automated testing in Ruby is responsible for the lower defect rate observed here relative to Python would definitely be an interesting topic for another paper.
Clojure is also dynamically typed by default and below the line. It does not have Ruby's strong unit testing culture, but it does have a design that encourages functional programming, which proponents argue reduces sources of error. It also has a culture of REPL-driven development that arguably fills some of the role of automated testing.
Very few of the unit tests I've written for Ruby/Python catch errors that would be caught by typical type system use in C/Java/etc. (Haskell, maybe, but...) The main thing I miss in dynamic languages vs. static is the more powerful automatic testing possible when test specs can leverage type information (e.g., QuickCheck/ScalaCheck), not an absence of need for testing.
Plus, AFAIK, no one has written the libraries, making it even higher marginal friction in practice even more than than is true in the ideal case.
Types just make everything easier to do right the first time.
Is the code quality better? Well maybe. Probably. But dollar for dollar you’ll do better with a good language because you’ll get much better people for your dollar.
Overall language effects do not appear to be a dominant factor in software quality. Manual memory management is error prone. Functional languages appear to produce better results than OO/imperaive ones. Static typing does not appear to play a measurable role. In fact, Clojure and Erlang were in a category of their own, beating out statically typed counterparts.
I wonder how they controlled for developer skill?
So choice of language does affect the number of potential bugs. But this ratio of effort a programmer gives to bugs vs features is almost completely independent. Actual bugs making it past the programmer depend on how much effort the programmer cares to expend
So a safer language doesn't reduce bugs. It's like farmers with back pain from driving tractors. Giving them comfier rides doesn't reduce their pain; it just means they drive faster upto the same pain limit
If this is true, then bugs can be reduced by making bugs more painful for the programmer
But also a safer language will let the programmer drive at a higher speed, releasing a greater percentage of safe code (even if the total number of bugs is the same)
However, the base methodology appears to be really weak.
The presence of fixes doesn't necessarily reflect the presence of underlying bugs: highly conscientious projects make many "fixes" that improve the software quality against an abstract ideal without directly fixing any defect, while highly unconscientious projects don't bother fixing anything.
There are also many confounders. For example, I've seen project institute restrictions on refactoring changes in response to the huge amount of brownian-code-motion popular projects can receive, only to then have some contributors start misleading describing their commits, "by splitting this function up, we avoid the risk that someone would later introduce an overflow!".
Considering how important software quality is to contemporary engineering, including life safety critical systems, it's disappointing that we don't see more randomize studies. E.g. take a pool of developers randomly assign them to teams using different tools each to accomplish the same task, then compare the results against each other and a hidden test suite.
So even the comparison of C++ vs. Haskell, that has ~25% difference, is within that 1%. This is similar to a study comparing the effect of running shoes on running speed that shows that Nike positively affects your running speed 25% more than Adidas, to the extent running shoes affect your speed at all, which is less than 1%.
-----
[1] One should take care not to overestimate the impact of language on defects. While these relationships are statistically significant, the effects are quite small. In the analysis of deviance... we see that activity in a project accounts for the majority of explained deviance... The next closest predictor, which accounts for less than one percent of the total deviance, is language. (https://web.cs.ucdavis.edu/~filkov/papers/lang_github.pdf)
But if it was something like switching editor fonts? I'd do it for 1%.
I think this is probably one of those. Haskell and C++ are very different languages, that are designed for very different purposes, and are popular in very different problem domains. To start with, that would make it difficult to come up with a task that wouldn't handicap one language or the other. (For example, a video game would favor C++.) Even if you found that, you'd have a hard time coming up with a good test. Under random assignment, Haskell is presumably going to be handicapped relative to C++ by the fact that most languages are imperative and use Algol-style syntax. You could try to avoid that by using participants with zero programming experience, but then you're studying learning curve for absolute beginners rather than productivity among experts. And so on and so on.
Long story short, probably best to leave this one to the spittle-flecked Internet arguments.
A huge, huge, huge part of the replication crisis in social sciences is due to researchers getting overconfident about the capabilities of their experimental methods.
I'm not saying there aren't challenges associated with measuring these things, as there obviously are, but it's certainly possible to study them. And the more studies we have, the more confidence we get regarding the effects.
For these kinds of research questions, human social behavior is not a distraction from the issue being studied. It's the very locus of the issue being studied.
At that point you can make a further hypothesis as to whether certain languages encourage a particular kind of social behavior, or whether particular kinds of people are drawn to particular languages. And of course it could just be the technical features of the language that end up playing a role because social aspect may be consistent across languages.
How do you measure that?
You could look at the project's bug tracker, but the number of bugs in it will reflect a project's popularity more than anything else.
You could look at commit messages, as the (original) paper does (see 2.2.1 / 2.2.2 in the reproduction paper), but the heuristic they use doesn't look very reliable to me; I've seen projects where every feature implementation had to have an issue in the bug tracker and every commit implementing that feature had to reference the issue, so almost every commit would be counted as a defect by their metric.
And of course, all of that is data about known defects, and fixed (presumably) defects in the case of commits - how do you compare the number of unknown defects?
There's an underlying assumption [edit: not implying it's yogthos' assumption, of course] that you can simply compare unrelated projects with vastly different policies and processes, and I believe that a lot more manual work is required to get reliable and comparable data.
It's a numbers game, if we look at a lot of projects written in a lot of different languages, we'll see a sample of projects with different kinds of popularity. If there is a trend associated with a particular language that's an outlier that would be an indication that the particular language may play a role.
>And of course, all of that is data about known defects, and fixed (presumably) defects in the case of commits - how do you compare the number of unknown defects?
Again, it's about trends. If you look at thousands or millions of projects these things average out across them. You can even group projects into different categories based on their domain, popularity, and so on. The underlying idea is that you should be able to see measurable trends when looking at large numbers of projects across languages. If such trends are established, then we can dig deeper and make a hypothesis as to what might be the cause.
For example, immutability provides similar benefits to GC. Instead of the developer having to manually manage references across the project by hand, the language takes care of that work. This frees the developer from doing additional work, and removes a source of errors. This also directly leads to the ability to do local reasoning about code resulting in developers needing less context to understand code. So, if GC plays a significant enough role then it's highly likely that immutability does as well because it addresses a similar set of problems.
[the] association between eleven programming languages and software defects in projects hosted on GitHub.
Nothing more, nothing less.
If they wanted a "x is better than y for business", it would not be a serious study at all, just a bunch of journalistic edgy writing.