Basically, folks nowadays think that this article[1] was aspirational rather than a cautionary tale.
HN user
gnuvince
Separately; Sam's belief that "AI has to be democratized; power cannot be too concentrated." rings incredibly hollow. OpenAI has abandoned its open source roots. It is concentrating wealth - and thus power - into fewer hands. Not more.
We should call it what it really is: oligapolization of intellectual work. The capital barrier to enter this market is too high and there can be no credible open source option to prevent a handful of companies from controlling a monster share of intellectual work in the short and medium term. Yet our profession just keeps rushing head first into this one-way door.
Just look at the code. How could it be simpler?
Cannot tell if this is a joke.
I like the more robotic "Objects: 1" or "Objects: 2", since it avoids the pluralization problems entirely (e.g., in French 0 is singular, but in English it's plural; some words have special when pluralized, such as child -> children or attorney general -> attorneys general). And related to this article, it's more greppable/awkable, e.g. `awk /^Objects:/ && $2 > 10`.
I went to Blackbox because its UI elements were smaller (title bars are more narrow, no 64x64 dock icons) which gave me more real estate on my 1024x768 monitor. I then migrated to Openbox because that had more active development at the time.
This year, I've switched to herbstluftwm, a tiling window manager that's really nice and works in a way that agrees with me.
Back in 1998-1999, I was interested in installing and using Linux in large part because I thought that the screenshots of Window Maker that I saw online were so damn pretty. When I finally got to use it, I liked how "solid" it felt; the menus were big and large, they stuck to the screen even if you moved your mouse off of them, etc. I don't use Window Maker anymore, but it'll forever hold a special place in my heart.
I get a progress bar when I run `cargo clean` because it's so large.
I need to find a pithy way to express "we use a garbage collector to avoid doing manual memory management because that'd require too much effort; but since the GC causes performance problems in production, we have spent more effort and energy working around those issues and creating bespoke tooling to mitigate them than the manual memory management we were trying to avoid in the first place would've required."
Is there a reason to prefer `while read; ...;done` over find's -exec or piping into xargs?
Probably because some terminals interpret Ctrl+S as a "pause the terminal" command and if you don't know about it, it looks like your editor has frozen.
I absolutely loved AntennaPod back when I had an Android phone -- I actually never really "attended" to it though: I installed it, it worked, never gave me any issue. Now that I own an iPhone, I really miss having a quality app like AntennaPod.
I'm mostly not following what is under a DDoS attack. Is it their web page mostly consisting of marketing material with static pages?
Yes.
Your mention of a "universal API" reminded me of the paper "Some Were Meant for C" [1] in which the author argues that one of the most important feature of C is its "communicative design", i.e., its ability to manipulate any memory -- whether this memory originates from the program or is foreign -- with the usual C operators (+, *, [], <<, >>, etc.)
[1] https://www.humprog.org/~stephen//research/papers/kell17some...
Isn't that our entire industry though?
- I use Emacs every day as my primary (and only) programming text editor.
- Having nearly 20 years of experience using Emacs, it's just a totally natural fit for me.
- I program primarily in Rust. I use the built-in LSP client, eglot, to communicate with rust-analyzer and have IDE features such as jump-to-def, find-refs, find-impls, auto-import, auto-format, semantic rename, etc. It works just as well as VSCode/Codium (which I tried for about a week to make sure I wasn't missing out; I wasn't.) I also do the odd shell script, Python script, YAML config, Dockerfile, etc. for which Emacs is also well-suited.
- As far as I know, I'm the only person in the company using Emacs. There's a few vim/neovim users, but the vast majority of people are using VSCode. Having paired with many, I don't think that I'm slower for using Emacs; in fact, I think that I am in many cases faster because I am so familiar with the text operations that I don't even think about them, I just do them.
- Overall, I don't see any reason for me to switch away from Emacs at the moment, especially since LSP really blurred the distinction between "text editor" and "IDE".
- I typically don't recommend that programmers try Emacs if they're not already familiar with it. Partly because I don't want them to ask me questions, but mostly because their natural tendency is to try and reproduce their VSCode/JetBrains/Visual Studio workflow. This usually causes frustration, because the way to use Emacs effectively is different from the way to use a product like VSCode that aims to have a good out-of-the-box experience.
Sorry, yes I did.
I've been calling the thinking of the parent "trickle-down devonomics": that by making the code better for the user, the benefits will trickle down to the users. Obviously, as the name suggests, that never happens. Devs get the quality of life and users end up paying for our disregard.
The side effect: some people remarked that the code looked like C
Did you understand this comment to be positive or negative?
Somewhere, somewhen, we, as software developers, started thinking that other programmers would rather extend code rather than modify it. This has led us to write code that tries to predict the use cases of future programmers and to pre-emptively include mechanisms for them to use or extend our code. And because it has seeped so deeply into our culture, if we don't do this -- engage in this theater -- we get called out for not being good software engineers.
Of course, the extra hooks we put in to allow re-use and extensibility usually results in code that is slower and more complex than the simple thing. Worse, very often, when a customer needs a new feature, the current extension hooks did not predict this use case and are useless, and so the code has to be modified anyway, but now it's made 10x more difficult because of the extra complexity and because we feel that we have to respect the original design and not rip out all the complexity.
I like Knuth's quote [1] on this subject:
I also must confess to a strong bias against the fashion for reusable code. To me, “re-editable code” is much, much better than an untouchable black box or toolkit. I could go on and on about this. If you’re totally convinced that reusable code is wonderful, I probably won’t be able to sway you anyway, but you’ll never convince me that reusable code isn’t mostly a menace.
[1] https://blog.jj5.net/blog/2021/05/21/knuth-on-reusable-code/
I like this video because there's a lot of a good actionable advice before he gets into SIMD code.
*Sokoban
Select the line, then type
C-u M-| jq -c sortEglot is the built-in LSP client. You need an external server. If you do C or C++, clangd is likely what you want. Install it (apt install clangd) and enable eglot for C or C++ files in your Emacs config, (add-hook 'c-mode-hook 'eglot-ensure).
There are many new languages that describe themselves as taking C, adding some good stuff (slices, defer), removing some of the bad stuff (textual includes) and adding some of their own spice. One might have the right mix of features for you: Zig, Odin, C3, Hare, Jai.
What's the difference between PHP giving "2" as the result of 1 + "1" and Python giving "999" as the result of "9" * 3?
I don’t accept that it’s wholly incompatible with OO
It's not incompatible with the mechanics of OO, but it does require that programmers change how they approach problems. For instance, a common way to write code in an OO language is to focus solely on the thing you want to think about (a user, a blog post, a money transaction, what have you) and to implement it in isolation of everything else, to hide all of its data, and then to think about what methods need to be exposed to be useful to other parts of the system. The idea of encapsulation is quite strong.
In DOD, it is more common for data related to different domains to be accessible and let the subsystems pick and choose what they need to do their work. Nothing about Java or Ruby would prevent this, but programmers definitely have mental barriers.
Avoid matching Option and Result
It's nice to use the ? operator, but if you also want to include logging/metrics, I really recommend using `match` to make it clear what each branch does.
Embrace the newtype pattern
A nice pattern for certain use cases, but often abused by programmers. Out of the box, a newtype is less useful than the type it wraps, because it has none of the underlying type's methods. This results in either having a ton of boiler-plate code that just does `self.0.underlying_method()` or in programmers making the wrapped value public, which defeats the purpose.
"Embrace" to me means "use it when possible", but my experience says that it should be like spice, a little bit can improve the dish, but too much can ruin it.
Consider using iterator transforms instead of explicit loops
Similar comment to the point about avoiding matches for Option and Result. For simple use cases, a .map() or .filter() can be good and easy to read, but I've also seen monstrosities with .skip(), .filter_map(), .chunks(), etc. that become a lot harder to decipher than the equivalent for-loop. We also tend to try and write those in an FP style with no side effects, and sometimes that can discourage people from including logs and metrics in places where they would be useful because they would tarnish the purity of the code.
Whatsmore, in Rust closures are more finicky than in GC'ed languages like OCaml or F#, and some iterator methods take their closure parameters by ownership, others borrow, and it's very often an unnecessary mental burden.
Don't panic
Good idea in general, but panicking is a great tool when the program is in a state that was not predicted by the programmer or cannot be recovered from. "In general, avoid panicking" would be better advice.
Minimize visibility
It's been accepted since the advent of OOP that we should aim to minimize the visibility of the data in our structures. Every Java IDE defaults to making fields private and auto-generating getters and setters. But more often than not, when programmers hide all the internal details, they limit what other programmers. Yes, other programmers could use the API wrong and create bugs in their programs, but they could also use it in ways that the original programmer could not have anticipated and make something amazing out of it.
And when other programmers complain that they are limited in what they can do, the answer is always "we'll add more stuff (traits, plugins, closure parameters, etc.) to help you do more", increasing the complexity of the code.
Listen to Clippy
Some of the warnings from clippy are good (e.g., when it reminds you to use .unwrap_or_else() instead of .unwrap_or()), but a lot of the lints are opinions made into code, and people view you very suspiciously if you disable any of them, which drives the general style of Rust toward the style of the people who successfully argued for their opinions to be part of clippy.
For example, I like putting return statements in my code; yes clippy, I know that the value of a block is the value of its last expression and thus it's unnecessary to put the return, but I want to make it more explicit that we are exiting the function here, why are you complaining about that?
Bravo!
I disagree with many of these: I've enough experience writing, reading, and maintaining Rust code to know that some of these sound good in theory, but are harmful in practice.
Recently, I've started using phpbb (with a docker-compose setup from Bitnami) for keeping personal notes. I find that it works better than pretty much everything I've used before. I like that when I reply to a thread to add an update, that post raises to the top, so it's harder to lose items.