The early stages of a project is exactly where you should really think hard and long about what exactly you do want to achieve, what qualities you want the software to have, what are the detailed requirements, how you test them, and how the UI should look like. And from that, you derive the architecture.
AI is fucking useless at all of that.
In all complex planned activities, laying the right groundwork and foundations is essential for success. Software engineering is no different. You won’t order a bricklayer apprentice to draw the plan for a new house.
And if your difficulty is in lacking detailed knowledge of a programming language, it might be - depending on the case ! - the best approach to write a first prototype in a language you know well, so that your head is free to think about the concerns listed in paragraph 1.
The average coder is a junior, due to the explosive growth of the field (similar as in some fast-growing nations the average age is very young). Thus what is average is far below what good code is.
On top of that, good code cannot be automatically identified by algorithms. Some very good codebases might look like bad at a superficial level. For example the code base of LMDB is very diffetent from what common style guidelines suggest, but it is actually a masterpiece which is widely used. And vice versa, it is not difficult to make crappy code look pretty.
OMG, this is gold! My neighbor must have wondered why I am laughing so hard…
The “reverse centaur” comment citing Cory Doctorow is so true it hurts - they want that people serve machines and not the other way around. That’s exactly how Amazon’s warehouses work with workers being paced by facory floor robots.
When did you last time decide to buy a car that barely drives?
And another thing, there are some tech companies that operate very short-term, like typical social media start-ups of which about 95% go bust within two years. But a lot of computing is very long term with code bases that are developed over many years.
The world only needs so many shopping list apps - and there exist enough of them that writing one is not profitable.
People seem to think that the development speed of any larger and more complex software depends on the speed the wizards vsn type in code.
Spoiler: This is not the case. Even if a project is a mere 50000 lines long, one is the solo developer, and one has a pretty good or even expert domain knowledge, one spends the mayor part of the time thinking, perhaps looking up documentation, or talking with people, and the key on the keyboard which is most used doesn’t need a Dvorak layout, bevause it is the “delete” key. In fact, you don’t need yo know touch-typing to be a good programmer, what you need is to think clearly and logically and be able to weight many different options by a variety of complex goals.
Which LLMs can’t.
Well, sometimes I think the web is flooded with advertising an spam praising AI. For these companies, it makes perfect sense because billions of dollars has been spent at these companies and they are trying to cash in before the tides might turn.
But do you know what is puzzling (and you do have a point here)? Many posts that defend AI do not engage in logical argumentation but they argue beside the point, appeal to emotions or short-circuited argumentation that “new” always equals “better”, or claiming that AI is useful for coding as long as the code is not complex (compare that to the objection that mathematics is simple as long it is not complex, which is a red herring and a laughable argument). So, many thanks for you pointing out the above points and giving in few words a bunch of examples which underline that one has to think carefully about this topic!
Stumpwm. The most ergonomic tiling window manager I know, fantastic configurability like emacs.
If you like screen or tmux, you might like a tiling window manager like i3 or sway, or GNOME with paperwm extension. It can have real advantages for older folks (like me) which don’t have perfect vision any more, because it is much more conservative with screen space. After a few days learning, it becomes also really fast to switch windows and desktops. This is not black-or-white: The desktop WMs do have keyboard shortcuts and windows layouts which mimick tiling WMs, and tiling WMs may have a few desktop features. The former are a bit more convenient and easy for beginners, while the latter are blazingly fast.
In my experience, dealing with repeated nvidia problems is not worth the hassle. Just replace it with a good AMD graphics card and sell that nvidia thing.
For me, this result is also not too surprising:
If allowing / using Undefined Behavior (UB) would allow for systematically better optimizations, Rust programs would be systematically slower than C or C++ programs, since Rust does not allow UB. But this is not the case. Rather, sometimes Rust programs are faster, and sometimes C/CC++ programs. A good example is the Debian Benchmark Game Comparison.
Now, one could argue that in the cases where C/C++ programs turned out to be faster than Rust programs, that at least im these cases exploiting UB gave an advantage. But, if you examine these programs im the Debian benchmark game (or in other places), this is not the case either. They do not rely on clever compiler optimizations based on assumptioms around UB. Instead, they make heavy use of compiler and SIMD intrinsics, manual vectorization, inline assembly, manual loop unrolling, and in general micro-managing what the CPU does. In fact, these implementations are long and complex and not at all idiomatic C/C++ code.
Thirdly, one could say that while these benchmark examples are not idiomatic C code, one at times needs that specific capability to fall back to things like inline assembly, and that this is a characteristic capability of C snd C++.
Well, Rust supports inline assembly as well, though it is rarely used.
You can legally buy second-market OEM licenses. They are not that expensive, and do not expire. And, older versions of Windows are much slimmer and boot much faster, though it is not a good idea to connect them to the Internet - instead, one would block connections between VM and Internet. Which is anyway much better from a privacy perspective.
Another big plus of that approach: If your laptop or PC breaks, you can just move the VM image with Windows exactly like any other file you have backed up (you do backups, don’t you?) to the new hardware and use it as before. This esoecially breaks the problem of forced OS upgrades if the new hardware does not support the old windows version, or you do not have the installer and license keys any more, but the new Windows version does not support your old documents, media formats, or pheriperals like scanners.
Also, if you modify your Windows install and it might break, you can just make a snapshot of the VM image - which is a copy of a file - and restore it when needed.
Great article, a pleasure to read and a fantastic work of really good science and critical thinking.
A few more thoughts here:
I want to learn / use a functional programming language.
That’s a good idea.
With over 20 years of programming in languages like C, C++, Python, Go, Pascal, Forth and so on, I think functional languages are often easier - in the same way that programming without lots of global variables is usually and objectively better. There are of course a few domains where the OOP approach works better, like defining data structures with tight invariants, Linux hardware drivers, or simulating ships.
Or sometimes, you need a bit of imperative code for a number-crunching core.
But most code can advantageously be represented and structured as:
input -> transformation -> output
and the transformation part, which is almost everything which is really interesting, is where the functional style shines.
Now if you want something beginner-friendly and practical, it depends on what you want to do. Here my ten cents:
For systems programming, signal processing and embedded stuff, I’d totally recommend Rust. It has certainly a bit of Algol syntax but that’s rhe proverbial wolf in sheeps clothing: Many concepts actually come from OCaml, as well as the first Rust compiler. This would also answer the question whether functional languages are relevant and useful in industry.
If you want to do concurrent server-side programming, I believe there is nothing better than Clojure - perhaps with Babashka for scripting and ClojureScript for the Browser. Clojure is also incredibly elegant and concise, and at the same time it can use Java libraries, so it has huge library support, a battery powerhouse included.
If you learn both, you will see that Clojure and Rust have actually a lot in common in their approach to concurrency, which is preventing shared mutable state. It is great to learn both.
If you want a very practical, well-documented, and beginner-friendly language that also has great GUI support, I’d recommend Racket, a Scheme descendant. Like Clojure, it supports gradual typing.
If you want to program close to the Unix/Linux environment and want a simple as well as powerful language, a Scheme version could be a good choice. Personally, I love Guile, and use it where I previously used Python. Guile is very easy to use as a extension library for C and C++ programs or to control low-level code written in C. It also has a quite good REPL and debugger support and thus, interactive experience.
Speaking of Python, it has a great vector library which is heavily influenced by APL and functional designs, named Numpy. A C++ analogon would be Eigen. You see that functional programmers subversively introduce their filth everywhere!!
For data analysis, Scala could be an option. It is like OCaml on the JVM. Similarly, F# for .NET (but who wants to get entangled in Windows?).
If you want to keep it more multi-paradigm, you could chose Common Lisp - it will let you program in many styles and its SBCL implementation probably has the best performance after Rust. But Schemes like Guile or Racket are more geared toward a functional-preferring style. And if you want Lisp with stricter typing, there is Coalton - but I have not tried that last one.
Not HTML but the much simpler Gemini protocol - well you could have a look at Bollux, a Gemini client written im shell, or at ereandel:
https://github.com/kr1sp1n/awesome-gemini?tab=readme-ov-file#terminal