Hacker News new | ask | show | jobs
by nine_k 12 days ago
Go is not a better C, in the sense that you cannot write an OS with it. Runtime, GC, etc.

But Go is a better language for many programs that were often written in C: network servers, CLI utilities, TUI utilities, etc.

3 comments

Plenty of OSes, since Xerox PARC days have been written in GC systems languages.

Interlisp-D, Smalltalk, Cedar, Topaz, Oberon, Active Oberon, Singularity, Midori, Ironclad

Go's runtime is written in Go.

The whole compiler toolchain, GC, compiler, linker, Assembler, is written in Go.

There are Go compilers for bare metal, no OS needed, like TinyGo, the runtime, written in Go is the OS.

I love the "you cannot write an OS in a GC language" discourse.

It isn't only a mainstream thing because everyone only cares about UNIX clones.

The fact that people care a lot about Unix clones is significant, though. nine_k could have been more effective in arguing the point, but it seems like a strong point to argue. Do you think you Go is flexible enough to write a Unix clone with performance equivalent to a C-unix? If so, why has it not been done?
Besides the sibling Biscuit, maybe because no one bothered to do it?

As simple as that, not everyone of us is a Linus.

I should also point out that if you are using a Mac, changes are its iBoot Safe C might already been replaced by Embedded Swift, a GC enabled systems language.

Chapter 5 of The Garbage Collection Handbook, or A Unified Theory of Garbage Collection paper for the incoming replies related to RC.

People care about UNIX clones because they are lazy, UNIX has the source code available, and an existing ecosystem that they don't want to replicate, so it always ends up being yet another clone, thus throwing away all the possible innovations.

We see this happening even with Haiku, Genode, Redox OS, or Windows now shipping alongside Linux on top of Hyper-V.

Unless one is an Apple or Google, with the money and will power to push something out the door, using Objective-C, Swift, Java, Kotlin, with plain C and C++ standard libraries, and even then people will bend backwards to put UNIX into those systems, even when the platform owners went to great effort to hide it under the official userspace APIs.

> As simple as that, not everyone of us is a Linus.

I’m pretty sure Linus could not have written Linux today. Too much hardware to support, too many drivers to write, before it’s remotely useful. Well, except perhaps on some specialised servers.

Yes, not everyone is Linus. Otherwise we’d be using GNU Hurd. But he also came at the right time.

It is no accident that recent attempts to write hobby OSes nowadays target type 1 hypervisors instead of real hardware.
> People care about UNIX clones because they are lazy, UNIX has the source code available, and an existing ecosystem that they don't want to replicate, so it always ends up being yet another clone, thus throwing away all the possible innovations.

Which is a real shame, because people thinking outside the UNIX clone box have come up with some incredibly innovative operating systems like Plan 9 and OS/400.

There is Biscuit from OSDI 2018 https://pdos.csail.mit.edu/projects/biscuit.html
> If so, why has it not been done?

Because of the 30 million lines problem. Writing a serious OS kernel nowadays is flat out impossible: the hardware is just too diverse, it requires too many drivers. The best we can do right now is just add to an existing kernel. Kind of a vicious cycle: the more drivers we accrete to any given OS, the more impossible it is to get feature parity from the ground up.

The only solution to that is for hardware vendor to standardise their interfaces (at the hardware level), and actually give us the fucking manual. And I mean the real manual, the one that tells us voltages and pins and baud rates and the actual wire formats required to talk to it. A proprietary Windows driver is not a manual, even if it comes with an SDK. Heck I’m not even sure the source code of a Linux driver would count.

But they won’t do it. They just won’t. So unless we do something drastic like forbidding hardware vendor to ever ship software (to force them to standardise and document their actual interfaces), writing another OS that can actually compete with the existing ones will remain flat out impossible.

> Go's runtime is written in Go. The whole compiler toolchain, GC, compiler, linker, Assembler, is written in Go.

There's some nuance to this. The runtime code uses specific compiler support and restrictions that are not ordinary Go - possible (or even done, like this case) ≠ ergonomic. No doubt of course that for the Go project, this is still a win.

Do you think libc is also written in pure ISO C?

I love how language extensions, and subsets are always valid for C and C++, but used as an attack against other languages, as if to prove they are not good enough for a specific use case.

Well, neither are C and C++, as they either have to rely on hand written Assembly code, language extensions, or be gutted down into subsets outside the official language standard.

> but used as an attack against other languages, as if to prove they are not good enough for a specific use case.

Ultimately, it comes down to the (subjective, sure) ergonomic limitations of a language. To me, Go without garbage collection and implemented using specific compiler support and significant amount of unsafe operations, does not really represent Go, just as, so to speak, a Rust project containing 90% unsafe code does not really represent Rust. Both are possible of course, and there are even use cases in which they may be desirable in the broader context (ie. the Go runtime).

Therefore, this is not an attack on the language; it is simply an assessment of its ergonomics for particular use cases.

> Go is not a better C, in the sense that you cannot write an OS with it

Can you even write an OS in pure ISO standard C? I know atomic (https://en.cppreference.com/c/language/atomic) was added in C11, but is that sufficient to write an OS? How do you write a kernel-user space transition in standard C, for example?

The larger runtime makes bootstrapping go for unsupported architectures more laborious than C, but it's not a hard blocker. The function call overhead for inline assembly feels like more of an issue doing close to hw programming. It can be avoided for the runtime, but user go code can't escape it afaik.
Just like when C was being brought to life in PDP hardware and there was nothing else, someone has to put the work into it.