Show HN: NES Contra (1987) port (ASM –> C and then C –> WebAssembly)
A browser-based port of the 1987 NES game Contra converts its assembly code to C and then WebAssembly. It supports solo play and online two-player games. (epoyraz.github.io)
Python’s None often carries several meanings: a value is absent, a setting is unset, an operation failed, or the value itself is genuinely None. That overlap causes bugs and awkward APIs. A cache cannot distinguish a missing key from one storing None; a configuration update cannot tell whether timeout=None means “disable the timeout” or “leave it unchanged”; and a function that catches TimeoutError and returns None hides whether it succeeded. Sentinel values solve the problem by using a distinct marker that cannot be confused with valid data. Python already uses sentinels: Ellipsis has roles in slicing and stubs, while NotImplemented lets operators defer to another implementation. Pydantic’s MISSING similarly distinguishes an omitted field from one explicitly set to null.
Creating custom sentinels used to involve trade-offs. The common object() marker works at runtime but does not support reliable type narrowing; TypeIs guards, string literals, and one-member Enums each have drawbacks, and copying or pickling can undermine identity checks. PEP 661, which was initially deferred and then accepted nine days later, introduces a standard sentinel() built-in in Python 3.15. A sentinel can distinguish “no update” from “delete this value” and an actual value, while allowing type checkers to narrow the remaining type. Older versions can use typing_extensions, though checker support may vary. The practical advice is to identify what None is meant to express, use a library’s existing sentinel where possible, and replace improvised markers with the built-in when available.
Summary generated by AI from the linked article. hn.today is not affiliated with Hacker News or Y Combinator.
A browser-based port of the 1987 NES game Contra converts its assembly code to C and then WebAssembly. It supports solo play and online two-player games. (epoyraz.github.io)
PostgreSQL’s TOAST storage made the table much smaller, and counting or scanning rows was faster than with the larger uncompressed table. But reading a field inside every toasted value required far more buffer reads, showing that TOAST can trade space savings for slower access to large values. (pgedge.com)
Large GROUP BY hash tables cause frequent slow RAM accesses, leaving CPUs stalled even when monitoring shows 100% usage. Processing data in smaller chunks can improve cache use and speed up aggregation, even if it requires more CPU work. (pivotlake.io)
Enlightenment 0.28 adds initial NetBSD support, a NetworkManager module, and native PipeWire mixer support while retaining PulseAudio compatibility. The release also improves window management, display handling, and X11 and Wayland support, alongside numerous fixes and code cleanups. (phoronix.com)
Nonna is a TypeScript dependency-injection framework and ahead-of-time compiler that avoids reflection and runtime dependencies. It supports Node.js, Deno, Bun, edge runtimes, and major frontend frameworks, with request scoping and deterministic lifecycle hooks. (nonna.nodeboot.io)
Jepsen found 96 bugs in ParticleDB versions 1.1.4 through 1.1.18.11.rc-22, including crashes, data loss, and serious transaction anomalies. Most issues were fixed, but committed writes could still disappear and serializable transactions still had anomalies; Orkes says a later release resolves the remaining problems. (jepsen.io)
Today's best Hacker News stories, summarized and screenshotted, one email a day.