Recent submissions

Comment · 18 days ago
> In an era of extremely accessible and competent language models, you have no excuse not to use one to verify your doctor's (or any hired professional's) work [...] the tools exist and are now ridiculously accessible

Well I certainly have an excuse: at work, code reviews provided by a particular LLM have been a net negative contribution, in my judgement. And then it's not hard to extrapolate that experience to other professions, ones that I myself am not competent in.

The old adage exists where you read the Sunday newspaper, get a nice educative experience from 14 out of the 16 pages, but then 2 pages happen to write about your own profession, and you seethe about the rampant stupidities and mischaracterizations in those 2 pages. But the other 14, about stuff you are not directly familar with, sound good. See the problem?

You got lucky because your doctor was receptive to ideas from sources other than his own brain (LLM or otherwise). Most medical professionals laugh you (or curse you) out of the room, if you attempt to make an informed decision. In fact the most selective search criterion for doctors, as a patient, is willing to talk.

Comment · 18 days ago
> The other knock on lesson that people should internalize is that you, and only you, are ultimately responsible for your own healthcare and maintenance.

Yes and no.

Yes in the sense that it's ultimately you who will get fucked up; you'll be the victim, you're the one punished for the mistakes of others.

And no in the sense that the social contract says different -- otherwise, you'd be responsible for baking your own bread AND manufacturing and fixing your car AND writing your own computer & smartphone programs AND taking care of your health AND educating your children AND cultivating your land and growing your own produce AND so on and on. We have "distribution of work" for a reason; you take the money, you take responsibility. (Except most doctors.)

So, "no", it's not your job, but "yes", you're held accountable for it.

Just because the social contract gets violated left and right, the violations aren't right.

People always emphasize that responsibility and authority should go hand in hand, and this is a prime example where that principle is shown invalid -- it's a human construction and does not hold up in nature. You have no authority to even understand your own health sufficiently, yet you get to bear the consequences.

What you are arguing for is that everyone should judge a professional from a position of lacking education / information. That's precisely what the social contract is not. I'm not saying you are wrong, I'm saying the state of the world is fundamentally wrong; it's way too easy to disclaim responsibility. Someone takes my money, they're on the hook.

People shouldn't trust the social contract, but you can't blame them for trusting it. Most of the time there's no way around trusting it.

Comment · 18 days ago
> This is all professionals. [...] Just take any profession that your retail consumer might get access to and the same spread applies.

The big difference is that if those other professionals fuck up, then the damage is usually done to some object. An object you can get fixed again (by someone else), or replaced, or you can even throw it away perhaps. This doesn't apply to doctors. The damage they can do can be irreversible, the damage is done to your body. This means they should take all the more responsibility. Yet what we see is that they disclaim responsibility to such a huge extent that most of those other professionals can't.

Most doctors have a god complex.

Comment · 1 month ago
(Whether Hungarian qualifies as Finno-Ugric is up for debate, but Hungarian most definitely has determinate and indeterminate articles.)
Comment · 1 month ago
My guess: Czech. :)

Native English speakers living for a decade or more in the Czech Republic (and picking up Czech in the process) may experience "retroactive article confusion", they may start to drop articles while speaking their mother tongue English.

Comment · 4 months ago
> The elegance of the fork() + exec() model is that every kind of configuration can be done after the fork using all the usual APIs.

Unfortunately, the opposite is true, when the parent process is multi-threaded. In the child process, only one thread exists (the thread returning from fork()), but the memory is an exact copy of the parent's. As a result, the child may inherit locks (resident in memory) that are in acquired state, but have no owner threads -- the threads that are responsible for eventually releasing those locks in the child's copy of the process memory do not exist in the child. If the single thread in the child process (returning from fork()) attempts to take such a lock (before exec), it deadlocks. This is why POSIX says that only async-signal-safe functions may be called in a child process, between fork and exec. And then, for example, "malloc" is not such a function (at least per POSIX), so the fork-to-exec environment in the child process is an extremely uncomfortable one. You've got to preallocate everything in the parent, can't report errors to stderr, etc.

https://pubs.opengroup.org/onlinepubs/9799919799/functions/f...

https://pubs.opengroup.org/onlinepubs/9799919799/functions/V...

The fork(2) Linux manual page spells out the sam restriction.

https://man7.org/linux/man-pages/man2/fork.2.html

https://man7.org/linux/man-pages/man7/signal-safety.7.html

"pthread_atfork" exists, but is effectively unusable.

