HN user

pbrowne011

495 karma
Posts52
Comments35
View on HN
blog.jgc.org 5mo ago

The European Schuko socket bothers me

pbrowne011
6pts0
elibaum.com 11mo ago

A Wrigley Mystery (2024)

pbrowne011
2pts0
igorpak.wordpress.com 1y ago

How not to Reference Papers (2014)

pbrowne011
1pts0
osf.io 1y ago

Reproduction of "Improving Women's Mental Health During a Pandemic"

pbrowne011
2pts1
practicaltypography.com 1y ago

The Billionaire's Typewriter (2019)

pbrowne011
1pts0
guicommits.com 1y ago

Handling exceptions in Python like a pro (2021)

pbrowne011
2pts0
eprint.iacr.org 1y ago

How to Prove False Statements: Practical Attacks on Fiat-Shamir

pbrowne011
2pts0
www.benrady.com 1y ago

There's No Such Thing as Software Productivity (2012)

pbrowne011
130pts135
www.benrady.com 1y ago

CRUFT: An alternative to the Technical Debt metaphor

pbrowne011
3pts0
breckyunits.com 1y ago

Strong Advice (2021)

pbrowne011
1pts0
www.tedinski.com 1y ago

How humans write programs (2018)

pbrowne011
2pts0
johnj.com 1y ago

Making a Tiny E-Paper Status Display for the Raspberry Pi Zero

pbrowne011
2pts0
www.loyalty.org 1y ago

Understanding Common Factor Attacks: An RSA-Cracking Puzzle

pbrowne011
2pts0
benjdd.com 1y ago

1B Nested Loop Iterations

pbrowne011
1pts2
classics.mit.edu 1y ago

The Rubaiyat (1120 ACE)

pbrowne011
1pts0
lwn.net 1y ago

An attempt to backdoor the kernel (2003)

pbrowne011
32pts0
www.bell-labs.com 1y ago

Dabbling in the Cryptographic World–A Story (1999)

pbrowne011
1pts0
chris-intel-corner.blogspot.com 1y ago

The American M-209 cipher machine

pbrowne011
2pts1
blog.regehr.org 1y ago

It's time for a modern synthesis kernel (2019)

pbrowne011
58pts8
edmcman.github.io 1y ago

The performance of hashing for similar function detection

pbrowne011
59pts2
blog.benjaminreinhardt.com 1y ago

Precocious young people should do deep technical training

pbrowne011
3pts0
blog.regehr.org 1y ago

It's time for a modern synthesis kernel (2019)

pbrowne011
5pts1
nabeelqu.co 1y ago

Reflections on Palantir

pbrowne011
4pts0
blog.kylemanna.com 1y ago

FriendlyElec NanoPi R5S as PTP Grandmaster Clock with GNSS/GPS Discipline (2022)

pbrowne011
36pts8
edmcman.github.io 1y ago

The performance of hashing for similar function detection

pbrowne011
1pts0
mrkaran.dev 1y ago

DNS Lookups in Kubernetes (2020)

pbrowne011
2pts0
dmytroengineering.com 1y ago

Hacking the T2S+ Out of Fear: Get Lock-In Thermography for Free

pbrowne011
2pts0
ruemohr.org 1y ago

So the serial comms aren't working to your microcontroller eh? (2009)

pbrowne011
3pts0
www.cs.cornell.edu 1y ago

Two's Complement (2000)

pbrowne011
1pts0
rsaxvc.net 1y ago

A Compiler Bug (2023)

pbrowne011
39pts10

Feels like this would be a good candidate for Pike's programming rules (https://www.cs.unc.edu/~stotts/COMP590-059-f24/robsrules.htm...):

"Rule 1. You can't tell where a program is going to spend its time. Bottlenecks occur in surprising places, so don't try to second guess and put in a speed hack until you've proven that's where the bottleneck is.

Rule 2. Measure. Don't tune for speed until you've measured, and even then don't unless one part of the code overwhelms the rest."

GitHub Stacked PRs 3 months ago

Interesting to see how their CLI compares with GitLab's CLI interface for stacked diffs (the only support they offer at the moment): https://docs.gitlab.com/user/project/merge_requests/stacked_.... Most things are the same (up/down/top/bottom vs. next/prev/first/last, init vs. create), but both feel quite limiting. I've heard of other systems such as Gerrit that offer better native support, but have not tried out any for myself.

