Armenia is perfectly safe as well and everyone speaks Russian there.
Armenia is perfectly safe as well and everyone speaks Russian there.
145 megs is a lot NGL. You used to be able to do all those tasks (sans the autocomplete) on a PC with 64 megs of ram.


thiserror helps a bit with conciseness. But it’s still the most annoying part of writing Rust for me, even more annoying than async closure capture semantics, and one that I happily offload to deepseek whenever I have to write it. I was even thinking of making some insane proc_macro that would traverse a function and extract the list of all ?, deduce the types, and come up with the final error type (maybe with some hints). But this turned out to be too difficult for a weekend project and ain’t nobody wants to pay me to write it.
Type-safe: can’t beat errors as enum values wrapped in Result.
I’m talking more about the anyhow-style here. It’s not very type-safe.
Composable: i don’t think you can beat rust enums in composability.
Well, thiserror-style enums are composable-ish, but they can be too structured for their own good. Sometimes you want only a particular property of an error (e.g. one of the HTTP requests returned 429 or something), and don’t care about the particular branch of the call tree it came from. Rust doesn’t really have the compile-time flexibility to write such a check without a ton of boilerplate that will also break once the call tree changes.


I am well aware, I wrote quite a lot of Rust, including professionally. I’m not necessarily talking about the “clear happy path”, even though that is relatively nice to have (Rust sort-of allows that with the ? sugar and the pseudo-functor and pseudo-monad methods on wrappers); I’m talking more about the fine line between the overly verbose lists of all the errors that a function could produce (thiserror-style) or just a single messy error type that makes error handling difficult (anyhow-style). There surely must be something in between there that is concise, type-safe, and composable, but I haven’t seen it in any language yet.
Rust does not have exceptions. You never have to try/catch. Functions usually encode the possible failures in their types, so you’d have something like this C++ snippet:
struct HttpError {
std::string message;
int responseCode;
}
struct FsError {
std::string message;
}
typedef std::variant<HttpError, IoError> FileDownloadError;
std::variant<std::filesystem::path, FileDownloadError> downloadFile(std::string url) { /* ... */ }
And then the caller of downloadFile has to decide what to do if it returns an error:
auto res = std::visit(overloaded {
[](FileDownloadError e) { /* ignore error, or handle it somehow, and return a new path */ },
[](std::filesystem::path p) { return p; }
}, downloadFile(url));
/* res is guaranteed to be a valid std::filesystem::path, you don't have to care about errors from downloadFile anymore */
However, Rust makes this whole thing a lot easier, by providing syntax sugar, and there are helper libraries that reduce the boilerplate. You usually end up with something like
#[derive(Error, Debug)]
enum FileDownloadError {
#[error("HTTP request failed")]
HttpError(http::status::StatusCode),
#[error("Filesystem error: {0}")
FSError(#[from] std::io::Error),
}
fn download_file(String url) -> Result<Path, FileDownloadError> {/* ... */}
(notice the #[from], which forwards the error message etc from the std::io::Error type)
The Result type is kind of like a std::variant with two template arguments, and, mostly by convention, the first one denotes the successful execution, while the second one is the error type. Result has a bunch of methods defined on it that help you with error handling.
Consumer code is something like this:
let res : Path = download_file(url).unwrap_or_else(|e| {
/* Ignore the error or handle it. You have to return a new path here */
});
/* res is guaranteed to be a valid Path, you don't have to care about errors from download_file anymore */
Or
let res : Path = download_file(url)?;
/* res is guaranteed to be a valid Path, you don't have to care about errors from download_file anymore */
Which will just forward the error to your caller (but your function has to return Result as well), or proceed with the execution if the function succeeded.
Finally, download_file(url).unwrap() is if you can neither ignore, nor handle, nor pass the error to the caller. It will abort if the function fails in any way, and there’s no (practical) way to catch that abort.
It’s worse than just exceptions in C++. There’s (almost) no way for the caller of your function to catch it. It’s a bit like this snippet:
std::optional<int> foo = <...>;
try {
return foo.value();
} catch(const std::bad_optional_access& e) {
std::cout << e.what() << std::endl;
abort();
}
It’s the abort that is the crux of the issue here. Usually you would pass the std::optional up/down the call stack. If you don’t control the types (e.g. using a library or a framework) you’d come up with some “default” value instead, like this:
std::optional<int> foo = <...>;
return foo.value_or(123);
Or in Rust:
let foo : Option<i32> = <...>;
return foo.unwrap_or(123);
But sometimes there’s no good “default” value, and then you have to resort to just unwrap-ing the value, and accepting that the entire program will abort when that function call fails. Usually this is a sign of poor engineering somewhere, likely in a library you’re using, and should be fixed; but sometimes you don’t have the time to fix it, and then it ends up in production.
To me it’s more surprising to have parking at a grocery store. In places I lived, it’s usually just on a ground floor of a residential building, and if there’s any parking nearby it’s either for residents only, or a municipal parking spot (which is almost always taken up by residents anyways). Almost nobody specifically drives to buy groceries, you just get what you need on your way home from work/gym/after hanging out with friends. Or, if you need to buy a lot of shit, you use a shopping trolley or something.
And I’d still consider cities like that carcentric hellholes, the american suburbia seems just unfathomably bad for me.
I strongly recommend going on hikes in the mountains, ain’t no car can get there! (this quickly turn into a problem if you break your leg or something, so be careful)
The actual resolution to this conundrum is of course: build more public transit and bicycle infrastructure, ban private cars in cities, replace parking lots with multi-story mixed-use buildings.


Sadly there’s still no truly good way to handle errors in rust. TBH I’m not sure if we as an industry have figured out an efficient, foolproof, composable, not overly verbose way to handle errors, so it’s not entirely on Rust.
BTW this is also the case for most network printers. You can just print to them by sending a pdf/postscript file with netcat. CUPS is rarely needed nowadays.
In my experience:
I think if you have some use-case that Wayland doesn’t fulfill, it’s totally fine to just pin some version of Plasma and stick with it. Maybe even switch to Trinity. Chances are it will keep working for like a decade or more.
I still use kdenlive 18.08, because I know how to use that version, and it does what I need it to do perfectly well. They broke something I needed in 19.whatever (I don’t remember what it was anymore), so I just pinned it and kept using it ever since. Maybe one day I’ll try to figure out the latest version, but there’s no real incentive for me to do so.
Nah, social division of labour is almost as old as civilization itself. It’s not possible to do everything by yourself, if you’re lucky enough not to die of hunger in a few weeks, you’ll die of a preventable disease within a few years.
Capitalist exploitation of it (combined with faux individualism) is the issue.
Translating to this scenario, there would be no issue if we had community kitchens with cheap/free food and well-paid workers. The issue is the capitalists extracting surplus value from a basic necessity, partly by convincing everyone to hate their neighbours and eat alone.
It was used to deliver the comic to you in the first place.
The intended use-case is for bit-banging, i.e. sending electricity to places according to certain algorithms. Think about simple automation, like the control chip in your washing machine which executes the selected program by sending enable/disable signals to the water pump, valves, and the motor. Well, the same basic principles could apply to a lot of industrial processes and such, helping us rebuild the civilization.
It would also be really fucking great for helping post-collapse engineers do various calculations. Those chips are really slow by modern standards, but insanely fast compared to an abacus, a slide rule, and a sheet of paper.
BTW there’s also dusk OS, which follows similar principles but is targeted for more advanced hardware, like the abundant x86 and ARM chips. It has a way more user-friendly interface, a basic GUI, filesystem drivers, and IIRC even networking capabilities, all possible to run on a PC from the early 90s. It also has great bootstrapping flow, allowing you to rebuild itself from source, flash itself to other computers, and flash Collapse OS onto microcontrollers.
Basically like a Linux install with all the dev-tools and sources already there, except much simpler, to the point that you probably can figure out how every component of the system works yourself, and fix issues when they happen. This knowledge will also directly translate into writing programs for collapse OS, because they share the programming language and many OS paradigms.
I like how the rememes of this only get more complicated and less stable with time; hopefully this means the collapse is approaching, or else I’m learning forth for nothing!
I guess we have vastly different expectations from our phones, then. At a minimum, I need to:
And in my experience, Librem5 just doesn’t have enough processing power and RAM to do any of those quickly and reliably. It was not comfortable at all, e.g. the browser kept filling up RAM and locking up the device with constant swapping, and finally OOMing. GPS took 5-10 minutes to get a lock, even with AGPS, and after that wouldn’t reliably keep it. Both Nheko and NeoChat were slow and laggy. It also died after 4-5 hours of suspend with a modem on, unacceptable for a reliable daily.
OnePlus6 is a rocketship in comparison, and performs all those tasks with ease. The battery also lasts for an entire day with conservative suspend settings (but with the modem on), and for a couple days in airplane mode (e.g. while hiking in the mountains).


Yes, but that shouldn’t generally explode the RAM usage by an order of magnitude. In terms of information amount, most of the data that computers handle is an internal binary representation of real-world phenomena (think: videos, pictures, audio, sensor data) and not encoded text.
You can also get away with being queer in Yerevan. Not anywhere else in Armenia sadly.