https://pubs.opengroup.org/onlinepubs/9799919799/functions/p...

Comment · 7 months ago
I have no love lost for Wayland, but this:

> Make easy things easy. Make hard things doable.

is generally unachievable. Instead, pick one:

- easy things easy, hard things impossible

- easy things tedious, hard things possible

(Unless you want to maintain two sets of interfaces in parallel.)

Comment · 7 months ago
> It does not matter which is the relationship between the sizes of such types, there will always be values of the operand that cannot be represented in the result.

It's not that bad actually; not "always". The only nontrivial case is when, as a part of the usual arithmetic conversions, you (perhaps unwittingly) convert a signed integer type to an unsigned integer type [*], and the original value was negative.

[*] This can happen in two cases (paraphrasing the standard):

- if the operand that has unsigned integer type has rank greater than or equal to the rank of the signed integer type of the other operand,

- if the operand that has signed integer type has rank greater than or equal to the rank of the unsigned integer type of the other operand, but the signed integer type cannot represent all values of the unsigned integer type.

Examples: (a) "unsigned int" vs. "signed int"; (b) "long signed int" vs. "unsigned int" in a POSIX ILP32 programming environment. Under (a), you get conversion to "unsigned int"; under (b), you get conversion (for both operands) to "long unsigned int".

Section "3.2 Conversions | 3.2.1 Arithmetic operands | 3.2.1.1 Characters, and integers" in the C89 Rationale <https://www.open-std.org/Jtc1/sc22/WG14/www/C89Rationale.pdf> is worth reading. (An updated version of the same section is included in the C99 Rationale <https://www.open-std.org/jtc1/sc22/wg14/www/C99RationaleV5.1...> under 6.3.1.1.)

It deals precisely with the problem highlighted in the blog post. I'll quote just the beginning and the end:

> Since the publication of K&R, a serious divergence has occurred among implementations of C in the evolution of integral promotion rules. Implementations fall into two major camps, which may be characterized as unsigned preserving and value preserving. [...]

> The unsigned preserving rules greatly increase the number of situations where unsigned int confronts signed int to yield a questionably signed result, whereas the value preserving rules minimize such confrontations. Thus, the value preserving rules were considered to be safer for the novice, or unwary, programmer. After much discussion, the Committee decided in favor of value preserving rules, despite the fact that the UNIX C compilers had evolved in the direction of unsigned preserving.

> QUIET CHANGE -- A program that depends upon unsigned preserving arithmetic conversions will behave differently, probably without complaint. This is considered the most serious semantic change made by the Committee to a widespread current practice.

Comment · 7 months ago
Everybody seems to be missing the forest for the trees on this.

There is absolutely no "sign extension" in the C standard (go ahead, search it). "Sign extension" is a feature of some assembly instructions on some architectures, but C has nothing to do with it.

Citing integer promotion from the standard is justified, but it's just one part (perhaps even the smaller part) of the picture. The crucial bit is not quoted in the article: the specification of "Bitwise shift operators". Namely

> The integer promotions are performed on each of the operands. The type of the result is that of the promoted left operand. [...]

> The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are filled with zeros. If E1 has an unsigned type, the value of the result is E1×2^E2, reduced modulo one more than the maximum value representable in the result type. If E1 has a signed type and nonnegative value, and E1×2^E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined.

What happens here is that "base2" (of type uint8_t, which is "unsigned char" in this environment) gets promoted to "int", and then left-shifted by 24 bits. You get undefined behavior because, while "base2" (after promotion) has a signed type ("int") and nonnegative value, E1×2^E2 (i.e., base2 × 2^24) is NOT representable in the result type ("int").

What happens during the conversion to "uint64_t" afterwards is irrelevant; even the particulars of the sign bit of "int", and how you end up with a negative "int" from the shift, are irrelevant; you got your UB right inside the invalid left-shift. How said UB happens to materialize on this particular C implementation may perhaps be explained in terms of sign extension of the underlying ISA -- but do that separately; be absolutely clear about what is what.

The article fails to mention the root cause (violating the rules for the bitwise left-shift operator) and fails to name the key consequence (undefined behavior); instead, it leads with not-a-thing ("sign-extension bug in C"). I'm displeased.

BTW this bug (invalid left shift of a signed integer) is common, sadly.

Comment · 8 months ago
One of the most fascinating and moving writings I've read in my life.
Comment · 8 months ago
Exactly; I can't understand this obsession with header-only C "libraries".

Live from the official Hacker News API

A modern reader for Hacker News · SvelteKit + Skeleton