It seems crazy to me that vulnerabilities like this still exist today. I understand that not everything will be written in Rust, but this could have been caught by basic testing and/or fuzzing, as Nick (the person who found the vulnerability) points out: https://www.openwall.com/lists/musl/2025/02/14/1. So far, this earned an 8.1 from MITRE: https://nvd.nist.gov/vuln/detail/CVE-2025-26519, although I'm not sure if that's just a function of it being a bug in a library that so many applications use.

This also goes to show how every line matters. The one line change was from

    if (c >= 93 || c>=0xc6-0x81 && d>0x52)
to
    if (c > 0xc6-0x81 || c==0xc6-0x81 && d>0x52)
Link to relevant source code: https://git.musl-libc.org/cgit/musl/tree/src/locale/iconv.c (bug fix is line 505).

To explain the bug, EUC_KR is Extended Unicode - Korean. After ASCII characters (0-127), each character is multiple bytes. The logic adjusts to look up from a base-0 index, then checks that both bytes (variables c and d) are in the normalized range. If not, the code adjusts the characters and checks the bounds again. This second check is what contained the bug.

0xc6 - 0x81 is the upper bound of this check (69), not 93. The irony is that the second part of the check gets this correct. I wonder what a `git blame` would reveal about this particular line.

Fun to see someone decide to just write a faster JSON parser because they believed it was possible. They mentioned last year that libjansson had some intermediate layer with Emacs, which led to too many memory allocations: https://lists.gnu.org/archive/html/emacs-devel/2024-03/msg00...

Also, the developer who wrote the parser (Géza Herman) was able to pass all of the tests with strange edge cases from https://seriot.ch/projects/parsing_json.html very quickly: https://lists.gnu.org/archive/html/emacs-devel/2024-03/msg00...

True, I was trying to find the variable storage requirements in the UEFI specification but couldn't (is it Section 3? 8?), so I resorted to linking to the struct definition in the EFI shell package that the author used.

Very interesting. I wonder if this a result of some "swiss cheese" effect due to constraints around UEFI and NVRAM themselves, when updating EFI variables.

NVRAM must maintain atomicity of memory transactions for power failures. Its whole purpose is to store data when you turn your computer off. As a result, when deleteing an EFI variable, you can't manage the individual bytes - you have to delete a whole entry (which can be rather large - based on the EFI specification and the code used for edk2, e.g. https://github.com/tianocore/edk2/blob/83a86f465ccb1a792f5c5...). Deleting these entries might become a problem when you start running against memory constraints and what slots in memory are actually available; hence a possible fragmentation issue.

Additionally, I appreciated how short and specific this blog post was. I enjoy this style of post of someone encountering a problem and solving it.

"The more skilled you are, the less you need advanced tools..."

I wonder how well this claim holds up under strict scrutiny. At a high level, it makes sense: someone who is a master of their craft will understand their tools and how to use them much better than a beginner starting out. However, I think this is a different claim than the one Paolini makes.

One concrete argument against this is the history of technological progress. With each improvement came a step function in the tools available to builders, creators, etc., and those able to master them achieved a new level of ability and progress not seen before.

There is evidence for this everywhere. In sports, athletes today use modern technologies and knowledge to push their bodies and abilites to new levels (low-oxygen training, equipment specialized in each sport, etc.). If you didn't upgrade your golf clubs from wood to titanium, you are going to be left far behind. In other industries, this applies: a specific example might be in welding, where using a multi-process welder will significantly improve your productivity as well as the quality of your work. [1]

In tech, this distinction is also apparent. There are the dual cases of a programmer being completely ineffective with a modern IDE versus Jeff Dean (or insert your favorite programming legend here) with Emacs (or another text editor). However, this does not mean that a great programmer does not require advanced tools. Great toolchains (compilers, linkers, interpreters, debuggers, etc.), advanced computing capabilities (GPUs for LLMs), and high-speed Internet access will dramatically change the quality of your work.

