• 0 Posts
  • 43 Comments
Joined 1 year ago
cake
Cake day: June 12th, 2023

help-circle

  • It’s weird to have something that verbose for using in the shell. I don’t want to use verbose commands when just doing stuff interactively, so I never learn how to really use its features as a concequence. Bash, while it has more footguns, is more readable to me because I’m more familiar with the individual commands. For most programing you spend more time reading it than writing it, but that’s not the case for the shell so there it’s the wrong tradeoff imo.


  • Since the diffs are tree-sitter based, it’s interesting to think about what a tree-sitter based patch would look like. Probably wouldn’t double as a human and computer friendly format like normals diffs. I suppose that you could create patches that are more robust to the source code changing since it wouldn’t care about linebreaks and maybe you could have it so it doesn’t care if you move code around since you could have it so its going by e.g. what the parent function is and not the line number. I gotta wonder how useful that actually is though.


  • There is a lot of fanboying in discussions like these, so I understand if you’re weary of that. That said I don’t think static analysis tools are a very good point of comparison for (what I’m assuming that you’re referring to) Rusts ownership system.

    While static analysis tools certainly can be useful for some classes of errors, there are types of errors that they can’t catch that the borrowchecker can. This is because the language are built around them in Rust. Rusts lifetime analysis is dependent on the user adding lifetime annotations in certain situations, so since c++ doesn’t have these annotations static analysis tools for c++ can’t benefit from the information these annotations provide.

    Furthermore, c++ suffers from being an old language with a lot of features. Legacy features can allow for various loopholes that are hard for a static analysis tool to reason about.

    C++ static analysis tools can find errors, but Rusts borrowchecker can prove the absence of errors modulo unsafe code.

    That said, I don’t have any good data on how much of a problem this is in practice. Modern c++ with a CI-pipeline doing static analysis and forbidding certain footguns is safe enough for most contexts. Personally, I’m exited about Rust more because I think that it’s a nicely designed language than because of its safety guarantees, but it doesn’t really have the ecosystem support for a lot of things, like gamedev or ui at the moment.


  • There will be plenty of jobs in c++ in the foreseeable future, so it’s not a bad language to know from that perspective. I don’t know if it’s the most pedagogical language to learn otoh, python is a better language for getting comfortable with the basics, c is better when it comes to learning a (slightly wrong but close enough) mental model of how a computer works under the hood, and there are many better languages to learn if you want to learn good approaches to thinking about problems.

    Maybe you are leaning c++ because you want to work on something specific that c++ is primarily used in, and in that case go ahead with that project. I think having something tangible that you want to work on is great when it comes to learning programing and that’s worth more than picking the “best” language. Besides, you can always learn different languages later in your career if you want/have to.




  • Multiple cursors are a lot better than :s for you standard search and replace, unless you have a really big file at which point helix gets to slow (which isn’t that common) but there are a lot of other stuff you can do with ex commands.

    I use :make pretty often, vim ships with the ability to parse a lot of compiler/linter outputs out of the box so if you tell it which one with :compiler you get build errors in the quickfix list. I also use :grep a lot. You can do <space>/ to grep in helix but I often find that I want to add command line options to only search in specific directories or for specific file types (we have a large codebase at work). Being able to filter results with :Cfilter, and being able to go back to old quickfix results with :colder is also really nice. Finally, you can use :cdo to apply ex commands to stuff you’ve matched in the quickfix list.

    As an example, if you get a build error because you’ve renamed a variable in one file but not the places it gets referenced in other files, you can :make to get the build errors in you quickfix list, :Cfilter to narrow it down to only that specific class of error if needed and then do :cdo s/oldName/newName/g to rename the variable in all places that cause errors. You can then go back to the list of all errors with :colder and handle other errors in another way if needed.

    I’ll have to admit that I don’t do this that often so honestly I wouldn’t lose out on that much switching to helix (after it gets proper plugin support and someone makes a decent replacement for the fugitive git plugin) but I would feel less powerful not knowing that I have those tools up my sleave lol.



  • Pair coding with vim is a skill in itself (for the vim user). You can make things a bit easier to follow by making liberal use of visual mode for example. I have a CoworkerMode command that turns on smooth scrolling via vim-smoothie and cursorline, and I’ve also added some stuff to the neovim right-click menu so that I can explicitly right click go to definition for example. It can be worth switching editor sometimes, but it’s not always worth it if you’re in the middle of something.




  • Peak dishwasher is a great concept and I think it highlights something important in the way we think of technology. There’s often this underlying assumption of technological progress, but if we look at a particular area (e.g. dishwashers) we can see that after a burst of initial innovation the progress has basically halted. Many things are like this and I would in fact wager that a large portion of technologies that we use haven’t actually meaningfully developed since the 80s. Computers are obviously a massive exception to this - and there are several more - but I think that we tend to overstate the inevitability of technological progress. One day we might even exhaust the well of smaller and faster computers each year and I wonder how we will continue to view technological progress after that.



  • Personally, the language that’s taught me the most to learn has been Haskell. It has a lot of very interesting ideas and a learning curve that plateaus after most other languages. There are several ideas that have trickled down from Haskell to other parts of the programming world and learning about them in the context Haskell is in my opinion better because you’ll learn about them in a context where they fit in with the rest of the language very well instead of being late additions that offer an alternate way of doing things.

    Coming from Java and JS, Haskell has a very different approach to a lot of things so you’ll have to re-learn a lot before you get productive in it. This can be frustrating for some but you’ll learn more if you get over that hump on the other hand.

    Haskell doesn’t see very much industry use and arguably isn’t very well suited for industrial application (I haven’t used it professionally so I don’t know personally) so it might not directly help you land any new jobs but it is in my opinion it’s a very good way to develop as a programmer.




  • I might be suffering from stockholms syndrome here, but my prefered ways of working with git are the cli and the fugitive vim plugin which is a fairly thin wrapper around the cli. It does take a middle ground approach on hiding the magic and forcing you to learn the magic which I suppose can be confusing for beginners when you work collaboratory and something happens that forces you to go beyond pull/add/commit/push



  • If you just Rc everything (which I’d count as “abusing Rc”) Rust is significantly worse than a language with a good GC. The good thing about Rust is that it forces you to aknowledge and consider the lifetimes of objects. By default things are allocated on the stack, but if you make something global or dynamically handled (e.g. through Rc) you have to do so explicitly. In Rust the compiler has greater compile time information about when things can be freed which means that you need less runtime overhead to check things and if you want to minimize the amount of potentially long-lived objects you can more easily see how long objects might live by reading the code as well as get help by the compiler to determine if a lifetime-based refactoring is sound or not.