Recent submissions

Comment · 7 months ago
Zig gives things we really dont have yet: C + generics + good const eval + good build system + easy cross compilation + modern niceties (optionals, errors, sum types, slices, vectors, arbitrary bit packing, expression freedom).

Are there any other languages that provide this? Would genuinely consider the switch for some stuff if so.

Comment · 7 months ago
There are places a language could be a better fit, but which haven't adopted it. E.g. most languages over typescript on the backend, most systems programming languages over Java for games.
Comment · 7 months ago
Comment · 7 months ago
Comment · 11 months ago
> so you have no clue if the shared data might be incompletely modified or otherwise logically corrupted.

One can make a panic wrapper type if they cared: It's what the stdlib Mutex currently does:

MutexGuard checks if its panicking during drop using `std::thread::panicking()`, and if so, sets a bool on the Mutex. The next acquirer checks for that bool & knows state may be corrupted. No need to bake this into the Mutex itself.

Comment · 1 year ago
C++'s `::` vs Zig's `.`

C++'s `__builtin_` (or arguably `_`/`__`) vs Zig's `@`

Comment · 1 year ago
Comment · 2 years ago
Tokio's focus is on low tail-latencies for networking applications (as mentioned). But it doesn't employs yield_now for waiting on a concurrent condition to occur, even as a backoff strategy, as that fundamentally kills tail-latency under the average OS scheduler.
Comment · 3 years ago
Thanks, seems like most are from LLVM or packed structs.
Comment · 3 years ago
Are there any links / examples for the miscompilations?
Comment · 3 years ago
> Green threads give you all the advantages of async

They require more memory over stackless coroutines as it stores the callstack instead of changing a single state. They also allow for recursion, but its undelimited meaning you either 1) overrun the guard page and potentially write to another Green thread's stack by just declaring a large local variable 2) enable some form of stack-probing to address that (?) or 3) Support growable stacks which requires a GC to fixup pointes (isn't available in a systems lang).

> green threads should run faster, as storing state on a stack is generally faster than malloc.

Stackless coroutines explicit don't malloc on each call. You only allocate the intial state machine (stack in GreenThread terms).

> The primary objection seems to be speed

It's compatibility. No way to properly set the stack-size at compile time for various platforms. No way to setup guard pages in a construct that's language-level so should support being used without an OS (i.e. embedded, wasm, kernel). The current async using stackless coroutines 1) knows the size upfront due to being a compiler-generated StateMachine 2) disallows recursion (as that's a recursive StateMachine type, so users must dynamically allocate those however appropriate) which works for all targets.

Comment · 3 years ago
This would imply a single/global runtime along with an unrealistic API surface;

For 1) It's common enough to have multiple runtimes in the same process, each setup possibly differently and running independently of each other. Often known as a "thread-per-core" architecture, this is the scheme used in apps focused on high IO perf like nginx, glommio, actix, etc.

For 2) runtime (libasync.so) implementations would have to cover a lot of aspects they may not need (async compute-focused runtimes like bevy don't need timers, priorities, or even IO) and expose a restrictive API (what's a good generic model for a runtime IO interface? something like io_uring, dpdk, or epoll? what about userspace networking as seen in seastar?). A pluggable runtime mainly works when the language has a smaller scope than "systems programming" like Ponylang or Golang.

As a side note; Rust tries to decouple the scheduling of Futures/tasks using its concept of Waker. This enables async implementations which only concern themselves with scheduling like synchronization primitives or basic sequencers/orchestration to be runtime-agnostic.

Comment · 3 years ago
Preemption simulates localized concurrency (running multiple distinct things logically at the same time) not parallelism (running them physically at the same time). You can have concurrency outside continuations. OS threads for example are not continuations, but still express concurrency to the kernel so that it can (not guaranteed) express concurrency to the physical CPU cores which hopefully execute the concurrent code in parallel (not guaranteed again, due to hyperthreading).
Comment · 3 years ago
getaddrinfo() is a synchronous function that can do network requests to resolve DNS. The network property isn't reflected in its function signature becoming async. You can have an async_getaddrinfo() which does, but the former is just a practical example of network calls in particular being unrelated to function coloring.
Comment · 3 years ago
no, .Wait in C# or block_on in Rust keep the caller sync while evaluating the async callee, preventing the "bubble up".

Live from the official Hacker News API

A modern reader for Hacker News · SvelteKit + Skeleton