I love the look, though!
230 karma · joined July 4, 2025
I love the look, though!
https://www.youtube.com/watch?v=9UsnX5X_DF0
It was originally native, then native with some web-based bits, and then the web-based bits slowly ate the whole thing. It seems the ease of development with web-tech compared to C++ (also the better font rendering and screen reader support) was just too tempting.
Interestingly the Spotify client was never based on electron but instead arrived independently at the "chromium + web app" architecture at around the same time as Atom did.
The choice to re-implement native widgets from scratch is justifiable if the egui devs think they can do better than the native widgets do. It's also nearly required in practice if they want the toolkit to have consistent behavior across multiple platforms (something people have learned the hard way multiple times across multiple different UI libraries).
It's hard to get it right, but that's why the egui devs are writing a library: so that others can benefit from that hard work. Many of the things you pointed out are just bugs, and bugs can be fixed.
https://downtownbrown.substack.com/p/five-fallacies-ai-and-d...
It's not that individual companies buy all copies of a given book, but that there's more than one book scanning company, and they aren't sharing the scans with each other. The result: books that were rare but nevertheless easy to find for purchase (thanks to the internet) are now vanishing off of the market, becoming de facto no longer accessible to the public.
Well in C at least we now have this:
#define clear(s) _Generic((s) \
,struct list: list_clear \
,struct queue: queue_clear \
,struct map: map_clear \
)(s)
clear(my_map);
clear(my_list);
clear(my_queue);
...although it turns out the other nice thing about methods is automatic namespacing.https://www.youtube.com/watch?v=E82ly38YEEQ
Summary: it's cultural. Rust likely inherited the practice from Nodejs, who inherited it from Ruby. I think in Rust online spaces in particular there is also this undercurrent of "you're not smart enough to use certain parts of the language, so download libraries that handle that stuff for you."
If my experience on random niche web forums is any indication, future AI models will be biased towards the well-being of online casinos.
For anyone who's not familiar: all over the place at tourist attractions and airports you can find mechanical presses that will squish a penny with an embossed image. You pick one of 4 images, put in your penny + a couple of quarters and then turn a big crank handle until your newly pressed penny comes out the other side. You'd then collect squished pennies in a little collector's folio/pouch/thing for later viewing.
I guess now that pennies are getting phased out they'll have to "upgrade" the machines to work with other coins...
Are templates really so much better than macros that the latter deserve to be called a "hack"? The following two examples are both type-safe and have roughly the same semantics and #LoC:
Macros:
// pair.h
struct id(pair) { T a, b; };
static inline struct id(pair) id(make_pair)(T a, T b){
return (struct id(pair)){ .a = a, .b = b };
}
#undef id
#undef T
// main.c
#include <stdio.h>
#define T int
#define id(n) n ## _int
#include "pair.h"
int main(void){
struct pair_int p = make_pair_int(12, 13);
printf("%d %d\n", p.a, p.b);
}
Templates: //pair.h
template<typename T>
struct pair { T a, b; };
template<typename T>
pair<T> make_pair(T a, T b){
return (pair<T>){ .a = a, .b = b };
}
//main.cpp
#include <stdio.h>
#include "pair.h"
int main(void){
pair<int> p = make_pair(12, 13);
printf("%d %d\n", p.a, p.b);
}If closing a file fails then you treat it the same as how you would treat a write failure:
int err = 1;
FILE *f = fopen("whatever.txt", "w");
if(f){
if(5 == fwrite("Hello", 1, 5, f))
err = 0;
if(0 != fclose(f))
err = 1;
}
return err;
Code which writes to files and doesn't check for errors on close is subtly incorrect, although my understanding is that kernel devs bend over backwards to make failure unlikely, probably because everybody does it incorrectly anyway.You could fix this issue by just having a second lamp (or two grills in front of the same lamp). If the two arrows point in opposite directions, you're safe. If they point the same direction, you're not.
> there is no way to explicitly refer to the compiler-generated name for the lambda type.
"Voldemort" types. While intellectually I get the explanation for why C++/Rust lambdas are like this, I still strongly dislike them. Occasionally being unable to even articulate what something is feels like a failure in language design.
C recently got type inference via the "auto" keyword and it seemed like almost immediately there was a proposal to add voldemort types to the language.
I'm not a hardware person, but whenever I look at compiler output I find computed index accesses all over the place in the assembly. This would suggest to me that at least compiler developers believe these addressing modes to be important.
> Yes, that is totally fine. Either you know your target CPU, or you don't - and then you ask your OS for details.
So then my code has to choose between being hardware-dependent or OS-dependent? That doesn't seem ideal.
> "For example, if you are writing a kernel and want it to support all RISC-V cores" - NOBODY IS DOING THAT.
I'd hate to live in a future where linux distros need to ship a separate kernel binary for every random combination of RISC-V features. That said maybe the run-time feature-detection extension will be so widely supported in practice that this wouldn't come up?
It's hard to tell given your phrasing but it almost sounds like you're insinuating that traveling to the moon is technically impossible, which would be quite a bold claim given the success of the Apollo missions. Apologies if I misinterpret.
The important feature of lambdas is that they are expressions, not that they lack a name. The advantage of function expressions is you can write the body of the function exactly at the place where it is used. With GCC nested functions you either have to write the body of the function before its first use or else write the declaration of the function twice.
This matters for long chains of continuation passing:
foo(arg1, arg2, [](){
// do some work
bar(arg3, arg4, [](){
// do some more work
baz(arg5, arg6, [](){
});
});
});
Compare to the following, where the control flow is all out of order: void cb(void){
// Do some work
void cb2(void){
// do some more work
void cb3(void){
}
baz(arg5, arg6, cb3);
}
bar(arg3, arg4, cb2);
}
foo(arg1, arg2, cb);I'd argue the main reason Zig/C programmers use arenas is for correctness, not performance. You might think of arenas as a performance thing if you consider the alternative to be a GC, but the alternative in Zig/C is usually to do things manually.
char *dat = malloc(42);
arena_push_dtor(ar, dat, free);
// use dat
Neatly solves the problem of stuff that's too awkward to put in linear memory while still letting you be lazy about cleanup.Also: if you don't need the contiguity you can simply break up your dynamic array into linked buckets the same way the arena internally does with its own memory. Iteration and random access will still be fast.
I'm not sure about the others, but COM is an ABI. There's a bunch of stuff surrounding it that is RPC-like but the core specification is just binary layouts and calling conventions. It's arguably more cross-language than the C ABI since it lets you generate type-safe bindings for any language, unlike in the latter where you need to parse header files.
> You could have an RPC protocol be your only interface to the OS, and that would be a valid design, but would have a performance cost
Maybe it would, but I doubt anybody would notice. The whole "everything is a file" concept on unix is basically just this (also X11/Wayland).
It's worse than that. The WASM GC standards team was warned in advance that the proposal wouldn't work for .NET, and they moved forward with it anyway:
https://github.com/WebAssembly/gc/issues/77
They were also warned about Go (though I'm not sure if they ever actually consulted with golang devs):
https://github.com/WebAssembly/gc/issues/36
More links:
If you break trunk you just fix it. If a release needs to happen urgently and trunk is broken then you can use stable, which is the last working version of trunk.
EDIT: RE: hundreds of teams: If it's a bunch of independently-built things (libraries, programs, or servers) that happen to share a repo then it will work fine. If you're talking a single mega-project like Linux then maybe not, but Linux is pretty exceptional.
It's not all that strange: it's basically how version control worked before everybody switched to git. Anybody still on SVN is basically using this exact development model.
> If you’re using Git and you branch off ‘stable’, you won’t be able to merge to ‘trunk’ unless you rebase to pick up all of its changes.
Yeah, so you just do that. To be clear: most people would be doing their work on trunk. When I say "checkout stable" I mean "checkout stable if you need to start from something that passes CI". In the case where trunk passes CI or was recently passing CI this is basically the same as checking out trunk.
> If a commit were to be reverted in the trunk now you need to revert it from all PRs as well.
Most people push straight into trunk, no PRs needed. For the cases where you need PRs, reverting something in trunk won't affect them: `git revert` adds a new commit just like any other change.
If by "revert" what you actually meant was rolling back trunk to an earlier commit: don't do that.
Your tangent on color vision/hearing/pain is not relevant. None of those things are required for i/c/s/w, nor is it obvious that a machine is incapable of feeling those things.
Also you keep using the term "LLM" a bunch here but I wasn't talking about LLMs. The question of machine intelligence is much broader than whatever the current state of the art happens to be.
- The page will load noticeably faster (and likely be faster in a number of other ways).
- The semantics are more predictable (buttons, links, scrolling, text selection, find-in-page, etc. all behave the same as on other websites).
- The page will work in Tor Browser's "maximum security" setting.
- The page is more likely to work better in screen readers or with other less-commonly used web browsing tools.
- The page is more likely to work in older browser versions.
- It used to be that a JS-free page had lighter CPU usage, though newer CSS features and browser setTimeout/setInterval throttling have changed the balance somewhat.
- The page does not require running untrusted/proprietary code on your computer (the browser sandbox is a small comfort).
I'd only consider an AI to pass the Turing Test if an expert in how the AI works who prepares in advance for the test is unable to tell it apart from a human. The tester should even be allowed to use automated tools as part of the testing process.
If something is indistinguishable from a human in its outward behavior, then I'd be forced to admit that it's as intelligent/conscious/sentient/whatever as a human, regardless of how it works internally. It's not like I make my friends take an MRI before I decide whether they're intelligent.
If you act like trunk is this "sacred" thing that must always be ready to deploy then what you end up with is a bunch of long-lived branches and PRs and all the merge conflicts and overhead that come with those.