His wife was a professor at the Northeastern computer science department when I went there. A wonderful teacher.
HN user
bguthrie
DirEng, Justworks. Founder, @orgspaceio. Ex Meetup, Slice, SoundCloud, ThoughtWorks. https://brianguthrie.com
I hadn't realized Zed was built from the ground up to support collaborative programming. I liked it already, and I like it even more now.
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.
I was working on Rails apps before AMIs or Heroku.
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).
Many demonstrably innocent people are indicted and convicted with far less evidence than a video. Nonetheless, for other cases I grant the point.
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.
Edit: For context, this is what I had in mind: https://medium.com/for-the-love-of-podcast/serials-big-confe...
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.
I think the focus on immediate, actionable feedback is great, but I get really nervous when I see screenshots with graphs. Does peer to peer feedback happen often enough to merit such an analytical approach? Getting continuous feedback is a great goal, but it strikes me as a human (or process) problem, not a technical one.
A day rate means a day's worth of your time, not necessarily of your code, and a standard workday normalizes to 8 hours. Don't sweat time on keys and be as productive as you'd normally be. If you'd normally take periodic breaks, take periodic breaks; the same goes for other work habits. If you can't code continuously for 8 hours (and most people can't), find other ways to contribute your skills. I believe this is fairly standard consulting practice.
This is a wonderful piece of computer science history, and is of interest less for its nominal topic (recursion) than for the insight it gives into an early slice of languages research. Well worth a full read.
Strategically, how did you approach the rewrite? It sounds like you had a significant amount of frontend code; replacing everything at once can be risky. Did you choose specific pages and work your way in, or scrap everything and work your way from the inside out?
That's a great tip––thanks, I'll do that.
My bike was just stolen yesterday. I never wrote down the serial number, and now I'm part of the problem.
Next time I'll be doing that, and registering with this service. Thanks for fighting the good fight.
Neither myself or the author presented a controlled study; they are both individualized experiences that may or may not be relevant to one's own project. I'm simply trying to say that the OP isn't gospel. That said, for the forcefulness of the headline, I would've expected much more data.
No, what this article states is that the author hates to register, and for their particular app, not registering may have made a difference in its adoption rate. That doesn't say much about the implications of registration for your business.
I recently launched an app that requires Facebook registration. I expected it to be a disaster, but a necessary evil for our first pass. I was shocked to find a conversion rate from opening the app to logging in of 95%; it's not hurting us nearly as badly as I anticipated. Measure!
People tend to reserve pair-programming for tasks they perceive as being unusual, complex, or otherwise needing extra review. Personally, I've found it can be helpful even when you simply need to stay on task. When you both have the same goal, you can rally each other; it's typical to become more productive together than you would have been apart.
If this sounds like it could be your style, grab a buddy and see if you can hammer out some of the small stuff together. If not, some of the other suggestions here are good as well.
I think this is a good assessment. I'm a little more bearish, though I love the language. I rode the Rails train in the past and recently embarked on a real web project with Compojure.
At first it felt like a very mixed bag. There are a number of reasonable if boring things that Rails provides that help make it easier to get your app production-ready––robust logging and asset compilation come to mind––that generally have to be hand-rolled in Compojure (as in microframeworks in other languages). More generally, there aren't many clear signposts from an architectural point of view––for example, there does not appear to be much community guidance over how to organize your namespaces, or how much code one should contain. We made some messes early on.
Once my partner and I got past the initial pain, however, we were extremely pleased with our choice. There are still times when I suspect Rails might have gotten us to market more quickly, but Clojure feels like a good ten-year choice. I certainly agree it's worth a second look.