Hacker Newsnew | past | comments | ask | show | jobs | submit | hyperpape's commentslogin

First sentence:

> In my Ottawa life, every Tuesday evening, I take two gym classes back to back—boxing and the pompously named “body sculpt,” which makes me discover muscles I didn’t know I had.

The em-dash matches how you'd speak out loud.

You'd say "I take two classes every Tuesday back to back, boxing and 'body sculpt'. Weird name." (Parts of that sentence did flow oddly, but not because of the em-dash).

Grammarians say you can't make those separate sentences without adding some extra words, and because of blah-de-blah-blah-blah, someone might say you can't join them with a comma. So we have an em-dash.

Rewriting the sentence would make it flow less naturally, not more.


This is why I find using speech-to-text tools quite difficult to use: because the parts of my brain that I use for writing and the parts of my brain I use for speaking are a little different — although with significant overlap.

With writing I find I'm drafting the flow for readability and clarity as I'm writing, so I go back and rework bits and pieces — sometimes even while I'm in the middle to typing a sentence. Maybe it's because I write code for a living.

Speech only moves forward and you have to state your retractions or clarifications on the go. You can't go back and edit what you've said.

I've been trying to use speech-to-text a bit to: a) give my hands a bit of a break when I'm writing prose, and b) see if it's faster than typing.

I find there are long pauses while I'm struggling to draft what I'm going to say to what I want written, so I'm not sure if it is faster (given that I'm a ten finger touch typist so can type pretty fast is short bursts, and the time spent going back and tidying up the output which is somewhat tedious). It might improve with more practice.

— No tokens were harmed in the production of this comment. —


If I had a nickel for every em-dash I saw that could’ve been a colon…

You'd be full of shit.

Oh, sorry, I thought you said colon…


When I write like I talk, I use a lot of commas. Replacing some of my commas with em dashies, so long as it was done judiciously, would probably make things easier to chunk.

I’ve seen people use colons where em dashes are effective. I use em dashes. AI leans heavily on them for same reason

It’s become the exclamation mark of mid-sentence punctuation. It connotes fragmented or interrupted speech in my opinion. The problem is that writing is not speech, that’s why it is more often seen in written dialogue.

Good writing shouldn't just be how you talk out loud.

Good writing doesn’t exclude it.

The Mac is a pre-existing platform that is both more capable than iOS, and had an existing user base that used apps that had much greater access. Apple’s attempts to lock down the Mac have met with poor adoption.

In exchange, it also less secure, less user friendly, and less popular.


> The curve of AI improvement will continue at the current pace

I guess this is trivially true if you say "maximalism" (hell, the maximalists think it will speed up as the AI becomes a super-AI-researcher), but as long as the rate of change is positive and not miniscule, it's hard to predict what 2035 looks like in software development.

These things are very hard to quantify, but making the progress that happened from Jan 2025-December 2025 repeat twice in 10 years would be enough for me to say I couldn't predict the day-to-day of a software engineer in 2035.


We need a companion to "IN MICE", which is "IN EVALS".

I don't think this is bad research, but you have to understand how far it generalizes. I'm not saying that evals are useless, we need to do our best to produce good benchmarks. But benchmarks are always going to lag pretty far behind real world applications.


> According to the paper, “Of the 22 vulnerabilities, five were level-based, meaning that the default weak isolation level led to the anomalies behind the vulnerabilities. The remaining 17 were scope-based, meaning that the database accesses were not properly encapsulated in transactions and concurrent API requests could trigger the vulnerability independent of the level of isolation provided by the database backend.”

I don't want to commit to a real opinion, but the cynic in me sees a bitter lesson you could take from this is that the database should default to a low isolation level--the damn developers aren't even using transactions right, so why waste performance handling transactions in the strictest possible way?


My experience is that there’s a percentage of developers who get it right and intuitively understand the serializable isolation level.

And database performance is a crapshoot. By “crapshoot”, I mean you mix some developers, data, and database technologies together and you get all sorts of weird performance profiles. Why sacrifice safety for performance, when you’re going to get performance problems anyway? It’s a lot easier to turn down the isolation level for a transaction, and it’s a lot harder to fix an unknown amount of inconsistent data in your database.

(The problem is that there are also a big cohort of developers who aren’t prepared to make their transactions retryable, and they’re writing their code in languages which don’t enforce transaction safety. By “languages which don’t enforce transaction safety”, I mean “languages other than Haskell”.)


So every database in the world not designed in Haskell can't do a proper transaction?

It's not the database, it's the lines of code making calls to the database.

If you're invoking your DB via C code, you will not get help with memory-safety. If you're invoking via non-Haskell code, you won't get help with transaction safety.


