Thank you for sharing that video, I just watched the whole thing; such great storytelling. Its got a very similar aesthetic to mine with every action having an extremely small margin for error, with extremely grave consequences, and with a protagonist who is surprisingly accepting of that world.
HN user
jesseduffield
You can plot all activities on a spectrum of dopamine 'cheapness'. On one side of the spectrum is slot machines, various drugs, and doomscrolling. These generally involve little effort, and involve 'variable ratio reinforcement' which is where you get rewards at unpredictable intervals in such a way that you get addicted. Generally, after a long session of one of these activities, you feel like crap.
On the other side of the spectrum is more wholesome long-horizon activities like a challenging side project, career progression, or fitness goals. There's certainly an element of variable ratio reinforcement in all of these, but because the rewards are so much more tangible, and you get to exercise more of your agency, these activities generally feel quite meaningful on reflection.
Playing pinball is somewhere in the middle, probably on the cheaper side of the spectrum. Introspective people can generally reflect on a session and decide whether it was a good use of their time or not.
I really think that 'how do you feel after a long session of this' is a good measuring stick. Very few people will tell you that they feel good after a long session of social media scrolling or short-form content.
Another good measuring stick is 'do you want to want to be doing this?'. I want to want to go to the gym and gain 10kg of muscle. I do not want to want to spend hours on tiktok every day.
I've seen a lot of AI 'arena's around but nothing that actually puts embodied agents in a space and lets them fight eachother, cooperate, etc. I built this in my week off work, and figured some of you may find it interesting. Feedback welcome!
The world needs more intelligent shitposting. I support you.
Post from the creator of Rust, 11 years ago. Highly relevant to today.
Glad somebody got the reference!
It appears that RedwoodJS as we know it is being wound down. I've never used Redwood JS but I've watched it from a distance as it was (to my knowledge) striving to be a proper fullstack JS framework akin to rails, which is a noble pursuit. Seems like they had some challenges getting traction and supporting React Server Components and now they're pivoting to a new project which revolves around cloudflare workers.
Good point. I've updated the post to provide context + link
Lazygit has its own built-in approach to this problem which is much more strict than what git-absorb does (it explicitly asks for confirmation if there's any ambiguity). There's an extensive writeup about it here: https://github.com/jesseduffield/lazygit/blob/master/docs/de...
Still down for me
In this interview I had the chance to ask Bob many questions that had been stewing in my mind for a while, such as: * Are there some domains where Object-oriented programming is better suited than functional programming? * Is the Single Responsibility Principle supposed to be taken literally? * Is the Dependency Inversion Principle still useful if you have fast compile times and it’s easy to test dependencies without injection * Testing private methods: surely sometimes it’s okay * Is 100% code coverage actually a good goal? * How does Bob feel about programmers who just see their job as a job and aren’t passionate about it * Is a call for professionalism just unproductive gatekeeping? * Comparison as a thought leader to Martin Fowler * Does AI threaten programmer jobs * Will we have an AI singularity?
If any of the above questions have been or your mind too, you might find this interview valuable.
Seconding this opinion: Dwarkesh's podcast is really good. I haven't watched all of the Zuck interview but I recommend others to check out a couple extra episodes to get a more representative sample. He is one of the few postcasters who does his homework.
I completely agree
Author here, this made my day! Sounds like you and I share similar experiences with motivation.
I'm glad you like lazygit, hopefully I can continue to keep it in high esteem :)
Thanks!
Whoops! I should have fact-checked that: I had it in my head that it was recent based on there being so much recent discussion of it online. I've updated the post
Maintainer here, thanks for the shoutout!
A new version just came out today https://github.com/jesseduffield/lazygit/releases/tag/v0.39....
In the next release we're adding worktree support: if you use worktrees in your daily flow I'd love to know what that flow looks like and what your pain points are so feel free to join the discussion here: https://github.com/jesseduffield/lazygit/discussions/2803
Thanks for the feedback, I've been slack on documentation as more features have been added. Do you have a preference for tutorials? e.g. video or text?
Lazygit maintainer here: I've found myself in your shoes quite a bit (without the commit signing part) and a few weeks ago I put up a draft PR where if a file is selected, it highlights the commits that touch that file. Typically you want to amend the most recent commit that changed the file and typically that commit is visible without needing to scroll. But I haven't spent much time thinking about what the ideal UX is, how to activate it, etc.
Author of the post here: I've written a follow-up that addresses some of the rebuttals made in these comments: https://jesseduffield.com/Unless-Responses/
If I've neglected to address your specific criticism I'm happy to do so here
After some thinking, I now see what you were talking about wrt code coverage, however again the same argument can be applied to higher levels of encapsulation and it's not obvious private methods are special.
Private methods by definition are not an abstraction.
A private method is indeed an abstraction. If you take a chunk of code and extract it out into a method, that's an abstraction, regardless of whether it's private or not.
Say a branch is never reached through a public interface but you test it in your unit tests since you don't know. This aspect is completely hidden from you.
This is purely a tooling problem. There is no good reason why your linter can't flag that a private method is unused in non-test code.
Encapsulation literally defines this as a core principal. If you don't accept that then you don't accept the most important concept of OOP.
Do you have a source evidencing this claim? I would be surprised to find any canonical source stating that private methods should be held to a different standard to private classes and private packages
If you want to break encapsulation you need to come up with an argument that's better than: "It's easier for me in this specific case".
My argument is this: we 'break' encapsulation every time we write a test that's not end-to-end. The question is how much we want to break it, and that question depends on how stable and well-defined the abstraction is that we want to test. If a private method is stable and well-defined, and if the cost of extracting it out into its own class is too great, then it's appropriate to test. A private method is less likely to be stable and well defined compared to a class or a package, because it's at the bottom of the encapsulation hierarchy, but it is not fundamentally different to other levels of encapsulation, and therefore there will be times when it is appropriate to test.
I address this point in the post but I'll summarise here: Your argument is equally applicable to higher levels of encapsulation. If you have a class which is private to a package, then code coverage tells you nothing about whether that class is actually used in your package's public API. If you have a package which is private to some parent package, you're in the same situation. You can follow this all the way up to the binary output of an application and say that unless you're doing end-to-end tests which capture user keystrokes and mouse clicks, you're breaking encapsulation (you can make the same argument for a large library).
We choose not to run only end-to-end tests because it's expensive both in terms of writing the tests and running them. We choose not to run only unit tests at the lowest possible form of encapsulation because they're more likely to need rewriting when we refactor. Instead we pick out abstractions at various levels of encapsulation that warrant testing in isolation. The decision on whether to test a private method or a private class or a private package differs only in degree, not in kind.
To convince those who disagree with you, you'll need to make a case for why private methods should in fact be held to a different standard than other levels of encapsulation. I'm open to being persuaded on this point but I can't think of an argument that convinces me.
To be clear, I was responding to the combined argument of the above comments: that you should split the class but not expose the extracted class in the public API. I agree that there are cases where we don't need to extract the class, but am willing to be convinced otherwise.
I see this as the main tension in the extracting-class viewpoint. Assuming your language allows it, you can extract out a class that's still private to the current package, meaning that the public API is unchanged. But there are still costs to extracting out that class.
If the one public method just calls private method A, B, and C in order, passing the result of one step to the next, and if we don't need to handle different variants of A, B, and C (meaning dependency injection is not necessary), we arguably don't gain much from splitting the original class in two. We're left with a very small class of a single method that's tightly coupled to the extracted class. We can remove the coupling with dependency injection, but now we need to add some code that actually injects that dependency at runtime. So understanding how the pieces fit together is harder. The only benefit to splitting the class that I can think of is in preparing for a future situation where orchestrating the three helper methods becomes more complex, or where you actually do need to handle different variants of A, B, and C via dependency injection. But it feels like premature abstraction to me, single responsibility principle notwithstanding.
I completely agree. The post became longer than I would have liked even without examples and didn't want to make it any longer with examples, though it would be a good basis for a follow-up post.
I agree with your point about the dangers of right/wrong thinking, though when I wrote that line I was specifically thinking about people who say we should never test private methods vs people we say we should always test private methods, in which case they truly can't both be right. I've updated the post to make that clearer.
On your point about language limitations, I also wonder about this. I vaguely recall coming across a post that mentioned testing private methods just wasn't an option in various languages in the early days, and it's possible that were that not the case, we wouldn't have so many advocates of the never-test-directly viewpoint. That's not to say that the viewpoint is wrong though.
Thanks for adding the stack trace. I've made a bug issue to track this https://github.com/jesseduffield/lazygit/issues/1601 and I'll take a look into it tonight. I'll need to dig into why our windows integration tests don't catch this (it appears to be a windows-specific problem)
One of the largest pieces of feedback I've had is around displaying the actual git commands that lazygit runs so now there's a new panel that does exactly that, displayed by default. I find that works well for demystifying what's going on and can actually help educate on which commands can satisfy which use cases. It's also kept me accountable in that if I try to satisfy some use case in a sneaky, smart way, it results in a scary looking series of git commands, so I've scaled back some of the 'magical' stuff that was going on for the sake of user confidence.
Yeah I regret using pgup/pgdown for regular scrolling in the beginning. I'm gonna add keybindings for paging up and down properly (so that a user can remap those to pgup/pgdown) and I think down the line I might change that to be the default behaviour, but it's tricky when it comes to keybindings people are now familiar with after using the app for a while.