Habits I've developed for fast and efficient programming
cprimozic.net
cprimozic.net
For 2 I'd like to give you the example of Grafana. To get it up and running all you have to do is install an RPM and start the service. That's it, you can immediately start playing around with the software. The out-of-the-box configuration is fine for 90% of the use cases. Upgrades are equally smooth as well, everything is done for you. Just install the newer version and restart the service. Database is upgraded automatically. By default an SQLite database is used to store everything, but if for some reason that becomes a bottleneck you can upgrade to MySQL, at which point also some more advanced skills are needed. But that's kind of the point I'm trying to make, it works well OOTB but can be tailored to fit outside of its default configuration.
I've grown to loathe software where much manual setup is needed. Creating databases, importing the schema and bootstrap data, going over a myriad of configuration options because the defaults don't work OOTB, having to configure things that could easily be auto detected by code, requiring dependencies that are not available on your distro, moving files around and setting permissions yourself... All feels needlessly complex, isn't the computer supposed to work _for me_?
Over time I've started to feel that the OOTB experience is directly proportional to the quality of the software. Using tools that just straight up work and drop those that require intensive tinkering to get going has definitely improved my work experience.
Couple all this together you get incredibly productive out of the box experience that is very easy to onboard new team-members onto. Pairing with this setup is also great, Code With Me is constantly getting better (pairing tool built into IDEA), being able to teach newbies keyboard shortcuts in IDEA to make them more productive etc.
I think the latter stuff is probably more important to me now as I mostly take on lead roles, my own productivity has always been high but being able to make that more scalable has been immensely more valuable.
Then something happened, I'm not sure what. Maybe I just got old but I no longer derived value from it being -my- setup. I just wanted whatever got the job done most efficiently.
These days I'm ultra boring. I run macOS everywhere, I still use zsh and a fairly pimped shell, but minimal vimrc and IDEA has replaced the vast majority of my dev environment. It doesn't have any of the personality it once did and tbh that doesn't bother me in the slightest.
I began to loathe complicated config files that require reading manuals to figure out how they work. Examples: SystemD, NixOS, Bazel, and BCL/GCL. Even worse are tools that silently ignore errors in config files. Examples: Gulp, ESLint, and nearly every other tool written in JavaScript.
Now I use a single machine with macOS and leave nearly every setting at the default. I don't even use Brew. I prefer to use tools that come with their own installers and updaters.
I think this change happened when I finally found work that difficult for me and took all of my energy. I had no energy left over to waste on sysadmin work.
Also, my brain began to fill up with knowledge of systems programming, languages, and libraries. Recalling details of random config files takes more effort than before.
I think my brain has a hierarchical memory system with four types of long-term memory:
0. Knowledge available instantly
1. Knowledge retrievable with 2-3 seconds of concentration
2. Knowledge that is unavailable upon request, but usually pops into mind 1-2 minutes later.
3. Knowledge that I can retrieve only with an associated memory or idea.
When I was a teenager, my technical knowledge fit into my tier 0 memory. Then I earned a degree and worked some years and my knowledge grew to fill tiers 0 & 1 and some has been relegated to tiers 2 and 3.
I take and keep many photos because I can use them years later to retrieve forgotten memories. Maybe I will start taking screenshots of my computer to use in a similar way.
With most of my projects, I have a couple of scripts to take care of the tasks relevant to that project. When I start something new, I just copy them over from a similar project and edit where needed. Super light weight, and basically will work until the end of time.
For work sometimes I need to adopt someone’s highly tooled workflow, and then you have to get the editor license, find the right plugins, make sure you’re on the same version and so on. And sometimes you dust off an old project and something broke in this big magical dependency chain and you have to do surgery to figure out what it is.
I am very annoyed with JB for keeping customers stuck working in molasses. Changing from JBR 11 to Azul Zulu 15 puts the "Jet" back in JetBrains!
Until recently I've been very happy with Scala support in IntelliJ. Stuff just works or at least works for Scala 2.12 and 2.13
I tried to kick tires with Scala 3 and well it is not ready (warnings about experimental support).
Worst of all Intellij is not actually compiling Scala 3.1 but 2.13.6 still. (despite build.sbt having scalaVersion := "3.1.0")
You start messing around with manually adding and removing jars and you are in for a bad time.
Dealing with setup just saps productivity especially if you have to work on other languages.
First bad experience with Scala and Intellij.
I'm used to TypeScript mostly.
My gut reaction used to be similar due to bad experience with it in university but now I realise I was just ignorant.
When I want to use Go, Rust or Node I just go to the website and download it. When I want to do anything with Java I first have to agree to a license agreement.
Then the whole thing of working with Kotlin and Maven just feels off (I tried). Like people working in those languages work under a completely different paradigm from me.
Then you have portable applications. If I want to run on many architectures and platforms the JVM allows me to do this easily, no need to worry about cross compilation or even multiple binary distributions.
So yeah. Is it always necessary if you are always going to target the same platform as your dev environment and never load code dynamically? Probably not. Is the tradeoff (higher memory usage) generally worth it? I think so. Not for all cases, for these I do think you have to go with a compiled language with better memory usage characteristics but that is about it tbh.
Previously the JVM also sort of sucked at latency sensitive workloads unless you were very careful not to upset the garbage collector. This is now a non-issue. ZGC and Shenandoah outclass the best latency optimised collectors in languages like Golang.
So really that only downside remaining is memory overhead, I don't actually think that one can be eliminated - it's likely to remain the "can I use JVM for this or not" lynchpin for the foreseeable future. (ignoring things like GraalVM native images because I don't know enough about them to speculate on if it can substantially lower memory usage)
At some point in the future, this might be solved neatly in a standards-based way with native WASM support
The "write once run anywhere" concept is still very useful, when required.
The only advantage of a VM is that the actual executable artifact is platform agnostic.
We compile some C libraries and use them via JNA. It takes time to create the cross-compilation environment with all the correct versions of the libraries they depend on (and the libraries that those libraries depend on).
In comparison, if a library works on Java version x, we can include it and debug it running on the JVM as necessary.
What are the alternatives you prefer to use?
Go compiles to a static binary, has great cross-compilation tooling, and provides a runtime with memory safety. But many programmers find Go's abstraction capabilities too primitive.
GraalVM provides an AOT compiler for Java [1]. In practice, this has proven to be a niche usecase [2].
If I had to guess the author's background, based on the article, I would assume that he/she has a corporate background and very little experience building systems from scratch end-to-end. It's only when you start building systems from scratch 'end-to-end' that you actually learn what is important in programming. Sadly, developers typically cannot get this experience while working for a corporation. Most corporations are too compartmentalized to allow individual employees to see how everything fits together into the big picture of software development.
Unfortunately, because of their high profile, corporate developers get a lot more attention in the industry even though they often have tunnel vision.
First, learn the basics of the trade: reading and writing code efficiently and painlessly... then you can think about high level architecture or whatever makes you feel more important. I see a lot of people who think they know the former but they can't even find a definition without clicking through some GUI menus, which takes 10x more time than if they'd just learned a couple of shortcuts. This is what is really going to compound over time, as you do this hundreds of times a day.
Besides, the author addressed your criticism in the second paragraph: _There's a lot more than just writing code that goes into being an effective software developer..._
I took, and still sometimes take, a part in discussions of adapting or improving autoformatting for some language we use.
It is incredible to think about programmers who have/will grow up entirely with autoformatters in all their tools. To them, the idea of manually formatting their code will seem as “ancient” and “backwards” as assembly programming feels to me. That’s a hallmark of true technological progress right there.
Heck, if we're talking language-based tooling, I'd rate the influence of JavaDoc higher.
Unfortunately, I rarely was able to make this work in my setups, except long time ago when I used Visual Basic. Then I worked with C++, mostly game development using SDL. The last couple of years I wrote Python, mostly for machine learning with Theano and then TensorFlow.
The startup time of an initial prototype might still be fast enough (couple of seconds) that you don't care too much and you are still productive. But as complexity adds up, and you add other slowdowns like slow NFS or whatever, this can reach minutes, and this already is annoying. But most development I do would probably not really allow for hot reloading, or I don't really know a good way. This is anyway not really common practice for Python, and whatever you try in that direction will probably be unstable and/or non-Pythonic.
And then, you have deep learning research itself, where your feedback loop is at minimum one day, but often more like a week.
I remember that I saw screencast of notch developing on some games, where he intensively used hot code reloading on some functions which defined the behavior or look of some game entities. This looked like an extremely productive and powerful tool. Just within half a second or so, he saw the result of his code change. He just played a lot around until the behavior was nice.
It makes reading easier and writing faster. And no more time wasted on pointless formatting debates.
> And no more time wasted on pointless formatting debates.
There will always be pointless debates: Naming variables, deciding which linters to enable, using reduce() vs. a loop, classes vs functions and so on. This is a cultural problem which occur because you're not focusing enough on the things that actually matter ("is the code correct?"; "can we safely ship this to production?"; "what's the long-term effect of introducing this abstraction/feature/capability?").
I love thinking about code as art, and I have numerous side projects which explores this, but when it comes to shipping real features on a deadline we need to create something which works, not something which evokes a good feeling inside me when reading the code.
I don't know, ask them? We here are on board with using them. ;)
I've met such problematic people. You can't reason with them, it's almost a religion.
But when you sell standardized tooling to your manager plus emphasize how this will reduce internal team friction, you can elegantly eliminate them from the equation.
I did it before and I plan on doing it again. We are here to write code and be productive, not to discuss aesthetics.
On Windows this is built in: Win+1 switches to the first app on the taskbar. On Mac I use Snap -- https://apps.apple.com/us/app/snap/id418073146?mt=12.
>If men learn this, it will implant forgetfulness in their souls. They will cease to exercise memory because they rely on that which is written, calling things to remembrance no longer from within themselves, but by means of external marks.
Both his point about writing and your point about Copilot are likely true in part or in whole. Ultimately it doesn't matter — the technology is here to stay and its adoption will be determined by the utility it provides its user.
Many studies show writing things down (on a paper medium, not phones or any electronics however) is very helpful for gaining focus and regaining productivity. We're not storage media; our brains are immensely creative machines but our memory preservation is inferior so we found a good workaround.
If you bank on your brain being the better autocompleter, I got very bad short to mid term news for you.
Many people have more pattern-forming brains than I do -- everyone notices before me when something has happened two weeks in a row or something they expected to happen didn't happen. My brain just doesn't try to predict.
thinking is auto completing by your brain. You don't create thoughts. It appears automatically. Sam Harris explains it perfectly.
There are people who talk to find out what they think, and those who must think before they can talk. You sound like the first type telling the second everyone is that way.
The sentence you just wrote, it came to your mind automatically. The thought appeared. You think you created it. But did you had any other choice? Could you have refused to not have that thought come to your mind? No right. That's the whole point. The thouths keeps coming in your mind. You can choose to ignore some and focus on some. But the brain keeps generating it. Mostly based on the environment and information you are consuming.
I would recomend taking a few minutes and watching the video. I an happy to engage in a healthy debate once you watched it. He explains it much better than I do. If you have ever heard Sam Harris talking you know for sure that he is not someone who keeps saying out whatever comes to his mind. Also he is a nueroscientist.
By autocomplete I was talking in the context of how GitHub copilot works. It doesn't merely recomend code snippets. It modifies the snippet according to context and all like human brain.
This lets me stay focused on the actual problem I'm solving; the higher level problem. My job as programmer is not an autocompleter -- if it was I'd be doing something else.
I think your hypothesis is valid, but when comparing the impact of IDE autocomplete on my experience, it seems unlikely. We'd have to try copilot to be sure though. Note I think the situation is different for beginner developers and professional developers.
It doesn't require that much practise either, a month of solid practise, 30 minutes a day will get you over the hump easily.
I would recommend getting a full size keyboard for this instead of the cramped, flat garbage of a laptop. Decent keyboards can be had at charity shops for a dollar.
People continually want to attribute this to some rational design consideration, but it’s just post-hoc reasoning. If vin were authored 10 years later it would use arrow keys and there’s no reason to stick with this terrible UX.
Also, if their experience is supposed to be indicative, HJKL should be replaced by WASD which is apparently much more efficient.
Have a deterministic work environment that can be set up and torn down in a single command.
Use standard names in build tool configurations (buildtool clean, buildtool lint, buildtool build, buildtool test, buildtool run, etc).
Set up your project such that there are only 6 steps to getting everything working:
- Commands to download
- Commands to install required support items that can't be automated
- Single command to install everything that's needed in the right places / start your deterministic work env
- Single command to build the project
- Single command to run the tests
- Single command to run the live app
Default to running all of one thing, with options to run a subset (i.e. run ALL tests if not specified otherwise).
Be an adequate typist (40wpm or so). If you're doing software development right you'll be spending around 10% of your development time typing, so after a point typing speed won't help you anymore.
Know how to use your debugger. There are some problems that are simply easier to solve with a debugger than by other means.
Know when to use what debugging technique.
Set things up such that everything gets autoformatted automatically.
I guess you mean JavaScript?
In regards to speed, I really really recommend Vim. Macros are sorely missing in a lot of editors, and they are really a great way to skip a huge amount of repetitive work.
For fun, I did that same example with multiple cursors + vs code: https://www.youtube.com/watch?v=H1uvNbtqJGk
First thing I do on a new installation of IntelliJ or VSCode: remove the stupid tabs.
EDIT: emacs doesn't have tabs, obviously as it doesn't need them, but some crazies have been pushing to make the tabs package installed AND active by default so newbies can feel more familiar with it... that's incredibly backwards: newbies should learn to not rely on inferior methods of file navigation and use the appropriate tools for the jobs, as a recent-files-switcher that's present in every editor I know... in emacs do this:
(require 'recentf)
(recentf-mode 1)
and bind `'recentf-open-files` to some shortcut.I've found it really hard to persuade some people that these things are really critical, even though it seems almost so obvious that it's hard to know how to explain it.
Like, how would you persuade someone that they should comment their code.. or use descriptive variable names?
I'm a really big fan of it; it unironically feels like a bona fide AI assistant.
Working for yourself? Rat race Working for others? Rat race
The human reward system works in a way that doing something repetitive, that is just novel enough and just challenging enough makes us feel great.
There's no such thing as a non rate-race life. The point is enjoying it. Otherwise you end up feeling dread and existential anxiety.
Life is meaningless, and at the same it's meaningful. It truly depends on your perspective, and a bit of self delusion.
There is. If you never met a Buddhist monk, I highly recommend to.
I enjoy the monetary reward but also the act of solving hard problems every day.
It is perfectly fine.