> If you're invoking your DB via C code, you will not get help with memory-safety.

Interesting. I didn't know C and Haskell were the only languages. I thought for sure there was at least one other memory safe language.

> If you're invoking via non-Haskell code, you won't get help with transaction safety.

Why would you not use transactions built into the database?!

You still did not answer the question...

If you can't do a transaction safely in any language besides Haskell... Then how do databases not written in Haskell do them all day everday?


The "transaction safety" part is confusing. What they mean is if you use SERIALIZABLE, transactions need to be retried, so your code inside the xact should be idempotent. I guess this is safer in Haskell because there are no variables, but that doesn't stop your code from having other side effects.

>>>> they’re writing their code in languages which don’t enforce transaction safety

>>> So every database in the world not designed in Haskell can't do a proper transaction?

>> It's not the database, it's the lines of code making calls to the database.

> Then how do databases not written in Haskell do them all day everday?


Too many people discovered databases with MySQL back in the day and didn't even know transactions were possible. And now 25 years later one of those people is likely a senior dev and 'the db guy' on a team of people who learn SQL by example. Or now never learnt it, relying on an LLM trained on decades of dodgy PHP code.

That’s the same mentality C and C++ take. Even if it was only 20%, that’s a non trivial amount of vulnerabilities that have nothing to do with the code.

I wonder what the impact of the rising base rate of employees with college degrees is. In 1992, a fresh college graduate had better educational attainment than 42% of the labor force. In 2016 (latest date I found numbers for), that was down to 32%. https://www.bls.gov/spotlight/2017/educational-attainment-of...

That shifting distribution would somewhat reduce the advantage of a college degree against the average member of the labor force.


Compare under 27s with a degree vs without and you see the problem is youth unemployment. If you are 25 you’re better off with a degree than without though.

In the U.K. youth unemployment is about 2005-6 levels. It was far higher by 2010.


Outcome is the same as in the great depression: new people can't get on the ladder and if you fall off the ladder, you'll never get back on.

It seemed like good advice as the manufacturing sector shrank.

Ding ding ding!

This also neatly explains why Boomers were able to have a good life with just a high school diploma. Wikipedia has a good chart, but the short version is that having a high school diploma in 1965 meant you were better educated than 50% of the labor force.

PhDs are the new undergraduate degree.


> If AI tokens were so magical in creating new value in developing software applications generally, they wouldn't be selling tokens directly. They'd hoard the tokens are use them to dominate SaaS software in any industry they want.

This doesn't follow at all. Anthropic's revenue is growing 10x year over year selling tokens. Their tokens can be super magical, let them enter established industries and displace incumbents, and get 100% annual growth in those industries, and they would still be better off prioritizing selling tokens, because it's a great business.

What your argument shows is that there are limits. Their tokens are not quite powerful enough to make infinite money instantly in every area of software. Admittedly, that does seem true.


kind of funny tokens don't prompt and steer themselves. it almost as if the value still lies with the human holding the tool.

They kinda do though, that's sort of how agents work. At least that's how it's always felt to me.

what is doing the steering is the weights of the words that came before in context. there is no agent or agency. if your problems need median effort and are well represented in shape in the corpus then agents may work well. true inovation is impossible without careful prompting, wherein the agent becomes an associative engine (kind of a smart search engine) and you the human become the manager of the process.

Management is very prone to fads. The current fad is that middle management is useless. Tomorrow, they'll discover the idea that organizations can have employees "working hard" on things that no one cares about, and that someone actually needs to work on focusing that effort.

Of course, the truth is you can have too many middle managers or too few (it really was bad that in 2017, the biggest achievement was "growing headcount"). But fads have a tendency to overcorrect.


I'm not sure it's so much a fad rather than recognition that AI-assisted engineering calls for flatter orgs. Also "growing headcount" as management yardstick persisted way longer than 2017 - all the way into 2022 until the rates shot up.

Thinking that middle management is useless isn't a fad, it's an acknowledgement of reality.

Lotta middle managers here goofing off instead of working :D

Even from the most purely instrumental perspective, what we care about is our ability to make use of correct answers, which is quite distinct from the possession of correct answers.

There are many theorems that aren't directly interesting, but whose proof requires techniques that are of substantial further interest, that lead to new domains, and/or new practical applications. Simply being handed a proof for those theorems isn't enough--we require the ability to apply those techniques in the real world, or discover further areas of mathematical research that build on that proof or its techniques.

It may be that AI can build on its own work for the long-term, but so far, AI does best at exploration in areas that have precisely specified and measurable goals. Actually creating understanding, and making use of mathemtical results outside of pure mathematics is more challenging than simply creating proofs.

