HNHacker News
TopNewBestAskShowJobs

brandmeyer

4,226 karma · joined April 19, 2015

submissionscomments
brandmeyer··on You Win, Broken Database Schemas
Iceland is a somewhat special case. As a tiny culture of < 400k people, it has to work hard to maintain cultural distinctiveness in an interconnected world. They don't just have a restrictive naming law, they also have dedicated teams which are focused on maintaining and preserving a distinctive definition of their language.

https://en.wikipedia.org/wiki/%C3%81rni_Magn%C3%BAsson_Insti...

brandmeyer··on Thoughts on Return, Break and Continue
I am reminded of "Lambda: The Ultimate GOTO"

https://dspace.mit.edu/handle/1721.1/5753

brandmeyer··on NASM Assembly Language Tutorials
It seems like every hardware vendor (and sometimes each compiler) provides its own syntax for assembly code. Leaving aside the obvious fact that each ISA has its own instructions, nearly everything else varies from one assembler to the next.

Are clobbered registers the left-most or right-most argument? How are comments expressed? Are operands separated by space alone or with commas? How are jump target labels expressed? How are addressing modes expressed? Go source diving in the FreeRTOS source code and you'll see that even when several different compilers support the same architecture (eg ARMv7-M), they will all have slightly incompatible assembly code syntax.

brandmeyer··on Features of a dream programming language
You cannot append to a std::span, or append to a vector-backed span through the span. You have to perform the append on the underlying vector. It is possible to perform an insertion into the middle of a std::vector through std::vector::insert.

If you can establish the precondition that the underlying vector will not re-allocate as a result of the append, then it is perfectly safe to perform such an append while holding a reference to one or more elements of the vector. Same thing for insertions: references to elements before the insertion point may still remain valid if you can establish the precondition that the vector will not be resized. In both cases, it is straightforward to establish the precondition through the reserve() member plus some foreknowledge of how much extra capacity the algorithm needs.

You can always construct a user-defined reference type which back-doors the borrow checker, such as by storing indexes instead of iterators as you mentioned. If the std.vector is reduced, then they are still just as invalid.

brandmeyer··on Redo: A recursive, general-purpose build system
You can get make to only re-generate its rules incrementally based on what was changed.

https://www.gnu.org/software/make/manual/html_node/Remaking-...

brandmeyer··on Features of a dream programming language
We also frequently need reference types to contiguous storage in addition to value types of contiguous storage. In C++ this is satisfied by std::span for both the static and dynamic cases.
brandmeyer··on Features of a dream programming language
Decorator over-use can lead to some difficult-to-read Python.

Doing just about anything imperative at import-time makes it hard to reason about what happens when. Even experienced Python programmers can get tripped up by the import system's order of evaluation.

brandmeyer··on Features of a dream programming language
Since Python scopes lexical variables to the function instead of the block, `j` is in scope for every line of `... outer ...`. So de-denting the last line of inner doesn't trigger a NameError, even for new bindings which were introduced within `... inner ...`.
brandmeyer··on Redo: A recursive, general-purpose build system
The original sin here is generating the dependencies from the source files in the same step that was used to generate the object files. The only way to ensure that Make observes structural changes in the dependency DAG is if the graph is rebuilt.
brandmeyer··on Lua: Good, Bad, and Ugly Parts (2012)
Some corrections: Boost.Python (note the period) was a C++ library for automaticing the generation of cross-language bindings between Python and C++. It wasn't itself a distribution of Python. Boost.Python still exists. However, its successor (pybind11) used features shipped in C++11 to simplify the implementation (and compiles far faster) and is the leading Python-to-C++ binding to use today. I'm using pybind11 in a project today with bog standard Python3 and it works great.

Lua made inroads into the game dev community in particular thanks to LuaJIT. Despite it actually being a fork of Lua that hasn't kept up with changes in the base language, LuaJIT remains popular for its speed.

brandmeyer··on On ELF, Part 2 (2018)
There are also segmentation differences. Only one copy of the read-only data and code (aka text) segments are mapped into all programs which load the library. However, each program instance gets its own unique pages of read-write data. Those pages are always located at a fixed offset from their code segment. That way, modern CPUs can execute PC-relative instructions to generate their addresses. The global data segments for a module are always located at a fixed offset relative to the code pages.

See ARMv8 `adrp` (address of PC-relative page), RISC-V `auipc` (add upper immediate to program counter), and x86-64 PC-relative addressing for some modern examples.

Then go backwards in time and see how ARMv7 does it (literal pools) and how some earlier RISCs did it (Itanium and Alpha global pointer aka "gp", PowerPC table-of-contents register).

brandmeyer··on On ELF, Part 2 (2018)
Symbol versioning is the feature which has kept libc at major ABI version 6 for all these years. The libc5 -> libc6 major version bump gave users trouble for many years afterwards.
brandmeyer··on PostgreSQL's Missing DateDiff Function
Why would you want this to round up instead of down or to nearest?
brandmeyer··on China issues new encryption import control
RISC-V has some extension instructions dedicated to them. The extension was ratified very recently, so it isn't clear which chips will actually support them.
brandmeyer··on Allocgate: Restructuring how allocators work in Zig
BitC used a strictly typed memory model.
brandmeyer··on Three loud climate warning signals
Climate change is a big problem, but harping on ice-sheet collapse is a strategic mistake. We know a priori that ice sheet collapse is one of the longest-term threats. None of us will experience impact from them in our lifetime, and focusing on them hands the deniers their own talking points to them on a silver platter.

Extreme weather events, wet-bulb temperature shifts, arable land changes, and habitat loss are near-term threats that are already having impact.

brandmeyer··on Three loud climate warning signals
Climate change is a slow-moving problem, and the situation with the Thwaites Glacier is no exception.

From the scientific article's[1] own plain-language summary: "The Thwaites Eastern Ice Shelf is the floating terminus of the Thwaites Glacier, one of the fastest changing glaciers in Antarctica and contributing as much as 4% of global sea level rise today. This floating ice shelf is stabilized offshore by a marine shoal and acts as a dam to slow the flow of ice off the continent into the ocean. If this floating ice shelf breaks apart, the Thwaites Glacier will accelerate and its contribution to sea level rise will increase by as much as 25%."

So, this specific ice shelf's collapse would increase global sea level rise by up to 1%. Over the coming decades, the dominant driver of sea level rise will continue to be thermal expansion of the ocean itself. The West Antarctic Ice Sheet in total may contribute 3 m of sea level rise... over a period of 13 thousand years[2].

[1]: https://agu.confex.com/agu/fm21/meetingapp.cgi/Paper/978762

[2]: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4655561/

brandmeyer··on T* makes for a poor optional&lt;T&&gt;
To be fair, languages which require explicit unwrapping also provide syntactic short-hands for the most common idioms. Long-handed if/else (or pattern matching) is used to implement the short-hands or as a last resort.

See also value_or and the C++20 monadic methods on std::optional.

http://open-std.org/JTC1/SC22/WG21/docs/papers/2021/p0798r6....

brandmeyer··on Notes on the Go translation of Reposurgeon (2020)
> With that perspective, I don’t think that 23 crates is terrifying. I’m going to look them all over and either pick one, or write the 24th crate myself. The result is the same either way.

In a fine-grained ecosystem, the problem is transitive. You aren't just picking one from 20+ for each of your direct dependencies, you are also trusting that they in turn did just as much diligence as you did in picking their direct dependencies and so on. Curation and pruning would at least help mitigate the scope of the problem.

> ... or write the 24th crate myself.

This is a good example of the xkcd joke about standards proliferation. If I found myself in this situation, I'd prefer to keep the 24th private to my own package. DRY has its limits. Sometimes you've just got to specialize.

I'm aware of the irony in saying this in the context of mmap. But in this case, a thin wrapper that reflects the system call's semantics ought to be available in a common `posix` crate that others may freely rely upon to build their higher-level services. There's no good reason for e.g. ripgrep to have to pick and choose among a dozen flowers for it.

brandmeyer··on Notes on the Go translation of Reposurgeon (2020)
> A lot of Rustaceans don’t seem to grasp why, when the question is “where do I get feature X?” the answer “oh, there are 23 crates for that” is objectively terrifying.

This is exactly the impression I have gotten from the crates system every time I've looked. It happens for things as foundational as mmap. Also terrifying: The plethora of highly-recommended crates that have not yet committed to a stable API (ie, are still semantically on version 0.X).

brandmeyer··on “UnGoogley”? Worker says she was fired for questioning no holiday pay
Depends. In other reports, she has admitted that they way she questioned the policy was by cussing out her supervisor. She had been on the job for less than two weeks.

Given those additional facts, I don't have very much sympathy for her position.

brandmeyer··on “Risc V greatly underperforms”
Comparing RISC-V's "C" extension to classic Thumb when Thumb-2 is 17 years old is like comparing RISC-V's "V" extension to classic SSE when AVX-512 and SVE2 are already available. Its an insidious form of straw-man attack that preys on the reader's ignorance.

> [Thumb-2] doesn't do everything, and switching has a significant cost.

Technically true, but irrelevant. Cortex-M is thumb-only and can't switch. Cortex-A processors that support both Thumb and ARM instructions almost never actually switch at all.

brandmeyer··on “Risc V greatly underperforms”
> The main thing wrong with the standard one in my opinion is that it gives too much prominence to floating point code, having been developed to optimise for SPEC including SPECFP (no, not the Linux kernel or Dhrystone ... I have no idea where you got that from).

The RISC-V Compressed Spec v1.9 documented the benchmarks which were used for the optimization. RV32 was optimized with Dhrystone, Coremark, and SPEC-2006. RV64GC was optimized using SPEC-2006 and the Linux kernel.

brandmeyer··on “Risc V greatly underperforms”
It only addresses a subset of the available registers. Small revisions in a function which change the number of live variables will suddenly and dramatically change the compressibility of the instructions.

Higher-level languages rely heavily on inlining to reduce their abstraction penalty. Profiles which were taken from the Linux kernel and (checks notes...) Drystone are not representative of code from higher-level languages.

3/4 of the available prefix instruction space was consumed by the 16-bit extension. There have been a couple of proposals showing that even better density could be achieved using only 1/2 the space instead of 3/4, but they were struck down in order to maintain backwards compatibility.

brandmeyer··on Endiannes and Polymorphism in Rust
If you're gong to the trouble to use an overlay structure to represent the serialization of an object, then the most optimal thing to do is to perform the endianness conversion once at the boundary between the outside world and the program.

Adding type annotations encourages a coding style that makes many conversions at every point of use, instead of only once at the boundary.

brandmeyer··on The time complexity of the libc++ deque push_front implementation is O(log n)
That is quite unfortunate, and I freely admit that I'm unfamiliar with MSVC's current quirks.

> They have made clear that this won't be changed, for ABI stability reasons.

Also unfortunate. Once upon a time, users had to be extra careful to control which version of the runtime DLL their program transitively linked to since MS would issue a new ABI-breaking version with every major compiler release. Sounds like they got ABI stability religion just in time to lock in some unfortunate decisions.

brandmeyer··on The time complexity of the libc++ deque push_front implementation is O(log n)
GDB has a pluggable pretty-printing system.

http://sourceware.org/gdb/wiki/STLSupport

That doesn't necessarily help if you are backtracing from your own lambda up through some <algorithm>. But it does help many other use cases with the standard library.

brandmeyer··on The time complexity of the libc++ deque push_front implementation is O(log n)
> internal methods have cryptic names

They choose names like _Capitalized and __lowercase because those identifiers are reserved for the implementation. Its a consequence of the preprocessor's lack of hygiene.

So where you might see a convention of naming members like m_thingish_foo, in the implementation's library headers they would be named _M_thingish_foo or __m_thingish_foo.

brandmeyer··on The time complexity of the libc++ deque push_front implementation is O(log n)
> MS STL at around 64bytes.

Citation? Are you sure it isn't 64 size-independent elements?

brandmeyer··on SQLite Release 3.37.0
Hot take: The ANY column type will never be used. Users who want to take advantage of it will just avoid the STRICT keyword on the whole table (maybe even the entire database). Users who like STRICT typing will reach for a JSON column for their occasional weakly- or sum-typed needs.
← PreviousPage 5 of 34Next →