I think that Paolini is more focused on the idea that a master craftsmen, when compared with a beginner, can still handily defeat the beginner using simple tools, as they understand both the tools and what they are trying to accomplish better. I agree with this point, but think that this relative comparison is distinct from the absolute comparison of a master using simple tools vs. the same master using advanced tools.

I appreicate his larger point that you want high-quality (even if simple) tools that you understand and that will last you a lifetime. This is one of the main benefits of mastering free/open source software [2]: freedom 0 of free software is to run a program as you wish, for any purpose, which is not guaranteed when using proprietary software.

[1] https://www.constructionequipment.com/light-equipment/weldin...

[2] https://gwern.net/choosing-software

Is the main idea to convert the model implementation from Python into C, then hardcode all possible values? Do you do this yourself in the generator code, or could you let the C preprocessor/compiler handle something like this by using macros? (might help with compile time/memory)

"NOTE: Ensure the device you are running on has no form of hardware acceleration like GPU or the results will be skewed"

How much does adding GPUs affect your performance improvement gains? I understand that the point of this optimization is for CPU-only machines, but it would be interesting to consider the affect your optimizations have when running on GPUs as well.

From The Register, with more comments by Filip ("Phil") Pizlo (the author): https://www.theregister.com/2024/11/16/rusthaters_unite_filc....

Other memory safe implementations for C and C++ mentioned/proposed are TrapC (https://vimeo.com/1028578347) and Safe C++ (https://safecpp.org/draft.html).

Fil-C adds capabilities and garbage, though it mentions performace costs of 1.5x - 5x. I would think the capabilties aspect of this language extension would be better addressed by hardware proposals (like CHERI) to prevent adding too much overhead to systems that are performance-critical.

Edit: It also looks like the author could use help porting C programs to Fil-C, see https://news.ycombinator.com/item?id=42158296.

(2016)

The comments on this fast range reduction are interesting, I recommend reading them (they're much longer than the post itself). Some highlights:

Versions of this exist as early as 1997, in CMU's Common Lisp implementation. Their GitLab is not loading quicky on my computer, but the commit is supposed to be from December by Douglas Crosher (https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-...).

The "Further reading" section (and comments) include implementations of the trick in the wild. Stockfish, the chess engine, used this optimization to reduce memory for storing precomputations of moves in their transposition tables (https://github.com/official-stockfish/Stockfish/commit/2198c...). The commit switches from using bitwise AND (&) and power-of-2 table sizes to using the modulo hash trick, which allows for full use of RAM (even if it's not an exact power of 2). It's also used in Hashtron's modular hash: https://github.com/neurlang/classifier/blob/master/hash/hash..., a straightforward application of the optimization to avoid using modulo.

A GitHub gist with more information: https://github.com/sipa/writeups/tree/main/uniform-range-ext.... It walks through a couple of intuitive explanations on why this technique maintains maximum uniformity in the output distribution, as opposed to the proof in the post.

More recent revision: https://isocpp.org/files/papers/P2900R10.pdf. It seems like they've added a few things since this draft.

It's somewhat funny to hear "minimum viable product" in the context of a language standard/specification. I'd never thought of adding a feature to a language in that way before.

The idea of design by contract (DbC) in C++ appears to have been around for a while too. The authors link to a "forthcoming companion paper" (currently a 404 error), but you can find proposals from as early as 2004 with the idea: https://www.open-std.org/JTC1/SC22/WG21/docs/papers/2004/n16...

(and potentially earlier, I just haven't seen one yet)

"Classic C++" and "Modern C++" refer to the language before and after C++11, respectively.

Some of the key differences are use of standard library and its containers, smart pointers, and other language features that look less like C. In this specific library, this refers to some of the techniques like bit manipulation, manual memory management and string parsing, and using things like enums to improve speed and reduce complexity.

An example of a more robust (but still "classic") library would be something like https://github.com/Tencent/rapidjson.

In embedded systems with hard real-time requirements, there are several ways to schedule tasks. Once the number of tasks you need to execute grows long enough, scheduling becomes a challenge. An RTOS is one way to manage these tasks with guaranteed, deterministic timing.

A concrete example: if you're in a car (an embedded system doing many things at once) and press the brakes, you want the car to be as responsive as possible. A real-time operating system will sacrifice other features of a general purpose OS to guarantee that the brakes are applied within a specified time interval after you press them.

Also, there are responses to a similar comment from when this was previously posted: https://news.ycombinator.com/item?id=32329499

I wonder - did the US government, specifically DARPA, consider CHERI when laying out their "Translating All C to Rust (TRACTOR)" initiative? The two initiatives could be compatible (memory safety at both the software and hardware level), especially since CHERI might be more feasible when it comes to rewriting legacy software.

I had not considered using a VM instead of strace when a program can detect ptrace(2) being used - good idea.

Normally when reverse engineering a program, it is common to use tracing programs like strace. These tracing programs are quite useful, but they suffer from a design flaw: they use ptrace(2) to accomplish the tracing, which can be detected by the program being traced.

One way to do this would be to call ptrace() from your program and check if it returns the error EPERM. From the man page:

       EPERM  The specified process cannot be traced.  This could be because the tracer has  insufficient  privileges
              (the  required  capability  is CAP_SYS_PTRACE); unprivileged processes cannot trace processes that they
              cannot send signals to or those running set-user-ID/set-group-ID programs, for obvious reasons.  Alter‐
              natively, the process may already be being traced, or (on kernels before 2.6.26) be init(1) (PID 1).
However, this is not the best solution, as if your system has a security policy already in place for ptrace() detection, your process might get detected and killed. Other methods from the calling process might involve timing mechanisms, breakpoint detection, or checking other factors in the process' environment. One problem with the workaround suggested in this post (running a process from qemu-user) is that if it is truly security hardened, it might rely on timing differences smaller than the speed of VM instruction execution.

As a user or sysadmin, one way to detect ptrace is to use Yama [1], a Linux kernel module that creates an entry in /proc/sys/kernel/yama/ptrace_scope to configure a user's desired level of ptrace protection, from 0 (normal - any process can call ptrace() on another process owned by the same user) to 3 (completely disabling ptrace).

[1] https://www.kernel.org/doc/html/latest/admin-guide/LSM/Yama....

Another name for a similar but slightly more pernicious problem is the Gell-Mann Amnesia effect: "the phenomenon of experts reading articles within their fields of expertise and finding them to be error-ridden and full of misunderstanding, but seemingly forgetting those experiences when reading articles in the same publications written on topics outside of their fields of expertise, which they believe to be credible."

https://en.wikipedia.org/wiki/Michael_Crichton#Gell-Mann_amn...

Another related set of differences to appreciate is between before-GMT and after-GMT worlds.

Before standardized time, it was very difficult to coordinate. Most US towns would have their own local time (think church steeples ringing out the hours), and there were 80+ different time standards across the country. In Massachusetts, for example, there were differences between Boston time and Worcester time, two cities that are ~45 miles apart.

Trains had trouble coordinating: if you're using the same sets of tracks, it's essential that you have a very good idea of where trains are going to be. Unfortunately, there were many collisions between trains as a result of mismatched times between the conductors and stations. [1]

In 1849, William Bond (owner of William Bond & Sons’ Boston) partnered with Harvard to offer the first standardized time from Harvard College Observatory. Time standardization between railroads, which started as a voluntary agreement, became mandatory after the Valley Falls collision. [2] As use of the telegraph spread, time standardization began to spread as well.

The idea of a train conductor holding a pocket watch has become quaint now, but it used to be the difference between life and death for passengers. Part of the cause of the Valley Falls collision (and several others) was a train conductor with a faulty pocket watch.

Another interesting rabbit hole to go down is the standardization of the prime meridian, why Greenwich was chosen [3] (hence Greenwich Mean Time [4]), and why the French were so upset about this (part of the reason time today is called UTC). Part of the reason GMT is the standard has to do with what Sobel discusses at the end of the book [5]: Nevil Maskelyne, the primary antagonist, published The Nautical Almanac, which was for many years the primary reference of sailors across the globe when determining time. All measurements for that book were taken from Greenwich; hence, when governments went to standardize a prime meridian, Greenwich was the obvious choice.

Harvard’s Collection of Historical Scientific Instruments has a fun collection of clocks that illustrate the challenges related to this. [6] It's a small but underrated museum when looking at places to go in Cambridge.

[1] https://news.harvard.edu/gazette/story/2011/11/americas-firs...

[2] https://en.wikipedia.org/wiki/Valley_Falls_train_collision

[3] https://en.wikipedia.org/wiki/Prime_meridian#Prime_meridian_...

[4] https://en.wikipedia.org/wiki/Greenwich_Mean_Time

[5] I don't remember if Sobel discussed this or not in the book

[6] https://chsi.harvard.edu/

A decent, short book on the historical story behind H4 (and the rest of Mr. Harrison’s time-keepers) is “Longitude: The True Story of a Lone Genius Who Solved the Greatest Scientific Problem of His Time” by Dava Sobel. It goes into the longitude competition, the people involved, and how Harrison was able to (eventually) win with his timekeepers.

There are several other good resources on the M-209.

Short cryptanalysis of M-209: http://www.jfbouch.fr/crypto/m209/cryptanalysis.html

Series on how to use the machine: https://www.nf6x.net/2013/03/practical-use-of-the-m-209-ciph...

Paper by James Reeds, Robert Morris and Dennis Ritchie analyzing its security from 1978: https://cryptome.org/2015/12/ReedsTheHagelinCipherBellLabs19...

Apparently the paper by Morris and Ritchie was not supposed to be published; it was instead a technical note. See Ritchie's account: https://www.bell-labs.com/usr/dmr/www/crypt.html

I enjoy Matt Levine's facsincation with the business of ransomware. He wrote a post early last year [0] on LockBit's business model and how the optimal amount of crime for them to commit is close to, but not quite 100%. It appears they may have tipped too far in the "too much crime" direction.

Another good look at LockBit is an investigative report [1] that goes in depth on how they've survived for so long.

[0] http://catless.ncl.ac.uk/risks/go/33/60/7

[1] https://redsense.com/publications/lockbit-story-a-three-year...

Paul Lockhart's "A Mathematician's Lament" [1] is the work that inspired his book, "Measurement" [2], which this video covers. I've always enjoyed it as a portrayal of the yin and yang of mathematics, calculating equations vs. proving them. The American education system overindexes on calculations, which, as Lockhart points out, tend to drown out the deeper joy that comes with mathematics. It's fascinating to see the battle between rote calculation and discovery play out at all levels, from students who feel that they "don't get math", to former olympiad medalists who struggle in graduate school.

[1] https://www.ams.org/notices/201304/rnoti-p461.pdf

[2] A preview: https://www.hup.harvard.edu/file/feeds/PDF/9780674067349_sam...

Terence Tao on O1 2 years ago

But no one really show how they're actually solving problems with LLMs and how the alternatives were worse for them. It's all claims that it's great with no further elaboration on the workflows.

To give an example, one person (a researcher at DeepMind) recently wrote about specific instances of his uses of LLMs, with anecdotes about alternatives to each example. [1] People on HN had different responses with similar claims with elaborations on how it has changed some of their workflows. [2]

While it would be interesting to see randomized controlled trials on LLM usage, hearing people's anecdotes brings to mind the (often misquoted) phrase: "The plural of anecdote is data". [3] [4]

[1] https://nicholas.carlini.com/writing/2024/how-i-use-ai.html

[2] https://news.ycombinator.com/item?id=41150317

[3] http://blog.danwin.com/don-t-forget-the-plural-of-anecdote-i...

[4] originally misquoted as "Anecdote is the plural of data."

A recent defense of the Bayesian approach: https://www.astralcodexten.com/p/in-continued-defense-of-non... (and Kling's response: https://arnoldkling.substack.com/p/what-is-probability)

Likelihood statistics is another approach that combines the classical and Bayesian approaches. Its main benefit is that it does not rely on prior probabilities about an event. Instead, you can use MLE (maximum likelihood estimation, https://en.wikipedia.org/wiki/Maximum_likelihood_estimation) to estimate your parameter, with certain guarantees based on which estimator you choose for the parameter and how you calculate it. The downside of this approach is that it requires a strong assumption: that you know the distribution of outcomes in advance.

Side note: the only time you'll know the population parameter is if you set it yourself (i.e., in a simulation).

edit: Title should also probably be changed to the article's title ("How I Teach Statistics")