I think the field will figure out how to make use of AI, and it will be better off for it. But that is not the same as just saying "answers good, grog want more answers."


I confess, this is very funny and the underlying situation is a bit absurd, but it's unclear what point Brouwer is making by pointing out the absurdity.

There surely is something absurd about having to register specific processes as exempt from the OOM killer. But given that the OOM killer exists, and could kill xlock...how should that be fixed?


I think part of it is that the design of screen lockers on X11 is just broken. If the locker crashes (or is killed), then the screen unlocks. Security-wise, it fails open. On Windows and macOS (and Wayland, using the ext-screen-lock protocol, coupled with sane compositor policy), that can't happen.

The right way for this to work is for the X server to have an extension that lets a screen locker say "hey, I'm locking the screen now", and the X server should respond to that by pretending that the screen locker client is the only client that exists: no other client gets input or gets to draw. And if the screen locker crashes (or is killed), the X server should just put itself into a permanently-locked state where it will never again send any input to anything, and won't ever draw anything except a blank screen. That's not a desirable situation, of course, but it's better than unlocking the screen.


Admittedly, that's right, and makes sense for that use case. But as others have pointed out, killing the user's web browser while they're using it is equally painful.

I read him as arguing that overcommit was a mistake. Of course, he doesn't answer any of the obvious follow-up questions, such as, does fork–exec copy all the process's memory and then immediately throw it away, or what. (One could argue that fork–exec was also a mistake, but it long predates Linux, so this doesn't answer the question of how Torvalds should have designed it.)

> does fork–exec copy all the process's memory

NT: Yes? Why not?

(note that this refers to the Windows NT kernel's operation because it had historically a POSIX emulation layer (NT Personalities), not the modern WSL which is just Linux in a Hyper-V)


because this is what causes Windows to use ~80% more memory than unixes

Well, in that case it's a good thing I guess. Windows is orders of magnitude better when it comes to memory management on the desktop compared to Linux. Like why would I even want a single process killed by OOM killer? On Windows things just work, or get slow. On Linux it works and then mayhem ensues.

Last year I was writing a reply on a forum in Firefox on Linux when the OOM killer decided to nuke Firefox. Poof gone, mid keystroke. How does anyone think that's acceptable?

This was on a stock Linux distro, nothing special.


> Windows is orders of magnitude better when it comes to memory management on the desktop compared to Linux.

The bar is pretty low, but the windows scheduler is aware what the currently focussed app is so it can prioritise not killing it.

On Linux? Not so much.


Actually, it depends on the Windows scheduler settings. On Windows Server, the default is to kill the foreground process (on the assumption that it is just a management app rather than a critical server component).

In either case, Windows tries a lot of things to avoid killing processes. Which at least in a desktop setting is an infinitely better approach than random beheadings without warning.

yeah. a lot of the issue with Linux's approach is that until recently, the kernel was the one making the choice, and it doesn't know which processes matter. The part Linus does a lot better if not getting to oom in the first place (and with the newish compressed ram stuff is getting even better)

Processes are usually spawned with CreateProcess. There's no fork in win32.

Windows doesn't use fork/exec for process creation in any relevant way today

There are Native APIs for implementing fork (needed for the obsolete POSIX subsystem, primarily), but even on the Native API side, processes are usually spawned through NtCreateProcess or RtlCreateUserProcess, though there is a bunch of setup with regards to the Csr APIs for the Win32 CreateProcess[1]).

[1]: https://stackoverflow.com/a/69605729/2805120


> does fork–exec copy all the process's memory and then immediately throw it away, or what

No, you just account for it (commit the charge) in the bookkeeping. If a 1GB process forks, you decrement the amount of free memory by 1GB to ensure other processes don't overcommit such that you won't have 1GB of free memory if and when you actually needed to allocate that memory. If the forked process immediately exits, you just bump the free memory counter back up. This is what Solaris and Windows do.

But precise accounting of memory is difficult if you didn't design for it in the first place. For example, you have to figure in the memory needed for page structures. (Though I think Linux can do that in particular, bugs notwithstanding.) Last time I checked (5+ years ago) Linux was incapable of such precise accounting across the board, so even if you disabled overcommit the kernel could still find itself in an OOM situation when the time comes to allocate memory it already promised or perform an operation it implicitly or explicitly guaranteed it could complete.

The expectation that Linux overcommits meant many Linux kernel developers didn't design subsystems in a way that the kernel as a whole could provide reliable, guaranteed, precise memory accounting. For example, some filesystems rely on being able to use the OOM killer to free up memory needed for an operation that it can't back out of once it starts because it wasn't written in a way that it could either predetermine or bound it's memory requirements, or cleanly back out of an operation it started.

To be fair I'm not sure any of the BSDs can do it either, at least when it comes to fork and CoW. IIRC, nor can macOS, though it will dynamically add swap so you won't get an OOM kill until you run out of disk space.


Well, Windows doesn't have fork–exec so there's no problem with a 15 GB process spawning a 15 MB subprocess. Whereas doing that on Linux without overcommit requires there to be 15 GB free. vfork and posix_spawn work around this, but lots of existing code doesn't use them, vfork is notoriously hard to use correctly, and posix_spawn doesn't (and doesn't try to) cover all fork–exec use cases.

NtCreateUserProcess supports copy-on-write fork semantics without overcommit. See https://github.com/huntandhackett/process-cloning#cloning-fo... And there's a wrapper, RtlCloneUserProcess, that is called using the same traditional fork pattern.

Precise memory accounting and CoW fork aren't intrinsically antagonistic, and the general ability to clone CoW mappings or similar kernel structures is useful beyond fork, which is why NT had all the necessary facilities in the kernel (it's the userspace CRT state that can be tricky, especially in the presence of threads, which is true on Unix systems as well).

The example of forking a process with a giant VM space just to exec some other program is, IMO, a straw man. Processes with such huge RW mappings typically don't fork and exec like that. Nobody architecting an app like PostgreSQL was relying on the ability to easily fork processes for minor tasks or exec utilities from processes already forked for resource intensive tasks. And when such a thing is desirable, it's easy enough to use the alternatives, like vfork, or architect a controller for spawning subprocesses, or just use threads. Heck, fork existed long before CoW. Expectations around fork, that you can and should be able to call it without any forethought about resource management was a consequence of Linux' popularity.

Linux embraced overcommit because people wanted to run existing big iron applications like networked databases on tiny PCs with fractions of the memory those applications were written to expect to be able to use. Overcommit was a hack that let your play around with those applications without them immediately falling over, partly because back then such applications often preallocated memory for cache, etc, but would never use all of it when running in an environment like early Linux, which would never see the same high loads and utilization as big iron servers.

Linux could have pivoted in the other direction and pursued strict memory accounting with the ability to expressly overcommit in, e.g., some process subtrees or dynamically allocate swap (which in the expected scenario it normally wouldn't have to actually do). But like most userspace developers they found it easier to write kernel code when they could pretend memory was infinite, and when the system hit the wall just blow up and blame the user. That choice can be defensible for userspace, but it's simply not defensible for a kernel.


To be 100% fair, it's rare that processes are cloned on Windows, if only because it's part of the Native API that applications generally don't use directly, and CreateProcess is easier and does all the housekeeping stuff, etc, that people writing Windows applications generally come to expect (or don't even know happens)

I do think overcommit was a poor design choice, but I think it probably mostly does logically follow from the fact that fork and friends are the only ways available to create a process that's available to userspace. It's quite unfortunate though.

Part of the problem is that some applications wanted to reserve lots of address space but didn't necessarily want to touch it right away (such as when they were using it sparsely). Something that VirtualAlloc(x, MEM_RESERVE) (or mmap(..., MAP_NORESERVE)) would be suited for. But while malloc exists, mreserve doesn't in libc, and I think it was pretty uncommon to use it.


Fork should be replaced by vfork (or something better) in almost all situations.

The point is that the OOM killer shouldn't exist and arguing about how to tweak it is addressing the wrong problem

I agree that that's the point he's making, but I don't see how that would work practically. His attitude is that malloc(1<<63) should immediately crash the system, every time? How is that better?

No, if a process allocates an infeasible amount, malloc fails and the process needs to deal with the failure (which is what already happens, "malloc doesn't fail on Linux" is only really true for smaller-than-page-size allocations). The point being made is that the system should account conservatively for all memory that can be used, not just the optimistic underestimate that overcommit enables (i.e. the plane should always carry enough fuel for contingencies, and landing with extra fuel is a good outcome).

You never need to crash the system if you remove overcommit. You just crash the one process. Practically speaking, you don't even need to crash here; you just return null (which malloc is always free to do) and let the consequences speak for themselves.

malloc can just return NULL (in specific, mmap returns -ENOMEM and your libc translates that). Applications need to check for success anyway

But the second clause doesn't follow from the first!

I don't think Linux was plausibly going to remove the OOM killer in 2004 or later. So the right solution for Linux is very much to tweak it to be less painful.


I also think the analogy doesn't work. In the plane situation it seems obvious that the luggage should be ejected before passengers, which is what the guy was asking ?

The analogy doesn't work because you can't call fork() on the plane and then it duplicates just the seat for the passenger or pilot that did something different. Also, killing them rather ghastly.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: