Juho Snellman
snellman.net · Personal blog · on HN since 2014
Juho Snellman, a software engineer, writes about networking, Lisp history, data structures, puzzle generation, and past jobs.
What HN saysHN commenters link his posts on the XXX/FIXME origin and the procedural puzzle generator, and point to his Terra Mystica web implementation.
56HN people shared it
31linked it in comments
56stories submitted
4.1Kstory points
10 months agolast shared
2014people per year2026
Most-shared posts
- 1LLMs are cheap8 people · 361 points · first shared 2025 · 309 comments on HN
- 2Numbers and tagged pointers in early Lisp implementations7 people · 97 points · first shared 2017 · 21 comments on HN
- 3The most obsolete infrastructure money could buy – my worst job ever6 people · 474 points · first shared 2015 · 238 comments on HN
- 4Writing a Procedural Puzzle Generator5 people · 73 points · first shared 2019 · 17 comments on HN
- 5TCP is harder than it looks5 people · 22 points · first shared 2014 · 2 comments on HN
- 6I've been writing ring buffers wrong all these years4 people · 529 points · first shared 2016 · 167 comments on HN
- 7Hanging S3 downloads4 people · 236 points · first shared 2017 · 37 comments on HN
- 8The origins of XXX as FIXME4 people · 196 points · first shared 2017 · 86 comments on HN
- 9Why PS4 downloads are so slow3 people · 716 points · first shared 2017 · 192 comments on HN
- 10Unit testing a TCP stack (2015)3 people · 232 points · first shared 2015 · 35 comments on HN
- 11Mobile TCP optimization – lessons learned in production3 people · 116 points · first shared 2015 · 11 comments on HN
- 12The hidden cost of QUIC and TOU (2016)3 people · 107 points · first shared 2016 · 60 comments on HN
- 13Ratas – A hierarchical timer wheel3 people · 82 points · first shared 2016 · 12 comments on HN
- 14Use Cases for Change-Class in Common Lisp3 people · 39 points · first shared 2015 · 15 comments on HN
- 15Command languages as game user interfaces3 people · 38 points · first shared 2015 · 4 comments on HN
What HN people wrote when they linked it
aurareturn · 2025-11-29
ChatGPT’s revenue means nothing if reports are to be believed that it loses money on each paying customer on just inference. It’s definitely not enough to support its training costs. Sam Altman: We're very profitable on inference. https://simonwillison.net/2025/Aug/17/sam-altman/#:~:text=Subscribe,20…
Independent analysis: Inference is very profitable. https://martinalderson.com/posts/are-openai-and-anthropic-really-losin… https://www.snellman.net/blog/archive/2025-06-02-llms-are-cheap/
slongfield · 2025-07-22
It has some ancient history as a morse code distress signal: https://regulatorylibrary.caa.co.uk/923-2012/Content/Regs/03800_1._DIS…
And it shows up in some old BSD code: https://www.snellman.net/blog/archive/2017-04-17-xxx-fixme/
But... I think repeated letters are just easier to type than any other string, and since X looks like the classic "marks the spot" logo, it's what people jump to.
bostik · 2024-11-22
This particular case would be a fantastic fit for timer wheel.[0] Instead of writing a brittle implementation of "after a fixed time in the future" logic yourself, you queue the outgoing event to occur after N ticks [of granularity X], and let the dedicated data structure engine do the work for you.
0: https://www.snellman.net/blog/archive/2016-07-27-ratas-hierarchical-ti…
jsnell · 2019-12-19
The puzzle generator is described in the following blog post:
https://www.snellman.net/blog/archive/2019-05-14-procedural-puzzle-gen…
samdk · 2017-11-29
This is not the same thing, but you might be interested in taking a look at the excellent online Terra Mystica implementation (https://terra.snellman.net/) if you haven't seen it already.
It's a web interface, but the underlying representation is text-based, and you can type in the commands directly if you want. This leads to some nice features--for example, you can plan your moves several steps ahead of time, and you get a game log for free.
There creator wrote a blog post about that particular design decision: https://www.snellman.net/blog/archive/2014-12-08-command-languages-as-…
sanxiyn · 2014-12-28
I don't write a TCP stack, but Juho Snellman writes a TCP stack for living, and I found the following anecdote on writing an interoperable TCP stack interesting.
http://snellman.net/blog/archive/2014-11-11-tcp-is-harder-than-it-look…
TLDR: There are TCP implementations that can't handle SYN retransmission which you have to interoperate if your TCP stack is the product.
logicprog · 2025-10-05
> This isn't like the early days of the web, or Amazon, or any of those other big winners that lost money before becoming profitable. Those were all propositions with excellent "unit economics" – they got cheaper with every successive technological generation, and the more customers they added, the more profitable they became. AI companies have – in the memorable phraseology of Ed Zitron – "dogshit unit-economics." Each generation of AI has been vastly more expensive than the previous one, and each new AI customer makes the AI companies lose more money...
See, I think this is wrong. The unit economics of LLMs are great, and more than that, they have a fuckton of users with obvious paths to funding for those users that aren't paying per unit (https://www.snellman.net/blog/archive/2025-06-02-llms-are-cheap/). The problem is the ludicrous up front over infestment, none of which was actually necessary to get to useful foundation models, as we saw with DeepSeek.
jauntywundrkind · 2023-08-01
I personally think the upsides of WebBundles are huge. There's nothing that would stop the browser from being able to filter & ignore content coming from in a WebBundle, so I'm not sure what Brave's greivance is here. The adserving topic is complicated as heck, but everyone seems to acknowledge big change is necessary & Google and Firefox both have proposals to radically overhaul the system while enhancing user privacy; Brave's own primary distinguisher at this point is their BAT tokens, their own answer here. There's complicated topics here, but I see Brave following the standard pattern of trying to be a lightning rod of discontent.
It's also surprising to me how almost no one has commented on Private Access Tokens shipping for Apple. Which do the same thing. Here's them bragging about being able to avoid catchpa's since the devices are all vouched for by Apple as unmodified & controlled by Apple: https://developer.apple.com/videos/play/wwdc2022/10077/
There was a decent submission on this recently, but not much engagement. https://www.snellman.net/blog/archive/2023-07-25-web-integrity-api-vs-… https://news.ycombinator.com/item?id=36866355
I think this is absolutely the worst shit, almost as bad as MV3 being a utterly neutered shitty hell hole version of what web extensions were. But it's notable to me that both Google didn't start this particular trend, Apple did, and more broadly - I have such a hard time picking words here - it feels like the…
SigmundA · 2020-02-29
>And whatever you otherwise think about those languages, none of them will just make shit up when there is a syntax error in your program, they will simply reject it. And no, that does not mean that I am claiming that noone has ever made a syntactical mistake when writing code in those languages. But, you know, people are actually capable of fixing those mistakes when they are pointed out to them.
Except its pretty common now for programming languages add quality of life changes that loosen some of the strict parsing rules, such as trailing commas or optional semi colons. Same with whitespace, many languages don't pay much attention to it then you have a formatter that is strict about it (gofmt). This is Postels law in action, liberal acceptance strict output. The alternative is strict adherence to whitespace then no need for a formatter, just have the compiler reject it and put the burden on the programmer.
>Also, obviously, the "robustness principle" did not allow for a graceful update to the spec.
Again your opinion is not shared historically, ECN is held up as an example of the robustness principle having been followed in most stacks, with some problem ones that did not causing some issues [1].
>Then your points are just irrelevant?
Then your points are just irrelevant? We can play this game forever. Just the fact the you are using HTML and not XHTML and TCP under that to write these should make some relevant point that you can't seem to see.
>Yes, it was obvious…
praptak · 2025-09-22
Pointer tagging is at least as old as Lisp: https://www.snellman.net/blog/archive/2017-09-04-lisp-numbers/
haiku2077 · 2025-07-15
https://www.snellman.net/blog/archive/2025-06-02-llms-are-cheap/, also note the "objections" section
Anecdotally thanks to hardware advancements the locally-run AI software I develop has gotten more than 100x faster in the past year thanks to Moore's law
miles · 2021-07-05
> When Jason Snell posts on HN, I sit up in my chair
I believe the post is from Juho Snell:
http://www.snellman.net/blog/archive/about/
https://twitter.com/juhosnellman
db48x · 2019-07-01
Only because the computer it was on already had a tag field in every word. Other implementations of Lisp did similar things though: https://www.snellman.net/blog/archive/2017-09-04-lisp-numbers/
tonyg · 2018-10-21
Because objects in Smalltalk encapsulate their representation, it's not possible (without using reflection) to figure out exactly how an object represents itself. So things that would be primitives in other languages, like small integers, are in Smalltalk ordinary objects like anything else. The language works hard to present a 'uniform object model'.
However! When the rubber meets the road, there has to be some kind of bit-level representation somewhere. In Smalltalk, the VM hides these details from the programmer, who gets to reason uniformly about objects without caring about their representation. Specifically, Smalltalk VMs often use pointer tagging [0] just like lots of other dynamic languages do.
[0] Lots of interesting stuff on pointer tagging here: https://www.snellman.net/blog/archive/2017-09-04-lisp-numbers/
fsiefken · 2018-02-09
Coincidentally came across this while looking up a board game: "The hidden costs of QUIC and TOU"
https://www.snellman.net/blog/archive/2016-12-01-quic-tou/
junke · 2017-09-04
This seems to be relevant ;-)
https://www.snellman.net/blog/archive/2017-09-04-lisp-numbers/
hydandata · 2017-07-29
Also check out https://www.snellman.net/blog/archive/2015-07-27-use-cases-for-change-… for some really interesting, but niche, things you can do to classes.
saminiir · 2017-07-06
Very interesting and yes, interoperability is hard.
https://www.snellman.net/blog/archive/2014-11-11-tcp-is-harder-than-it…
lispm · 2017-01-20
Because no one wrote one. There were some attempts but nothing which would work now. Delivering small applications does not seem to be a focus of SBCL users.
https://www.snellman.net/blog/archive/2005-07-06.html
There is also the possibility to compress the image. See :compression option when saving an image:
http://www.sbcl.org/manual/#index-g_t_0040sbext_007bsave_002dlisp_002d…
Commercial Lisp implementations like LispWorks and Allegro CL have a treeshaker for delivery, but that's not too surprising, since these products are for developers of applications and the users pay for such features.
jessaustin · 2016-12-15
Why is push() checking for overlap? I thought not caring about that was the point of a ring buffer?
[EDIT:] To clarify for those who didn't (couldn't?) read TFA's first sentence, it specifically invokes "I've been writing ring buffers wrong all these years" [0], recently featured on HN.
[0] https://www.snellman.net/blog/archive/2016-12-13-ring-buffers/
SloopJon · 2015-09-22
It doesn't look like Google's paper or the results on this site consider CloudFlare's zlib fork:
https://github.com/cloudflare/zlib
Previously discussed here:
https://news.ycombinator.com/item?id=9857784
And a recent performance comparison with Intel's patches:
https://www.snellman.net/blog/archive/2014-08-04-comparison-of-intel-a…
lmz · 2015-05-19
Unrelated: the previous post on that blog about Finnish election candidate-matching websites is quite fascinating: https://www.snellman.net/blog/archive/2015-05-11-okcupid-for-voting-th…
ej88 · 2025-08-27
Not really sure how this article refutes what I said?
He defines it as "everything that happens from when you put a prompt in to generate an output" -> but he seems to conflate inference with a query. Putting in input to generate the next single token is inference. A query or response just means the LLM repeats this until the stop token is emitted. (Happy to be corrected here)
The cost of inference per token is going down - the cost per query goes up because models consume more tokens, which was my point.
Either way, charging consumers per token pretty much guarantees that serving models is profitable (each of Anthropic's prior models turn a profit). The consumer-friendly flat 20$ subscription is not sustainable in the long run.
https://epoch.ai/data-insights/llm-inference-price-trends
https://www.snellman.net/blog/archive/2025-06-02-llms-are-cheap/
https://x.com/eladgil/status/1827521805755806107
bazzargh · 2023-08-31
you don't need to run the puzzle backwards to generate solvable positions, you run it forwards and generate the pieces from the solution moves.
Starting with the piece and square from the previous board, mark all squares but this one as unknown. Make a random move. Any unknown squares passed through get marked blank in the current board and in the puzzle. Randomly choose to keep the same piece (making this square blank in the puzzle) or switch (marking the chosen piece in the puzzle, but now blank in the current board). Continue making random moves (biasing slightly towards choosing unknown squares), eventually stop and randomly assign the remaining unknowns as obstactles or blanks. Because you've said you don't care if there's only one solution, this gives you solvable puzzles trivially.
This isn't a new idea, eg https://www.snellman.net/blog/archive/2019-05-14-procedural-puzzle-gen… talks about generating solvable puzzles using the forward moves, you'd generally pair it with a filter that weeds out puzzles that are not fun for some reason (eg, solutions that random walk blank squares; these can be avoided at generation time by having a budget for move-to-blank)
takoid · 2022-09-17
https://jrock.us/
https://jgc.org/
http://kaledavis.com/
https://aegir.sexy/
https://www.gwern.net/
https://jacquesmattheij.com/
https://danwin.com/
https://www.kalzumeus.com/
https://www.magic.do/
https://edweissman.com/
https://jakeseliger.com/
http://www.fogus.me/
https://www.stavros.io/
https://jasonlefkowitz.net/
https://minimaxir.com/
https://www.robinwhittleton.com/
https://ciexinc.com/
https://rongarret.info/
https://williampietri.com/
https://bpier.re/
https://joshtriplett.org/
https://ooer.com/
https://feross.org/resume/
https://www.brandons.me/
https://benjaminpbreen.com/
http://hokstad.com/
https://www.scott-a-s.com/
https://www.bermita.com/
http://tlrobinson.net/
https://ldpreload.com/
https://dotat.at/
http://xavvy.com/
https://correa.in/
https://adriann.github.io/
https://leclan.ch/
https://joeyespo.com/
https://pius.me/
https://adamierymenko.com/
https://drewdevault.com/
https://battlepenguin.com/
https://chris.improbable.org/
https://www.snellman.net/
https://ocdtrekkie.com/
https://www.cryptolotus.com/
https://www.gregkogan.com/
https://david.kitchen/
In no particular order. From: https://jessimekirk.com/blog/hn_users_links/. I went through about half of the list looking for personal websites to use as inspiration for my own.
jeroenhd · 2022-05-02
I don't know if this is the exact incantation, but some IDE extensions will recognise some special comment annotations. TODO/FIXME support is in pretty much every IDE, but there are some special codes that some IDEs will recognise.
Visual Studio (not necessarily Code) will recognise TODO, HACK, NOTE and UNDONE, for example.
Java conventions mention XXX: https://www.oracle.com/java/technologies/javase/codeconventions-progra…
10.5.4 Special Comments
Use XXX in a comment to flag something that is bogus but works. Use FIXME to flag something that is bogus and broken.
Using XXX in comments goes back to 1978, according to https://www.snellman.net/blog/archive/2017-04-17-xxx-fixme/
I'm not a huge fan of XXX as a warning, there are more descriptive names in caps available that your IDE will probably even autocomplete after using them for a while. However, the practice is common enough that it's just a General Programmer Thing, kind of like how some people prefer /* */ over // because they're just more used to it.
toast0 · 2021-02-19
Most physical transports don't pad packets to the maximum size. Ethernet only pads if you're below 46 bytes of payload, which is smaller than TCP packets with TCP timestamps; so if you're on Ethernet and have TCP timestamps enabled (which is very common), you'll certainly see the savings from any bytes removed from your certificate; unless your TLS layer is padding out to (path) MTU.
Assuming that's in the neighborhood of a 20 byte savings, it's not very significant. Using EC keys rather than RSA keys if possible is a bigger savings. And disabling TCP Timestamps, which add 12 bytes per packet (including ACKs) would be bigger still[1].
That said, shaving off bytes wherever possible adds up.
[1] I've heard that disabling TCP Timestamps may disable receive window scaling on iOS (and maybe macos), see [2] for a report. It's also very useful to avoid problems with wrapped sequence numbers if your (bytes/time * assumed maximum segment lifetime) is anywhere near 32-bits; this usually requires around a gigabit on a single TCP connection. As the link mentions, tcp timestamps do make retransmits have different content than the original send, which can incidentally help if you have broken networking equipment on your path, depending on the details of the brokenness.
[2] https://www.snellman.net/blog/archive/2017-07-20-s3-mystery/
panic · 2017-07-25
Here are a bunch of blogs from my RSS reader that I think are worth reading. Some of them haven't updated in a while, but the archives may be worth a look anyway.
* Blogs with a math focus:
http://blog.sigfpe.com
http://bit-player.org
http://mathr.co.uk/blog/
https://www.johndcook.com/blog/
* Blogs with a programming languages focus:
https://existentialtype.wordpress.com
https://bluishcoder.co.nz
http://blog.ezyang.com
http://akkartik.name
http://lambda-the-ultimate.org
http://mrale.ph
* Blogs with a UI design focus:
http://www.brandonwalkin.com/blog/
http://ignorethecode.net/blog/
http://interuserface.net
* Blogs with a graphics / 3D rendering focus:
http://c0de517e.blogspot.com
http://diaryofagraphicsprogrammer.blogspot.com
https://directtovideo.wordpress.com
http://graphicrants.blogspot.com
http://www.reedbeta.com
http://www.realtimerendering.com/blog/
https://blog.demofox.org
http://eelpi.gotdns.org/blog.wiki.html
* Other interesting / more general programming blogs (many of these have a "systems" focus):
http://danluu.com
http://ewontfix.com
http://chneukirchen.org/blog/
http://neverworkintheory.org
http://apenwarr.ca/log/
https://www.snellman.net/blog/
https://www.pvk.ca
http://psy-lob-saw.blogspot.com
https://randomascii.wordpress.com
http://fastcompression.blogspot.com
https://fgiesen.wordpress.com
http://blog.plover.com
http://chneukirchen.org/trivium/
http://rachelbythebay.com/w/
hyperpape · 2016-05-24
Every so often, I think about the meme of the 100 year language. The idea is that we need to start working towards the languages we'll use in 100 years. Instead, I wonder how many we already have.
Fortan: 59
C: 43
C++: 33
Python: 25
Php: 21
Javascript: 20
Java: 20
It's still a long time until any of those languages reach 100. But longevity seems to be the rule, not the exception. How many languages that were widespread actually died?[0] I don't pretend to know all the languages that have ever been popular, but not many that subsequently died come to mind. Cobol, maybe some lisp dialects, if you don't count Common Lisp as their successor? Is PL/1 dead? Was APL big enough to make the list?
Probably some of the languages I listed above will die before they're 100. Others might be niche, like Fortran already is. But I wouldn't guarantee it.
[0] Where dead doesn't rule out someone being paid to maintain ancient code. By that standard, it's unclear whether anything will ever die (https://www.snellman.net/blog/archive/2015-09-01-the-most-obsolete-inf…
nl · 2025-12-24
Lots of sources, and you can do the math yourself.
Here's a few good ones:
https://github.com/deepseek-ai/open-infra-index/blob/main/202502OpenSo… (suggests Deepseek is making 80% raw margin on inference)
https://www.snellman.net/blog/archive/2025-06-02-llms-are-cheap/
https://martinalderson.com/posts/are-openai-and-anthropic-really-losin… (there's a HN discussion of this where it was pointed out this overestimates the costs)
https://www.tensoreconomics.com/p/llm-inference-economics-from-first (long, but the TL;DR is that serving Lllama 3.3 70B costs around $0.28/million tokens input, $0.95 output at high utilization. These are close to what we see in the market: https://artificialanalysis.ai/models/llama-3-3-instruct-70b/providers?… )