The problem with no collaboration is that it can lead to fragility. Context transfer is costly, but without it work bottlenecks around key individuals. When those individuals are explicitly disincentivized to transfer knowledge preemptively, you lose the slack in the system. Vacations and exits become more fraught. Deadlines are harder to hit reliably. You have less systemic resiliency.
Instead, encourage targeted collaboration (in particular, pairing: collaboration with a goal of accomplishing something) within the scope of a team, and avoid cross-team collaboration, which is the expensive part.
This was before Git! (Subversion had its meager charms.) Even after Git became widespread, some infra teams were uncomfortable installing a dev tool like Git on production systems, so a git pull was out of the question.
The main issue that, while not unique to Rails, plagued the early interpreted-language webapps I worked on was that the tail end of early CI pipelines didn't spit out a unified binary, just a bag of blessed files. Generating a tarball helped, but you still needed to pair it with some sort of an unpack-and-deploy mechanism in environments that wouldn't or couldn't work with stock cap deploy, like the enterprise. (I maintained CC.rb for several years.) Docker was a big step up IMV because all of the sudden the output could be a relatively standardized binary artifact.
This is fun. We should grab a beer and swap war stories.
My recollection is that this is what many Capistrano setups were doing under the covers. Capistrano was just an orchestration framework for executing commands across multiple machines.
More than that, I worked for many enterprises that were using Rails but had their own infrastructure conventions and requirements, and were unable or unwilling to explore tools like Capistrano or (later) Heroku.
I've been writing Rails code since 2007. There's a reason the stack has gotten more complicated with time, and virtually no team has ever done it right by this definition.
The trouble with an omakase framework is not just that you have to agree to the initial set of choices but that you have to agree with every subsequent choice that's made, and you have to pull your entire dev team along for the ride. It's a very powerful framework, but the maintainers are generally well-meaning humans who do not possess a crystal ball, and many choices were made that were subsequently discarded. Consequently, my sense is that there are very few vanilla Rails apps in the wild anywhere.
(I'm old enough to remember what it was like to deploy a Rails application pre-Docker: rsyncing or dropping a tarball into a fleet of instances and then `touch`ing the requisite file to get the app server to reset. Docker and k8s bring a lot of pain. It's not worse than that was.)
I spoke to the authors of this database while running my last startup about the exact problem this sets out to solve—the need for time-travel features in particular domains (versioning for everything!). Opens up a range of interesting options for novel user experiences—really glad that this is seeing the light of day.
I reviewed the article in question and have a little more color to add for some of the skeptics commenting below.
Advocates of pre-merge review point out (correctly) that peer review is valuable: humans are fallible, and a second pair of eyes often helps. Maybe I read a different article, but I don't think the author disputes this. What gets lost in the discourse around the dominant PR-based, asynchronous workflow is that it comes with tradeoffs. Do you understand what you're giving up to get back in your preferred mode of working? Are you so certain it's more appropriate for your present circumstances?
_Forced_ pre-merge review has a number of negative tradeoffs that aren't always visible to the teams that use it. For one thing, it can lead to "review theatre": casual pull request reviews can't meaningfully detect most bugs; reviews that can are hugely time consuming and as a result quite rare; poor PRs are sometimes "laundered" by the review process; poor reviewers encourage bikeshedding; but even a bad review can introduce a cycle time hit and a bunch of context-switching as both the submitter and reviewer bounce back and forth. If you work at a shop that uses PRs and has none of these problems, I salute you; I have not.
The answer to all of these from PR advocates tends to be, well, maybe make the pre-merge review process itself better, to which I say: you are making a slow process slower; if your team is trying to move quickly, instead of adding additional padding around a slow process, maybe try to smooth out a fast one?
A good framing question I ask my teams is: if your goal was to get high quality code into production as often as possible, what processes would you tweak and why? Where would you invest and where would you pull back? There are lots of great ways to ship high-quality code quickly without pull requests; we did it all the time before they were invented.
I use Scala frequently for internal microservices development. I also write a fair amount of Clojure. I believe that a lot of good and robust software is built in Scala, but that it suffers from a kind of complexity fetishization that offsets, for debugging purposes, a lot of the positive effects of robust typing. Compiler speed is also a problem for me personally.
Given my choice of options, I will choose to build new systems in almost any other JVM language, including stock Java 8. However, the language isn't going anywhere, and is worth learning. I find that feedback is fastest in Clojure. Your mileage, as always, may vary.
I think that talking about a 10x engineer or 0.5x engineer misses the right optimization: good software is built in teams, so build a strong team. Cross-skilling, pairing, and blocker removal all help give people a collective sense of commitment and autonomy: you have the right to touch the systems you need to accomplish your job, and it's my job as servant-leader to remove whatever's stopping you. But you have less leverage and less resilience without that sense of collective ownership.
I've likewise experienced both 10x and 0.5x situations. The latter invariably arose from sitting in a corner, divorced from context or support. The former is extremely rare and I've only achieved it on personal projects. But I'll settle for a motivated and healthy team of 5xers any day.
Cursive is an excellent way to write Clojure and has improved my workflow tremendously. Highly recommended; I bought a license. Congratulations to Colin on a 1.0 release.
I'm not clear what technique this article is trying to describe, but anyone that spends two weeks pre-writing tests is not performing TDD. That simply isn't how it works.
The cycle is: red, green, refactor, repeat. That's per test. It shouldn't take long. It works nicely.
I remember working out of the same office as these guys back when they were just getting started, and their success and impact has been truly amazing. Recognition well deserved.
Exception handling is currently my biggest complaint with core.async, and I've gained a fair amount of sympathy for the idea of encapsulating asynchronous operations inside an object that can accommodate failure states, like a future (though Clojure futures don't).
The law doesn't do an especially good job of it either. Perhaps it would be better were we all more observant of the principle than we tend to be; the accused is not always guilty.
Note that while the main header describes the topic as "the practice and craft of functional programming," the body text makes it clear that it is "a new conference for typed functional programmers." Thus the notable omission of any Lisps. Seems like a wonderful idea for a conference, and best of luck to the organizers.
Puzzles are a terrifically poor way of judging whether a candidate will be good at performing the most common form of programming there is: solving meaningful problems, often business or interface ones, in a simple and readable way. Your primary audience for this type of programming is other humans. I'll take a good writer over a puzzle-solver any day. Don't get discouraged if they aren't for you.
As a candidate, I'd much rather they ask; I find that companies that don't ask for code are almost by definition unlikely to ask the right questions. If you must screen candidates for skillset, the less you have to rely on a proxy for that skillset the better off you are. As an employer, I find code samples irreplaceable, and I'm comfortable screening out candidates who decline to take the challenge out of principle or limited time.