10 interesting stories served every morning and every evening.

Blocked

old.reddit.com

whoa there, pard­ner!

Your re­quest has been blocked due to a net­work pol­icy.

Try log­ging in or cre­at­ing an ac­count here to get back to brows­ing.

If you’re run­ning a script or ap­pli­ca­tion, please reg­is­ter or sign in with your de­vel­oper cre­den­tials here. Additionally make sure your User-Agent is not empty and is some­thing unique and de­scrip­tive and try again. if you’re sup­ply­ing an al­ter­nate User-Agent string, try chang­ing back to de­fault as that can some­times re­sult in a block.

You can read Reddit’s Terms of Service here.

If you think that we’ve in­cor­rectly blocked you or you would like to dis­cuss eas­ier ways to get the data you want, please file a ticket here.

When con­tact­ing us, please in­clude your Reddit ac­count along with the fol­low­ing code:

019eea62 – 7613-7ff7-a698 – 85c31e074bc3

Did my old job only exist because of fraud? – It's not about code

david.newgas.net

Early in my soft­ware en­gi­neer­ing ca­reer, the UK-based startup I worked at, GenieDB, was taken over by a US Venture Capital fund, Frost VP, owned by Stuart Frost. I was func­tion­ally the only piece that came to the US. The code was re­built, the rest of the team even­tu­ally ro­tated out, even the core strat­egy was re­placed. But I was early in my ca­reer and ex­cited to be work­ing in the VC tech-startup world. I ended up mak­ing my life in the US, so this was a pretty piv­otal phase in my life.

For a while I lived the start-up life: build­ing rapidly and play­ing Foosball1. GenieDB ac­tively re­jected rev­enue op­por­tu­ni­ties (a la Silicon Valley) with the aim of get­ting ac­quired for pi­o­neer­ing tech­nol­ogy. We limped along for years with never more than 3 cus­tomers, even when big-tech and even­tu­ally open-source did what we tried to do bet­ter than us. I left with mixed feel­ings and even­tu­ally came to re­al­ize we never had the se­ri­ous foot­ing it would have taken to ac­tu­ally de­velop sig­nif­i­cant tech­nol­ogy.

A decade later I heard from a for­mer col­league that Frost was be­ing sued by the SEC for fraud. Still not sure what to make of my time at GenieDB, I was cu­ri­ous enough to skim the com­plaint, where I saw this line:

Was GenieDB in­volved in this fraud some­how? I chewed on this ques­tion and it evolved to a form that be­gan to haunt me:

Did my old job — the one that brought me to the USA and changed the course of my en­tire life — only ex­ist be­cause of fraud?

Did my old job — the one that brought me to the USA and changed the course of my en­tire life — only ex­ist be­cause of fraud?

With this burn­ing ques­tion I dove into the record of the case. The al­leged fraud was sim­ple: Frost VP op­er­ated as an in­cu­ba­tor, pro­vid­ing ser­vices to the port­fo­lio com­pa­nies, and the in­vestors say these fees charged were ex­ces­sive.

The case went to bind­ing ar­bi­tra­tion2 and the in­vestors won, af­ter which the SEC sued to bar Frost from man­ag­ing funds in the fu­ture. There’s some great el­e­ments like claim­ing a per­sonal chef and cleaner as ex­penses, telling in­vestors no salary would be paid by the fees (it was) and start­ing a mar­ket­ing com­pany just to spon­sor some­one’s visa.

But what about GenieDB? Both the ar­bi­tra­tion and SEC suit elab­o­rate on this idea of cre­at­ing com­pa­nies just to charge them fees:

This al­le­ga­tion was never lit­i­gated though, nei­ther court nor ar­bi­tra­tor were kind enough to rule on why GenieDB was in the port­fo­lio. I had to dive into the ev­i­dence and de­cide for my­self. First of all, my old CEO tes­ti­fied that GenieDB was pay­ing ex­ces­sive fees:

I was only re­ally shaken when I saw what the in­sid­ers at the VC fund say­ing to each other:

To me, this email shows that the in­vest­ments were mo­ti­vated by the fees3 and GenieDB was be­ing used to siphon in­vestor money away. I felt like an ant. My ca­reer, my fam­ily, my cit­i­zen­ship all would be com­pletely dif­fer­ent ex­cept for this fraud. This story plays out be­tween in­vestors, multi-mil­lion­aire VCs, judges, and my en­tire life is­n’t even a foot­note.

I took a deep breath. GenieDB did have a con­cept at the core, which pre-dated Frost turn­ing his eyes on us. A con­cept which turned out to be quite use­ful when more se­ri­ous play­ers took it on. My col­leagues and I were re­ally try­ing to build it, even if the fund man­ager was eat­ing up our run­way with spu­ri­ous fees for his per­sonal gain. I was­n’t just some in­stru­ment of fraud work­ing on noth­ing.

Besides, tur­bu­lence from chance events, light­hearted de­ci­sions and even crime al­ters the course of every life. Stories of chance meet­ings of a spouse are dime-a-dozen. I just looked in my wake and was sur­prised by a dark cur­rent.

Amusingly Foosball abil­ity re­flected the cor­po­rate hi­er­ar­chy. Stuart Frost was hands down the best. His sec­ond in com­mand a close sec­ond, and GenieDB’s CEO could beat any of us pro­gram­mers. ↩︎

In fact Frost ac­tu­ally ini­ti­ated the ar­bi­tra­tion be­cause he al­leged the in­vestors were con­spir­ing against him. The coun­ter­claim laid out the fraud. ↩︎

With Genie com­ing out” here is re­fer­ring to GenieDB dis­solv­ing and not pay­ing fees to the in­cu­ba­tor any more. GenieDB is­n’t one of the com­pa­nies they are propos­ing here. ↩︎

Beyond All Reason ★ RTS

www.beyondallreason.info

Real-Time Strategy

Redefined

Every unit, pro­jec­tile and ex­plo­sion sim­u­lated in real-time

Unmatched

Scale & re­al­ism

All units and pro­jec­tiles are sim­u­lated in real-time. The game of­fers fully sim­u­lated pro­jec­tile bal­lis­tics, ex­plo­sion physics and ter­rain de­for­ma­tion.

Enjoy an im­mer­sive RTS ex­pe­ri­ence, whether you are com­mand­ing in­di­vid­ual units, or armies of thou­sands. Take con­trol as you en­gage in an epic strug­gle for dom­i­na­tion!

ScreenshotsGameplay

Strategic

Importance of ter­rain

The shape of every bat­tle­field in-game im­poses which strate­gies work and which units are ef­fec­tive. No two maps will play the same. Radar can­not pen­e­trate moun­tains and nu­clear war­fare will phys­i­cally al­ter the ter­rain.

Utilize over 10 dif­fer­ent unit classes, in­clud­ing all-ter­rain Experimental units, to work your way to vic­tory.

Learn how to Play

Countless

World-class con­trols

Your power lies in the care­ful bal­ance of ex­po­nen­tially grow­ing your re­source in­come and the pro­duc­tion of dev­as­tat­ing war ma­chines.

You de­cide if you want to dis­arm your en­e­mies with a few pre­cise early strikes or to build a thou­sand bombers and oblit­er­ate them.

Immerse your­self in a vi­o­lent world where tac­ti­cal and strate­gi­cal su­premacy are needed in your fight to­wards vic­tory.

Commands Overview

Relentless game de­sign

Unique and with a pur­pose

Each and every unit in the game has a role to fill. Mix-and-match units to cre­ate in­fi­nite pos­si­ble tac­tics. Experiment with your own com­bi­na­tions and show off the new strate­gies you de­velop in bat­tle.

Compare Units

Desktop apps

docs.deno.com

deno desk­top turns a Deno pro­ject (anything from a sin­gle TypeScript file to a Next.js app) into a self-con­tained desk­top ap­pli­ca­tion. The out­put is a re­dis­trib­utable bi­nary that bun­dles your code, the Deno run­time, and a web ren­der­ing en­gine into one bun­dle per plat­form.

Coming in Deno 2.9

deno desk­top ships in Deno v2.9.0 and is not in a sta­ble re­lease yet. To try it now, run deno up­grade ca­nary to in­stall the ca­nary build. The com­mand, con­fig­u­ra­tion keys, and TypeScript APIs may still change be­fore the fea­ture is sta­ble.

Why deno desk­top Jump to head­ing

Web tech­nol­ogy is the most widely-known UI toolkit in the world. Desktop apps built on web stacks (Electron, Tauri, Electrobun) take ad­van­tage of that, but each has trade­offs you have to live with: huge bi­na­ries, miss­ing plat­form sup­port, no JavaScript ecosys­tem, no built-in up­date story, no frame­work in­te­gra­tion.

deno desk­top is opin­ion­ated about those trade­offs:

Small by de­fault, full Node com­pat­i­bil­ity. The de­fault WebView back­end uses the op­er­at­ing sys­tem’s own we­b­view for small bi­na­ries, and you still have the en­tire npm ecosys­tem avail­able through Deno’s Node com­pat layer. Opt into the bun­dled Chromium (CEF) back­end when you need iden­ti­cal ren­der­ing across ma­cOS, Windows, and Linux.

Framework auto-de­tec­tion. Point deno desk­top at a Next.js, Astro, Fresh, Remix, Nuxt, SvelteKit, SolidStart, TanStack Start, or Vite SSR pro­ject and it runs: the pro­duc­tion server in re­lease mode, the dev server with hot re­load un­der –hmr. No code changes are re­quired to take an ex­ist­ing web pro­ject to the desk­top.

In-process bind­ings in­stead of IPC. Backend and UI com­mu­ni­ca­tion goes through in-process chan­nels, not socket-based IPC. Values are still en­coded as they cross the call bound­ary, but there is no cross-process round-trip be­tween your Deno code and the we­b­view.

Cross-compile from one ma­chine. The same ma­chine can build for ma­cOS, Windows, and Linux. Backends are down­loaded as needed, not built lo­cally.

Built-in bi­nary-diff auto-up­date. Ship a sin­gle lat­est.json man­i­fest and bs­d­iff patches; the run­time polls, ap­plies, and rolls back au­to­mat­i­cally on failed launches.

Hello, desk­top Jump to head­ing

Create a one-file desk­top app:

main.ts

Deno.serve(() => new Response(“<h1>Hello, desk­top</​h1>”, { head­ers: { content-type”: text/html” }, }) );

>_

deno desk­top main.ts

The com­piled bi­nary opens a win­dow pointed at a lo­cal HTTP server bound to your Deno.serve() han­dler. Run it di­rectly:

>_

./main # ma­cOS / Linux .\main.exe # Windows

Deno.serve() au­to­mat­i­cally binds to the ad­dress the we­b­view nav­i­gates to, so you do not need to pass a port or host­name. See HTTP serv­ing for de­tails.

What’s in this sec­tion Jump to head­ing

Configuration: the desk­top block in deno.json.

Backends: CEF, we­b­view, raw; how to choose.

HTTP serv­ing: Deno.serve() in­te­gra­tion and the serv­ing model.

Frameworks: Next.js, Astro, Fresh, Remix, Nuxt, SvelteKit, and oth­ers.

Windows: Deno.BrowserWindow life­cy­cle, mul­ti­ple win­dows, events.

Bindings: call­ing Deno code from the we­b­view via bind­ings.<name>().

Menus: ap­pli­ca­tion and con­text menus.

Tray and dock: sys­tem sta­tus icons and the ma­cOS dock.

Dialogs: prompt(), alert(), con­firm() as na­tive pop­ups.

Notifications: na­tive OS no­ti­fi­ca­tions via the Web Notification API.

Hot mod­ule re­place­ment: –hmr for frame­work and non-frame­work apps.

DevTools: uni­fied DevTools at­tached to both the Deno run­time and the we­b­view.

Auto-update: Deno.autoUpdate(), man­i­fests, bs­d­iff, roll­back.

Error re­port­ing: cap­tur­ing un­caught ex­cep­tions and pan­ics.

Distribution: cross-com­pi­la­tion, out­put for­mats, in­stallers.

Comparison: how deno desk­top re­lates to Electron, Tauri, Electrobun, Dioxus.

deno desk­top CLI ref­er­ence: the com­mand, its flags, and the deno.json desk­top schema.

Fully Open Foundation Model for Sovereign AI

apertvs.ai

Developed by the Swiss AI Initiative as a col­lab­o­ra­tive ef­fort be­tween EPFL, ETH Zurich, and CSCS. Open weights, open data, open sci­ence.

Fully Open

Training data, code, weights, meth­ods, and align­ment prin­ci­ples — all doc­u­mented and re­pro­ducible. Apertus is to AI as Open is to Source.

Compliant at Scale

Built to meet EU AI Act re­quire­ments: the model re­spects opt-outs, re­moves PII, pre­vents mem­o­riza­tion. A global foun­da­tion to build on.

Run for Performance

Competitive with top open mod­els at an equiv­a­lent scale of 8B and 70B pa­ra­me­ters. Multilingual from day one — trained on 1000+ lan­guages.

Swisscom is a Strategic Partner of the Swiss AI Initiative.

Stay Updated

Our newslet­ter will keep you on top of Apertus re­leases, our team’s re­search, and com­mu­nity news.

help i accidentally a wigglegram

lmao.center

Do you know what a wig­gle­gram is?

It is a kind of stereo im­age you make by loop­ing frames to­gether, like as a GIF.

The ef­fect is quite con­vinc­ing.

I am some­thing of an in­de­ci­sive pho­tog­ra­pher and when I like an an­gle I will take a lot of frames, from slightly dif­fer­ent an­gles etc., look­ing for the shot”. And since I am also a bit of a hoarder I never clear out my cam­era roll.

Same shot from dif­fer­ent an­gles”? You know what that sounds a bit fa­mil­iar.

Sure enough my phone is full of wig­gle­grams that I took by ac­ci­dent. Years’ worth, wait­ing for me to sit down and stitch them to­gether.

Or, per­haps, for some­thing to stitch them to­gether. It oc­curred to me last week­end that I can use per­cep­tual hash­ing - what TinEye (et al.) uses for re­verse im­age search - to try and find runs of sim­i­lar im­ages and pull them out from my li­brary au­to­mat­i­cally. So I wrote a lit­tle script to hash all my pic­tures:

Hashing is quick but down­load­ing pho­tos from iCloud is not.

The re­sult is a hash that - un­like a cryp­to­graphic func­tion like sha1 - will share more bits with hashes of sim­i­lar-look­ing im­ages than with dis­sim­i­lar ones. We can use that to cal­cu­late the ham­ming dis­tance be­tween pairs of im­ages and find a thresh­old:

And ex­tract pairs:

And hun­dreds of wig­gle­grams spew forth.

A few of them I am guilty of tak­ing in­ten­tion­ally. But most are true ac­ci­dents. As such many of them come out as less stereoscopic” and more kinescopic” - like lit­tle un­in­ten­tional movies.

Animals are a nat­ural fit for the con­cept, un­pre­dictable as they are:

Design-work also. (I am al­ways in­de­ci­sive.)

And sculp­ture:

What fun. I have the script up on Github if you want to play with it - it’ll work on your iCloud pho­tos li­brary if you’re on a Mac, or you can point it at a di­rec­tory of pic­tures oth­er­wise.

Cheers~

home ~ posted june 04 2026

cancel_claude

www.marble.onl

There is min­i­mal down­side to switch­ing to open mod­els

Andrew Marblemarble.onlandrew@willows.aiJune 21, 2026

There was a time not too long ago when us­ing Linux en­tailed some pro­fes­sional risk1. First there was com­pat­i­bil­ity: you may not have been able to ren­der a Word doc­u­ment or PowerPoint cor­rectly, and you might have had to trust Open Office’s ex­port ca­pa­bil­ity to ren­der docs the way you wanted. There might have been spe­cialty file for­mats you could­n’t eas­ily view and so could­n’t col­lab­o­rate. And sec­ond, the soft­ware ecosys­tem was just worse gen­er­ally. There were lots of half-build open-source pro­jects try­ing to achieve the func­tion­al­ity of main­stream soft­ware, but they al­ways had rough edges. I, em­bar­rass­ingly, stayed on Windows un­til I left acad­e­mia over Matlab.

Nowadays I think this is­sue has largely dis­ap­peared. Most pro­duc­tiv­ity soft­ware has a web-app, Linux is more ma­ture, open-source soft­ware is bet­ter. I’m sure that there are all sorts of ap­pli­ca­tion spe­cific soft­ware (CAD?) that still re­quire a Windows ma­chine, but the gap is much nar­rower and Linux + open source gen­er­ally aren’t the sacrifice” they once were gen­er­ally.

There re­mains a clear penalty for be­ing an open2 LLM user. Every leader­board con­sis­tently gets topped by pro­pri­etary mod­els served over API. Today on June 21, 2026, Claude and GPT are at the top of the Artificial Analysis in­tel­li­gence leader­board. That’s from the per­for­mance side. The com­pat­i­bil­ity side is worse too. Claude code just works, and more gen­er­ally, the big two pro­vide nice APIs that make them easy to use, and, even if it’s a low bar, are trustworthy” in the sense that we’ve largely all agreed we don’t mind send­ing them our LLM queries and trust them to han­dle them ap­pro­pri­ately.

Open mod­els are served via var­i­ous means, some by the com­pa­nies that re­leased them and some by third par­ties like OpenRouter. Unfortunately, both of these routes are dodgier in terms of pri­vacy and data shar­ing, and I would not feel the same com­fort send­ing API calls con­tain­ing client or con­fi­den­tial data to them3.

The other op­tion or course is to run them your­self. This solves the pri­vacy is­sue but is at least two of ex­pen­sive, com­pli­cated, and com­par­a­tively slow.

Up un­til re­cently, open mod­els had mostly been a hobby for me. I’ve tin­kered with them since the orig­i­nal Llama leak, and oc­ca­sion­ally used them when I has a niche use case, but for most pro­fes­sional work, I stuck with the Big 2. This ap­pears to be chang­ing, with Claude’s ID ver­i­fi­ca­tion roll­out4. It was in­evitable that things would get worse for users, and the writ­ing was on the wall any­way re­cently with all the new safeguards” on re­cent mod­els and the whole Mythos thing. I’m not go­ing to spend time talk­ing about why I’m not go­ing to in­dulge ID ver­i­fi­ca­tion (or the LARPing that sur­rounds it) but what is im­me­di­ately con­cern­ing is what kind of pro­fes­sional penalty it will in­cur to stop us­ing the top mod­els.

I’m hop­ing it’s go­ing to be min­i­mal. I’m al­ready set up to run a range of open mod­els ei­ther lo­cally or in the cloud, there are good cod­ing har­nesses for open mod­els, and most im­por­tantly the open mod­els are now very close to the lead­ers and typ­i­cally trail only by a few months. This does­n’t feel like 2008 Linux vs Windows, it’s much closer. I ex­pect pro­duc­tiv­ity will take a short-term hit, but don’t think it’s a deal breaker the way switch­ing from Matlab to GNU Octave would have been when I was do­ing re­search.

I’m as­sum­ing a tech­ni­cal job that in­cludes gen­eral pur­pose work that re­quires pro­duc­tiv­ity soft­ware like MS Office etc.↩︎

I’m as­sum­ing a tech­ni­cal job that in­cludes gen­eral pur­pose work that re­quires pro­duc­tiv­ity soft­ware like MS Office etc.↩︎

I use open” here to mean the weights are avail­able, I have writ­ten ex­ten­sively on why I don’t con­sider this au­to­mat­i­cally open source, but I’m us­ing open” as short­hand. And un­like when I ad­dressed this pre­vi­ously, the cur­rent lead­ing open mod­els gen­er­ally are MIT li­censed which I do con­sider open source, though many don’t.↩︎

I use open” here to mean the weights are avail­able, I have writ­ten ex­ten­sively on why I don’t con­sider this au­to­mat­i­cally open source, but I’m us­ing open” as short­hand. And un­like when I ad­dressed this pre­vi­ously, the cur­rent lead­ing open mod­els gen­er­ally are MIT li­censed which I do con­sider open source, though many don’t.↩︎

I won’t dwell on this, happy to be cor­rected, but in my ex­pe­ri­ence un­der nor­mal cir­cum­stances no­body balks if you tell them you’re us­ing OpenAI or Anthropic. If you’re send­ing re­quests to Deepseek or OpenRouter etc. there are likely to be more con­cerns, re­gard­less of the un­der­ly­ing truth.↩︎

I won’t dwell on this, happy to be cor­rected, but in my ex­pe­ri­ence un­der nor­mal cir­cum­stances no­body balks if you tell them you’re us­ing OpenAI or Anthropic. If you’re send­ing re­quests to Deepseek or OpenRouter etc. there are likely to be more con­cerns, re­gard­less of the un­der­ly­ing truth.↩︎

https://​sup­port.claude.com/​en/​ar­ti­cles/​14328960-iden­tity-ver­i­fi­ca­tion-on-claude↩︎

https://​sup­port.claude.com/​en/​ar­ti­cles/​14328960-iden­tity-ver­i­fi­ca­tion-on-claude↩︎

Everything Is Logarithms

alexkritchevsky.com

Some con­nec­tions be­tween things, which I have not seen else­where. Maybe they mean some­thing?

1. The Baseless Logarithm

Normally one writes a log­a­rithm with a base, \(\log_b (x)\), to mean

\[y = \log_b (x) \Lra b^y = x\]

And then you can change the base of the log­a­rithm with

\[\log_b (x) = \frac{\log_a (x)}{\log_a(b)}\]

Which fol­lows from re­ar­rang­ing \(\log_a (x) = \log_a (b^{\log_b x}) = \log_b (x) \times \log_a (b)\).

One way of think­ing about what this for­mula does is that it is a change of units, akin to writ­ing \(2 \text{ km} = 2000 \text{ m} / \frac{1000 \text{ m}}{1 \text{ km}}\) or \(5 \text{ bytes} = 40 \text{ bits}/\​frac{8 \text{ bits}}{1\text{ byte}}\). It says: how many copies of \(b\) are in \(x\)? It’s the num­ber of copies of \(a\) in \(x\), di­vided by the num­ber of copies of \(a\) that are in \(b\).

This is per­fectly sim­ple, but for some rea­son it’s hard to think about log­a­rithms that way. The no­ta­tion kind of… ob­fus­cates things? Specifically it is hard to read \(\log_b x\) as how many copies of \(b\) are in \(x\)”, be­cause that English ex­pres­sion should cor­re­spond to the no­ta­tion \(x/b\), not \(\log_b x\). How many fac­tors of \(b\) are in \(x\)” is a bit bet­ter, but it still feels off.

I found a way of think­ing about log­a­rithms which I think makes this clearer, but you have to al­low a sort of odd ob­ject that I am call the base­less log­a­rithm. It is sim­ply a log­a­rithm with­out a base:

\[\log N\]

which we re­gard as an ab­stract ob­ject, not a num­ber. Then we write our nor­mal based” log­a­rithm as a ra­tio of two of these base­less log­a­rithms:

\[\log_2 N = \frac{\log N}{\log 2}\]

Note, this is al­ready a thing peo­ple do col­lo­qui­ally, e.g. leav­ing out the base of log­a­rithms in as­ymp­totic for­mu­las. But I do not mean it as a short­hand; it is more use­ful to re­gard it as an ac­tual al­ge­braic ob­ject.

We in­ter­pret \(\log 2\) as be­ing the unit bits”. To write \(\log N\) in bits is to fac­tor it as a mul­ti­ple of \(\log 2\):

\[\log N = \frac{\log N}{\log 2} \log 2 = \log_2 (N) \log 2 = \log_2 (N) \text{ bits}\]

Then the change-of-base for log­a­rithms fol­lows from just writ­ing the same geo­met­ric quan­tity in dif­fer­ent units. For ex­am­ple \(\log e\) as a unit is some­times called nats”:

\[\begin{aligned} \log N = \frac{\log N}{\log 2} \log 2 = \log_2 (N) \text{ bits} = \frac{\log N}{\log e} \log e = \ln (N) \text{ nats} \end{aligned}\]

The base­less \(\log N\) is sort of the mul­ti­plica­tive ver­sion of an ob­ject that might be fa­mil­iar from dis­cus­sions of vec­tors. It is com­mon with vec­tors to dis­tin­guish be­tween points and dis­place­ments: a dis­place­ment vec­tor \(\b{v}\) is given by the dif­fer­ence of two points \(\v = (b) - (a)\). When we write think of points as hav­ing co­or­di­nates, this in­volves an ex­plicit choice of ori­gin \(\O\), such that \(\b{a} \equiv (a) - \O\) and \(\b{b} \equiv (b) - \O\). Then a dis­place­ment vec­tor is con­structed by sub­tract­ing off the fac­tors of \(\O\), \(\b{v} = \b{b} - \b{a} = ((b) - \O) - ((a) - \O) = (b) - (a)\). The base­less log­a­rithm im­ple­ments the same thing but with mul­ti­pli­ca­tion: the value \(\log N\) may be thought of as \(\log N / \log \O\) for an un­spec­i­fied choice of ori­gin; turn­ing it into an ac­tual nu­meric value in­volves di­vid­ing two such log­a­rithms to can­cel out the ori­gin, \(\log_M N = \log N / \log M = (\log N / \log \O) / (\log M / \log O)\). I think of \(\log N\) as the point cor­re­spond­ing to \(N\) and \(\log N / \log \O\) as its cor­re­spond­ing dis­place­ment vec­tor once you pick a co­or­di­nate sys­tem. The point ver­sion is more fun­da­men­tal.

You might ask: if we have a base­less log­a­rithm \(\log N\), do we also have a baseless ex­po­nen­tial”? Normally \(b^{\log_b N}\) can be writ­ten as some­thing like \(b^{\log_b N} = b^{\ln N / \ln b} = e^{\ln N} = N\); is there any way to do this with­out ac­tu­ally choos­ing a base, like \((\ast)^{\log N}\) or some­thing? I think the an­swer has to be no”, be­cause I can’t think of a way to make it mean any­thing. All we can say is that we have split the one ob­ject, a log­a­rithm \(\log_b N\) which is the so­lu­tion of \(b^y = N\), into two ob­jects, \(\log N\) and \(\log b\), each of which on their own are with­out units” and so have no nu­mer­i­cal mean­ing.

So log­a­rithms act kinda like mul­ti­plica­tive vec­tors, in the sense that they have have to de­fined rel­a­tive to an origin’, a choice of base. In fact there are many sur­pris­ing sim­i­lar­i­ties be­tween log­a­rithms and vec­tors, which I had fun ex­posit­ing about:

2. Logarithms are Vectors

When do­ing vec­tor al­ge­bra and dif­fer­en­tial geom­e­try in a prop­erly co­vari­ant way, we dis­tin­guish be­tween ab­stract vec­tors and vec­tors in a par­tic­u­lar co­or­di­nate sys­tem.

My per­sonal con­ven­tion for this is to re­fer to the ab­stract vec­tors as geometric” vec­tors and al­ways write them in bold, \(\v\), whereas coordinate” vec­tors, tu­ples of their val­ues in co­or­di­nates, are writ­ten with an ar­row over them like \(\vec{v} = (v_x, v_y, v_z)\). Boldface geo­met­ric vec­tors are al­ways co­or­di­nate-free, whereas co­or­di­nate vec­tors are just col­lec­tions of num­bers or other ob­jects. The geo­met­ric vec­tor \(\b{v}\) can be writ­ten as a dot prod­uct of its co­or­di­nates with a frame’ \(X = (\x, \y, \z)\) of ba­sis vec­tors

\[\b{v} = \vec{v} \cdot X = (v_x, v_y, v_z) \cdot (\x, \y, \z) = v_x \x + v_y \y + v_z \z\]

The pro­jec­tion of \(\v\) onto a ba­sis vec­tor \(\x\) is then given by measuring’ the vec­tor against the ba­sis vec­tor (which does not have to be of unit length). I like to write this as di­vi­sion be­cause it acts a lot like di­vi­sion (although it’s tech­ni­cally pseu­do­di­vi­sion in­stead):

\[\frac{\v}{\x} = v_x\]

That’s in my own very non­stan­dard no­ta­tion1 for vec­tor di­vi­sion here. The more com­mon way to write this is to pro­ject a com­po­nent of a dif­fer­en­tial \(df = f_x dx + f_y dy + f_z dz\) with a par­tial de­riv­a­tive, which is also the pseu­do­di­vi­sion op­er­a­tion (which is in­ci­den­tally the sense in which par­tial de­riv­a­tives kinda work like di­vi­sion but not re­ally):

\[\frac{\p f}{\p x} = f_x\]

I will write things in both forms to make it easy to trans­late be­tween them; I do pre­fer my vec­tor-di­vi­sion ver­sion be­cause it avoids bring­ing in the ir­rel­e­vant no­ta­tions of dif­fer­en­tial cal­cu­lus, but since the lat­ter is ac­tu­ally stan­dard I ought to in­clude it for com­par­i­son.

Suppose \(\b{v}\) is one-di­men­sional, \(\b{v} = v_x \x\). Then the pro­jec­tion onto a measuring stick’ \(\b{m} = m \x\) mea­sures its length in terms of mul­ti­ples of \(m\):

\[\frac{\v}{\b{m}} = \frac{v_x \x}{m \x} = \frac{v_x}{m}\]

Multiplying by \(\b{m}\) again is what we mean by writing \(\b{v}\) in units of \(\b{m}\)”:

\[\frac{\b{v}}{\b{m}} \b{m} = (\frac{v_x}{m}) (m \x)\]

Here \(m\) is the unit meters” and \(v_x/m\) is the value of \(v_x\) writ­ten in me­ters. Of course to ac­tu­ally com­pute \(v_x/m\) you have to have it in units in the first place—but clearly it’s the same kind of thing as in the log­a­rithm case, where you can think of \(\b{v}\) and \(\b{m}\) as unitless” con­cepts that are com­pared geo­met­ri­cally, and then \(v_x/m\) as their pro­jec­tions into an arib­trary co­or­di­nate sys­tem.2

The base­less log­a­rithm is per­form­ing the same op­er­a­tion on log­a­rithms, where \(\log N\) is fill­ing the role of the geo­met­ric vec­tor \(\v\) and \(\log 2 = \text{bits}\) is the unit vec­tor or mea­sur­ing stick, which takes the role of \(\x\).

\[\begin{aligned} \frac{\log N}{\log 2} &= \log_2 N \\ \frac{\log N}{\log 2} \log 2 &= \log_2 N \text{ bits} \end{aligned}\]

In this sense base­less log­a­rithms write num­bers in co­or­di­nates in ex­actly the same way that mea­sur­ing sticks write vec­tors in co­or­di­nates.

The equiv­a­lence of log­a­rithms in dif­fer­ent units

\[\begin{aligned} \log N &= \frac{\log N}{\log 2} \log 2 = \log_2 (N) \text{ bits} \\ &= \frac{\log N}{\log e} \log e = \ln (N) \text{ nats} \end{aligned}\]

is the same as the equiv­a­lence of geo­met­ric vec­tors in dif­fer­ent units

\[\begin{aligned} \v &= \frac{\v}{\x} \x = v_x \x \\[1em] &= \frac{\v}{\x’} \x’ = v_{\x’} \x’ \\ \end{aligned}\]

or

\[\begin{aligned} df &= \frac{\p f}{\p x} dx = f_x dx \\ &= \frac{\p f}{\p x’} dx’ = f_{x’} dx’ \end{aligned}\]

And the change of base for­mula that com­putes a ra­tio of log­a­rithms in dif­fer­ent bases

\[\begin{aligned} \log_2 N \text{ bits}&= \ln N \text{ nats} \\ \log_2 N &= \frac{\text{nats}}{\text{bits}} \ln N\\ &= \frac{\log e}{\log 2} \ln N \\ &= \log_2 (e) \ln N \end{aligned}\]

is ex­actly like the change of co­or­di­nates for a vec­tor, where \(\x\) and \(\x\) are two units for the same quan­tity.

\[\begin{aligned} v_x \x &= v_{x’} \x’ \\ v_x &= \frac{\x’}{\x} v_{\x’} \\ \end{aligned}\]

or3

\[\begin{aligned} f_x dx &= f_{x’} dx’ \\ f_x &= \frac{dx’}{dx} f_{x’} \end{aligned}\]

What log­a­rithms don’t al­low that vec­tor di­vi­sion and dif­fer­en­tial no­ta­tions eas­ily do is to talk about a par­tial pro­jec­tion op­er­a­tion or a par­tial de­riv­a­tive in iso­la­tion. For ex­am­ple, if \(N = 2^a 3^b\), you can only talk about the total” log­a­rithm, the ra­tio with re­spect to a sin­gle unit \(\log 2\)

\[\frac{\log N}{\log 2} = a \frac{\log 2}{\log 2} + b \frac{\log 3}{\log 2} = a + b \log_2 3\]

which is equiv­a­lent to writ­ing a vec­tor as a mul­ti­ple of a sin­gle ba­sis vec­tor (like in Clifford/geometric al­ge­bra)

\[\frac{\v}{\x} = v_x + v_y \frac{\y}{\x}\]

or to a to­tal de­riv­a­tive

\[\frac{df}{dx} = f_x + f_y \frac{dy}{dx}\]

But there is no equiv­a­lent of the op­er­a­tion of par­tial dif­fer­en­ti­a­tion, a partial log­a­rithm”, which would let you fac­tor a num­ber like

\[N \? (\log_{\p 2} N) \log 2 + (\log_{\p 3} N) \log 3\]

However, I keep find­ing that peo­ple have gone and in­vented the pro­jec­tion / par­tial de­riv­a­tive op­er­a­tion on log­a­rithms any­way. For ex­am­ple, the p-adic val­u­a­tion in num­ber the­ory

\[\nu_p (n) = \max \{ k \in \bb{N} \mid p^k \mid n \}\]

cor­re­sponds to ex­tract­ing the co­ef­fi­cient of \(\log p\) of an nat­ural num­ber in a log­a­rith­mic ba­sis

\[\begin{aligned} \log n &= \log 2^{n_2} 3^{n_3} 5^{n_5} \cdots \\ &= n_2 \log 2 + n_3 \log 3 + n_5 \log 5 + \ldots \\ \nu_p (n) &= n_p \end{aligned}\]

Each co­ef­fi­cient is a pos­i­tive in­te­ger, and \(\nu_p\) just takes the com­po­nent cor­re­spond­ing to \(\log p\). Clearly \(\log n\) acts like a vec­tor (although since the co­ef­fi­cients are in \(\bb{N}\) it is tech­ni­cally a com­mu­ta­tive monoid in­stead of a vec­tor space… nev­er­the­less, it has the fa­mil­iar struc­ture of a vec­tor). Since \(\nu_p\) is a projection’ out of this log­a­rithm, it still obeys log­a­rith­mic iden­ti­ties like \(\nu_p(m/n) = \nu_p(m) - \nu_p(n)\). But there is not re­ally a good no­ta­tion for ac­tu­ally ex­press­ing it as a pro­jec­tion, so sadly it gets a whole sep­a­rate nomen­cla­ture that you have to learn.4

The same thing also works for ra­tio­nal \(n\) or rad­i­cal \(n\) (meaning it is the prod­uct of rad­i­cals of prime fac­tors), in which case the co­ef­fi­cients be­come in­te­gers or ra­tio­nals. (As a bonus the re­sult­ing ob­jects live in an ac­tual vec­tor space.)

Another ex­am­ple of these log­a­rith­mic pro­jec­tions: in com­plex analy­sis the order of van­ish­ing” \(\text{ord}_a f(z)\) of a mero­mor­phic func­tion \(f(z)\) at a point \(z=a\) is the or­der of the pole or zero at a point (where ze­roes are like neg­a­tive poles). That is, it is the de­gree \(n\) of the low­est-de­gree term in the Laurent se­ries of the func­tion around the point \(z=a\),

\[f(z) = f_{-n} (z-a)^{-n} + f_{-n+1} (z-a)^{-n+1} + \cdots + f_{-1} (z-a)^{-1} + f_0 + f_1 (z-a) + \cdots\]

(that is, the value of \(n\) such that \((z-a)^n f(z)\) is holo­mor­phic around \(a\)). This is ex­tracted with a log­a­rithm:

\[\text{ord}_a f(z) = \lim_{z \ra a} \frac{\log f(z)}{\log (z-a)} = -n\]

since for \(z \approx a\), \(f(z) \sim f_{-n} (z-a)^{-n}\) which dom­i­nates the other terms that blow up less quickly. If we write \(g(z)\) for the rest of \(f(z)\) which has \(\text{ord}_a (g(z)) > -n\):

\[\begin{aligned} \lim_{z \ra a} \frac{\log f(z)}{\log (z-a)} &= \lim_{z \ra a} \frac{\log (f_{-n} (z-a)^{-n} + g(z))}{\log (z-a)}\\ &= \lim_{z \ra a} \frac{\log f_{-n} (z-a)^{-n} (1 + \frac{g(z)}{f_{-n}} (z-a)^n)}{\log (z-a)} \\ &= \lim_{z \ra a} \frac{\log f_{-n}}{\log (z-a)} -n \frac{\log (z-a)}{\log (z-a)} + \frac{\log (1 + c (z-a))}{\log (z-a)} \\ &= -n \end{aligned}\]

So this is a very sim­i­lar op­er­a­tion: the limit \(\lim_{z \ra a} \log (z-b)/\log(z-a) = 1_{a=b}\) serves to can­cel out the rest of the terms, like how \(\p_j dx^i \sim (\p x^i)/(\​p x^j) = 1_{i=j}\) serves to can­cel out the terms in a par­tial de­riv­a­tive, ex­tract­ing the \(dx\) com­po­nent of \(df = f_x dx + f_y dy + \ldots\).

(I’m not very good at com­plex analy­sis so that’s all I’m go­ing to say about that. Still, it seems clear that this is ba­si­cally the same op­er­a­tion.)

We see that the base­less log­a­rithm \(\log n\) works a lot like a vec­tor \(\v\) or dif­fer­en­tial \(df\), and then ex­press­ing a log­a­rithm in a base like \(\log_2 n = \log n / \log 2\) is a lot like a to­tal de­riv­a­tive \(df/dx\) or Clifford di­vi­sion \(\v \ast \b{x}^{-1}\). What is miss­ing is some equiv­a­lent of the par­tial de­riv­a­tive / pro­jec­tion op­er­a­tor that pro­jects only onto that com­po­nent… but var­i­ous fields have gone and Found a way to in­vent that any­way, ei­ther in the form of a par­tial de­riv­a­tive \(\p f/\​p x\), or just by mak­ing up the \(p\)-adic val­u­a­tion \(\nu_p\), or by the lim­its \(\lim_{z\ra a} \log f(z) / \log (z-a)\) in com­plex analy­sis. The si­m­il­iar­i­ties are all sus­pi­cious, though, and I can’t help but think there is some uni­fy­ing the­ory here that ties all this to­gether… but I can’t see what it is yet.

One thing that we might try in or­der to in­vent a \(\log_2 N\) that acts like \(\p_x f\) or \(\b{v}/\x\) is to some­how re­strict the val­ues of the log­a­rithms to cer­tain spaces, e.g. in­te­gers or ra­tio­nals. Since the \(\{\log p_i\}\) are lin­early in­de­pe­dent (which is es­sen­tially equiv­a­lent to prime fac­tor­iza­tions be­ing unique), you would end up with ob­jects like \(\log_2 3 = \log_3/\log_2\) which have no value in \(\bb{Q}\); zeroing” those out then gives some­thing that acts like a par­tial de­riv­a­tive. But I don’t know if that’s use­ful. Certainly it does­n’t help in any nu­meric con­text.

Anyway, onto more things that are log­a­rithms.

3. Vectors are also Logarithms?

In dif­fer­en­tial geom­e­try one in­ter­prets vec­tors like \(\v = v_x \x + v_y \y\) be­ing writ­ten in a ba­sis of par­tial de­riv­a­tive op­er­a­tors, \(\v = v_x \p_x + v_y \p_y\). These can then be used to cre­ate dis­crete trans­la­tions which move around in the var­i­ous co­or­di­nates,

\[T^{\v} = e^{\v} = e^{v_x \p_x + v_y \p_y }\]

The par­tial de­riv­a­tives are here in or­der to make it op­er­ate on func­tions

\[e^{v_x \p_x + v_y \p_y} f(x,y) = f(x + v_x, y + v_y)\]

which is true at the level Taylor ex­pan­sions as well. I of­ten find it eas­ier to dis­pense with the par­tial de­riv­a­tives and just think of these as trans­la­tion op­er­a­tors on the space \((x,y)\) di­rectly

\[e^{v_x \p_x + v_y \p_y} (x, y) = (x + v_x, y + v_y)\]

(You can think of this act­ing on the func­tion \(f(x,y) = (x,y)\) also, but that feels like overkill.)

In any case, all this is re­ally do­ing (in flat space, at least) is rewrit­ing the ad­di­tive vec­tor \(\b{v}\) into a mul­ti­plica­tive form \(T^{\b{v}}\) which cor­re­sponds to the same op­er­a­tion. Things are just be­ing writ­ten dif­fer­ently: its terms are mul­ti­plied in­stead of added, and scalar co­ef­fi­cients are ap­plied via ex­po­nen­ti­a­tion in­stead of mul­ti­pli­ca­tion. A ba­sis for the vec­tor space now con­sists of trans­la­tion op­er­a­tors in each co­or­di­nate:5

\[T^{\v} = e^{v_x \p_x} e^{v_y \p_y} = T_x^{v_x} T_y^{v_y}\]

(In non-flat space this is not so sim­ple be­cause the trans­la­tions in dif­fer­ent co­or­di­nates may not com­mute; you can still write it in this form but it’s a lot more com­pli­cated.)

What this means for us is: look, vec­tors are log­a­rithms too!

\[\begin{aligned} \ln T^{\v} &= \ln T_x^{v_x} T_y^{v_y} \\ &= v_x \ln T_x + v_y \ln T_y \\ &= v_x \p_x + v_y \p_y \end{aligned}\]

I can’t ex­actly say why, but it seems prefer­able to have this writ­ten in terms of base­less log­a­rithms also. We do this by re­al­iz­ing that \(T_x = e^{\p_x} = T^{\p_x}\) and think­ing of this sym­bol \(T\) as a sort of generic’ base for trans­la­tions, ab­sent the nu­meric mean­ing of the sym­bol \(e\), which has \(\log T_x = \log T^{\p_x} = \p_x \log T\). Then

\[\log T^{\v} = \v \log T = v_x \p_x \log T + v_y \p_y \log T\]

And then we can write \(\v = \log_T T^{\v} = \log T^{\v} / \log T\). This is equiv­a­lent to the nat­ural log ver­sion but it avoids ex­plic­itly de­pend­ing on the nu­meric value of \(e\): any choice of base for the log­a­rithm \(T\) gives the same con­cept of a vec­tor, writ­ten in terms of the ex­po­nen­ti­a­tion of \(T\), but now we make ex­plicit that the units’ on \(\v\) come in part from the units on \(\log T\) it­self.

So vec­tors in dif­fer­en­tial geom­e­try may also be thought of as log­a­rithms, specif­i­cally, the log­a­rithms of trans­la­tion op­er­a­tors.

Regular mul­ti­pli­ca­tion can even be viewed as an ex­am­ple of this. A prod­uct like \(xa\) can be rewrit­ten as translation” in the \(\ln a\) co­or­di­nate:

\[xa = e^{\ln x} e^{\ln a} = e^{(\ln x) \p_{\, \ln a}} a = x^{\p_{\, \ln a}} a\]

I men­tion this be­cause it’s cute, but I can’t imag­ine how it would ever be use­ful.

4. Logarithms are Derivatives?

This part does­n’t re­ally con­nect to the rest; I just thought I would men­tion it so that this ar­ti­cle con­tains every fun fact about log­a­rithms that I know.

One way of defin­ing the nat­ural log­a­rithm is

\[\ln x = \lim_{a \ra 0} \frac{x^a - 1}{a}\]

Which can be found by rewrit­ing \(x^a = e^{a \ln x}\) and then Taylor ex­pand­ing:

HPV jabs cut risk of dying from cervical cancer before 30 to almost zero

www.theguardian.com

Women who re­ceived an HPV vac­cine in early ado­les­cence have vir­tu­ally zero risk of dy­ing from cer­vi­cal can­cer be­fore the age of 30, ac­cord­ing to a ground­break­ing study, but falling vac­ci­na­tion rates could see a rise in avoid­able deaths.

Cervical can­cer is the fourth most com­mon can­cer in women, ac­cord­ing to the World Health Organization, and high-risk hu­man pa­pil­lo­maviruses (HPV) cause 99% of cases. About 3,300 women in England are di­ag­nosed with the dis­ease every year.

While the HPV vac­cine pre­vents about 90% of cer­vi­cal can­cers, un­til now the im­pact on sur­vival has been un­known. In new analy­sis, re­searchers from Queen Mary University of London (QMUL) used of­fi­cial can­cer mor­tal­ity and vac­ci­na­tion data for women aged 20 to 34 to cal­cu­late the im­pact of vac­ci­na­tion on cer­vi­cal can­cer sur­vival.

While the study, funded by Cancer Research UK and pub­lished in the Lancet, saw lit­tle change in cer­vi­cal can­cer mor­tal­ity in those who were never of­fered HPV vac­ci­na­tion, there were sub­stan­tial falls in those who were of­fered vac­ci­na­tion af­ter the HPV jab was in­tro­duced in 2008.

The im­pact on mor­tal­ity has been so great that the au­thors es­ti­mate that the like­li­hood of girls who are in­oc­u­lated when they are 12 or 13 dy­ing from cer­vi­cal can­cer be­fore the age of 30 is al­most zero. For vac­ci­nated women aged 30 – 34, the rel­a­tive risk of death from the dis­ease is 63% lower.

And for the first time in recorded his­tory, no women aged 20 to 24 died from cer­vi­cal can­cer in England be­tween 2020 and 2024. In all, the HPV vac­cine has saved hun­dreds of lives, the au­thors con­clude.

Peter Sasieni, pro­fes­sor of can­cer epi­demi­ol­ogy at QMUL and lead au­thor of the study, said: We es­ti­mate that since its in­tro­duc­tion, HPV vac­ci­na­tion has pre­vented nearly 200 young women from dy­ing from cer­vi­cal can­cer in England.”

The jab, which also pro­tects against cer­tain can­cers of the anus, pe­nis, vagina, vulva, mouth and throat, as well as gen­i­tal warts, is given to girls and boys in year 8, with catchup vac­ci­na­tions of­fered in some ar­eas in years 9 and 10.

WHOs global strat­egy on cer­vi­cal can­cer states that by 2030, all coun­tries should vac­ci­nate 90% of girls with the HPV vac­cine by the age of 15, screen 70% of women and treat 90% of those with cer­vi­cal dis­ease.

Until the pan­demic, vac­ci­na­tion rates were close to WHOs tar­get, but have fallen sig­nif­i­cantly since then.

With close to 90% HPV vac­cine up­take in women born be­tween 1995 and 2004, we ex­pect to see thou­sands of cer­vi­cal can­cer deaths pre­vented in those women over the com­ing years,” said Sasieni.

HPV vac­ci­na­tion com­bined with cer­vi­cal screen­ing could re­duce cer­vi­cal can­cer rates to the point where al­most no one de­vel­ops it.”

But he said deaths and cases could rise again be­cause of fewer teenagers get­ting vac­ci­nated.

The falling HPV vac­cine up­take — now just 75% na­tion­ally and 60% in London — means that with­out swift and con­certed ef­forts to in­crease HPV vac­cine up­take, we could see a re­ver­sal of these trends.

There could be an­other 15 – 25 avoid­able deaths each year in young women and even­tu­ally about 200 deaths from cer­vi­cal can­cer each year that could be pre­vented if we can in­crease vac­cine up­take to pre-Covid lev­els.”

Michelle Mitchell, chief ex­ec­u­tive of Cancer Research UK, said: It’s es­sen­tial that the UK gov­ern­ment and health sys­tems ur­gently ad­dress this with tar­geted ac­tion to reach com­mu­ni­ties where up­take is the low­est.”

Helen Hyndman, lead nurse at gy­nae­co­log­i­cal can­cer char­ity The Eve Appeal, said cer­vi­cal can­cer will not be elim­i­nated un­less vac­ci­na­tion and screen­ing rates im­prove and those who need it get timely treat­ment.

We need ur­gent ac­tion — we are lag­ging be­hind on our plans to elim­i­nate cer­vi­cal can­cer by 2024 and at our cur­rent rate it will be 2050 be­fore this is achieved.”

Dr Alison Wright, pres­i­dent of the Royal College of Obstetricians and Gynaecologists, said the exciting and pow­er­ful data” showed the vac­cine’s use could see fewer women with a cer­vi­cal can­cer di­ag­no­sis, and fewer lives lost to a largely pre­ventable dis­ease”.

While im­proved ac­cess to vac­cines through lo­cal com­mu­nity phar­ma­cies for those who missed school vac­ci­na­tions was wel­come, fur­ther progress now de­pends on en­cour­ag­ing vac­cine up­take at all lev­els, rais­ing aware­ness of the vac­ci­na­tion pro­gramme, and en­sur­ing that every­one who is el­i­gi­ble can get timely, eq­ui­table ac­cess, she added.

Caroline Temmink, the NHS Director of Vaccination, said: This hugely en­cour­ag­ing news shows the life-sav­ing im­pact of the HPV vac­cine and it’s in­cred­i­bly ex­cit­ing to be able to say to this whole gen­er­a­tion, cer­vi­cal can­cer and some other can­cers should­n’t be a risk for you.

Alongside cer­vi­cal screen­ing, HPV vac­ci­na­tion is cen­tral to the NHS am­bi­tion to elim­i­nate cer­vi­cal can­cer by 2040. It’s a safe and ef­fec­tive vac­cine and we urge every­one el­i­gi­ble to take up the of­fer when in­vited.”

A Department of Health and Social Care spokesper­son said: We are boost­ing vac­cine up­take so that more young peo­ple ben­e­fit from this life-sav­ing pro­tec­tion — in­clud­ing rolling out catchup HPV vac­ci­na­tion cam­paigns via com­mu­nity phar­ma­cies, and mak­ing it eas­ier to ac­cess cer­vi­cal screen­ing. HPV self-test­ing kits are now be­ing sent to those who do not come for­ward for screen­ing, to en­sure we catch more can­cers at their ear­li­est, most treat­able stages.”

JSON-LD Explained for Personal Websites

hawksley.dev

JSON-LD, also known as JSON Linked Data, is a for­mat for adding struc­tured data to web­pages. It can aid web crawlers in un­der­stand­ing the se­man­tic struc­ture of your site, qual­i­fy­ing you for richer link pre­views, and even po­ten­tially im­prov­ing your search rank­ing.

It’s been 4 months since my first post where I de­scribed build­ing this site, and Wakatime es­ti­mates I’ve spent ~100 hours cod­ing now, not in­clud­ing time spent re­search­ing and test­ing. Since then, this site has been re­ceiv­ing plenty of pol­ish, in­clud­ing the ad­di­tion of JSON-LD on each page.

JSON-LD Fundamentals

To add JSON-LD to a page, add the fol­low­ing some­where in your <head> sec­tion:

<script type=“ap­pli­ca­tion/​ld+json”> { @context”: https://​schema.org, @graph”: [ { @type”: WebSite”, @id”: https://​hawk­sley.dev/#​web­site, url”: https://​hawk­sley.dev/, name”: Ethan Hawksley” }, // Insert more nodes here. ] } </script>

Let’s break down what each part does.

<script type=“ap­pli­ca­tion/​ld+json”>

This de­clares a new script with MIME type ap­pli­ca­tion/​ld+json. Since it has this type spec­i­fied, the browser’s JS en­gine won’t run it. Specialised crawlers like Googlebot look out for these el­e­ments and parse the con­tents.

{ @context”: https://​schema.org }

Here, a JSON ob­ject is ini­tialised and the prop­erty @context is set to https://​schema.org. In JSON-LD, the struc­ture of data is de­ter­mined by as­sign­ing the ap­pro­pri­ate con­text. Web crawlers are stan­dard­ised on Schema.org,, opens in new tab which de­fines all the valid key-value pairs for the JSON.

Now that we’ve de­fined the schema our JSON-LD is fol­low­ing, we can de­scribe our web­page!

{ @graph”: [ { @type”: WebSite”, @id”: https://​hawk­sley.dev/#​web­site, url”: https://​hawk­sley.dev/, name”: Ethan Hawksley” } // Insert more nodes here. ] }

A JSON-LD doc­u­ment can be thought of as a la­belled, di­rected graph, stored un­der @graph. The graph con­tains mul­ti­ple nodes, con­nected to each other with di­rected arcs.

Nodes have:

@type - Describes what the node is, e.g. WebSite or SoftwareApplication

@id - A unique iden­ti­fier for the node, typ­i­cally a URL with a unique hash value at the end

Properties - Key/Value pairs that de­scribe the at­trib­utes of the node

In the ex­am­ple above, the type is WebSite, the ID is https://​hawk­sley.dev/#​web­site, and it has two prop­er­ties, url and name.

Web crawlers can merge the prop­er­ties of a node across mul­ti­ple pages, as long as they share an ID. However, scrap­ers that only read one page - such as LLMs - will not merge the prop­er­ties. When JSON-LD is reused across pages, strik­ing this bal­ance is im­por­tant to keep in mind. It is best prac­tice for the ID to be a URL fol­lowed by a hash, such as #website, that uniquely iden­ti­fies the node.

Although the Schema.org con­text de­fines many types of nodes, this guide will only be cov­er­ing nodes that have no­tice­able SEO im­pact. If you’re in­ter­ested in more, look up the se­man­tic web - it’s a fun rab­bit hole.

Let’s move on to which nodes each page on our site should in­clude. For each type, I’ve in­cluded the JSON-LD from this site, so you can copy-paste and edit it to fit your own.

WebSite

You’ve seen an ex­tract of WebSite ear­lier! Now here’s the full ver­sion:

{ @type”: WebSite”, @id”: https://​hawk­sley.dev/#​web­site, url”: https://​hawk­sley.dev/, name”: Ethan Hawksley”, alternateName”: [“hawksley.dev”, Hawksley”], description”: The per­sonal site and tech­ni­cal blog of Ethan Hawksley, a UK-based CS stu­dent with a fo­cus on sys­tems pro­gram­ming, low-level com­put­ing, and cy­ber­se­cu­rity.”, inLanguage”: en-GB”, publisher”: { @id”: https://​hawk­sley.dev/#​per­son }, image”: { @type”: ImageObject”, @id”: https://​hawk­sley.dev/#​web­site-im­age, url”: https://​hawk­sley.dev/​logo-square.png, caption”: Ethan Hawksley Logo” } }

WebSite ex­plains the meta­data about the site. It gives crawlers hints on how to dis­play your site.

Here, you can see that Google has in­ter­preted the name field as rep­re­sen­ta­tive of the do­main and is la­belling the re­sult ap­pro­pri­ately.

Although WebSite ap­plies to every page, you don’t need to in­clude the full ver­sion of it on every page. The root page of the do­main should be fully de­tailed, but it is per­fectly ac­cept­able for other pages to have a slimmed-down ver­sion:

{ @type”: WebSite”, @id”: https://​hawk­sley.dev/#​web­site, url”: https://​hawk­sley.dev/, name”: Ethan Hawksley” }

This gives suf­fi­cient con­text to sin­gle-page crawlers so they cor­rectly name the site, but they don’t need the full de­tails.

WebPage

WebPage de­scribes the cur­rent page, but it’s im­por­tant to dis­tin­guish it from other types like BlogPosting (covered later). WebPage rep­re­sents the phys­i­cal page it­self, the HTML. It con­tains the con­tent of the page.

{ @type”: WebPage”, @id”: https://​hawk­sley.dev/​blog/​hack-club-camp­fire/#​web­page, url”: https://​hawk­sley.dev/​blog/​hack-club-camp­fire/, isPartOf”: { @id”: https://​hawk­sley.dev/#​web­site }, name”: Winning the Hack Club Campfire Hackathon”, inLanguage”: en-GB”, breadcrumb”: { @id”: https://​hawk­sley.dev/​blog/​hack-club-camp­fire/#​bread­crumb } }

There are more spe­cific sub­types of WebPage. In this post, I’ll cover ProfilePage and CollectionPage. You can find less com­mon ones at the bot­tom of Schema.org’s de­f­i­n­i­tion for WebPage., opens in new tab

Person

Another node that every page on a per­sonal web­site should have is Person. It de­scribes who you are, which Google uses as part of their con­tent qual­ity met­ric. Increasingly, LLM crawlers are also us­ing it to de­cide who to cite in their an­swers.

Unlike WebSite, it is im­por­tant enough con­text that you should in­clude it on all of your site’s pages.

{ @type”: Person”, @id”: https://​hawk­sley.dev/#​per­son, url”: https://​hawk­sley.dev/, name”: Ethan Hawksley”, alternateName”: ethanhawksley”, givenName”: Ethan”, familyName”: Hawksley”, description”: Long Description”, disambiguatingDescription”: Shorter Description”, jobTitle”: Computer Science Student”, knowsLanguage”: en-GB”, knowsAbout”: [ // Keywords ], nationality”: { @type”: Country”, name”: United Kingdom” }, homeLocation”: { @type”: Place”, address”: { @type”: PostalAddress”, addressCountry”: GB } }, affiliation”: { @type”: HighSchool”, url”: https://​www.al­ces­tergs.co.uk, name”: Alcester Grammar School”, sameAs”: [ https://​www.wiki­data.org/​wiki/​Q4713005, https://​en.wikipedia.org/​wiki/​Al­ces­ter_­Gram­mar_School ] }, alumniOf”: [ { @type”: HighSchool”, url”: https://​www.brookewe­ston.org, name”: Brooke Weston Academy”, sameAs”: [ https://​www.wiki­data.org/​wiki/​Q4974495, https://​en.wikipedia.org/​wiki/​Brooke_We­st­on_A­cad­emy ] } ], image”: { @type”: ImageObject”, @id”: https://​hawk­sley.dev/#​per­son-im­age, url”: https://​hawk­sley.dev/​ethan-hawk­sley.png, caption”: Ethan Hawksley”, width”: 1536, height”: 1536 }, sameAs”: [ https://​github.com/​ethan-hawk­sley, https://​www.linkedin.com/​in/​ethanhawk­sley, https://​lob­ste.rs/~​ethanhawk­sley, https://​news.ycombi­na­tor.com/​user?id=ethanhawk­sley // etc. etc. ] }

Phew! There’s plenty of prop­er­ties for Person. I find that it helps to be more de­scrip­tive, rather than less, when it comes to fill­ing it out. Let’s look at the most im­por­tant prop­er­ties:

url - Points to your root page, an­chor­ing the node.

name, given­Name, fam­i­ly­Name - Clearly de­scribes your name.

im­age - Preferably a photo of you, or a logo you are af­fil­i­ated with. Connects you to a canon­i­cal im­age of you.

sameAs - Immensely use­ful for dis­am­bigua­tion, es­pe­cially if you have a com­mon name. It cleanly in­forms crawlers what your other pro­files are, let­ting them build a knowl­edge graph rep­re­sen­ta­tion of you across mul­ti­ple pages. At the time of writ­ing, /g/11m62cgdtf, opens in new tab is my Google knowl­edge graph ID.

The other prop­er­ties of Person are use­ful for adding more de­tail, but aren’t strictly nec­es­sary. You can trim them if you wish with only mi­nor im­pact.

ProfilePage

A ProfilePage, as you may ex­pect, de­scribes a page on the site about a per­son. For in­stance, I use this node on my home page, as that’s where I talk about my­self. On your site, putting it on an about page could be more ap­pro­pri­ate.

{ @type”: ProfilePage”, @id”: https://​hawk­sley.dev/#​web­page, url”: https://​hawk­sley.dev/, isPartOf”: { @id”: https://​hawk­sley.dev/#​web­site }, name”: About Ethan Hawksley”, inLanguage”: en-GB”, dateCreated”: 2024 – 09-10T00:00:00.000Z”, dateModified”: 2026 – 05-17T00:00:00.000Z”, mainEntity”: { @id”: https://​hawk­sley.dev/#​per­son } }

It’s im­por­tant to use is­PartOf to link it to your broader WebSite node, to cre­ate a re­la­tion­ship be­tween the two nodes. The same ap­plies for mainEn­tity, it lets crawlers know who the page is about. Including date­Cre­ated and date­Mod­i­fied is a good fresh­ness sig­nal for crawlers, but if your site does­n’t have them read­ily avail­able, don’t worry too much about it.

SoftwareApplication

If you are show­cas­ing any soft­ware on your page, it’s a good idea to in­clude a SoftwareApplication node to de­scribe the meta­data about it.

{ @type”: SoftwareApplication”, @id”: https://​hawk­sley.dev/#​pro­ject-yt-play, url”: https://​crates.io/​crates/​yt-play, name”: yt-play”, description”: A CLI util­ity writ­ten in Rust that syn­chro­nises YouTube playlists to lo­cal di­rec­to­ries.”, applicationCategory”: MultimediaApplication”, operatingSystem”: All”, creator”: { @id”: https://​hawk­sley.dev/#​per­son }, sameAs”: [“https://​github.com/​ethan-hawk­sley/​yt-play], offers”: { @type”: Offer”, price”: 0, priceCurrency”: GBP } }

If you want to be more spe­cific than SoftwareApplication, other valid types for this node are MobileApplication, WebApplication, and VideoGame.

The url prop­erty should be a link to where the pro­ject is de­ployed, e.g. crates.io. sameAs is for any other pages as­so­ci­ated with the pro­ject, like its source code repos­i­tory.

There are lots of valid val­ues for ap­pli­ca­tion­Cat­e­gory, you can find a list on Google’s de­f­i­n­i­tion for SoftwareApplication., opens in new tab

Even if your pro­ject is FOSS, in­clude of­fers but make sure to set the price to 0.

BreadcrumbList

BreadcrumbList is widely use­ful and should be in­cluded on all pages aside from the root page. It is used to de­scribe the cat­e­gori­sa­tion of a page, which is­n’t nec­es­sar­ily the ac­tual path to the page.

{ @type”: BreadcrumbList”, @id”: https://​hawk­sley.dev/​blog/​hack-club-ship­wrecked/#​bread­crumb, itemListElement”: [ { @type”: ListItem”, item”: https://​hawk­sley.dev/, position”: 1, name”: Home” }, { @type”: ListItem”, item”: https://​hawk­sley.dev/​blog/, position”: 2, name”: Blog” }, { @type”: ListItem”, item”: https://​hawk­sley.dev/​blog/​hack-club-ship­wrecked/, position”: 3, name”: The Shipwrecked Hackathon by Hack Club” } ] }

BreadcrumbList de­scribes the path of a page. By in­clud­ing one, you can con­trol how search en­gines rep­re­sent the path of a spe­cific page.

Here, the search re­sult for my blog post con­tains the path https://​hawk­sley.dev › Blog. If your site al­ready uses short paths, this node is a mi­nor gain and can be omit­ted. However, if your paths are longer, BreadcrumbList is use­ful for short­en­ing them.

CollectionPage

The CollectionPage node is a sub­type of WebPage, us­able for pages that pri­mar­ily con­tain lists. For ex­am­ple, my /elsewhere/ page lists all my other pro­files, and /blog/ lists all my blog posts.

{ @type”: CollectionPage”, @id”: https://​hawk­sley.dev/​else­where/#​web­page, url”: https://​hawk­sley.dev/​else­where/, isPartOf”: { @id”: https://​hawk­sley.dev/#​web­site }, name”: Elsewhere”, description”: Online pro­files of Ethan Hawksley, a UK-based CS stu­dent. Links to his de­vel­op­ment, so­cial me­dia, tech­ni­cal writ­ing, and se­cu­rity ac­counts.”, inLanguage”: en-GB”, about”: { @id”: https://​hawk­sley.dev/#​per­son }, breadcrumb”: { @id”: https://​hawk­sley.dev/​else­where/#​bread­crumb } }

You’ve met most of these prop­er­ties al­ready, so they are largely self-ex­plana­tory. Make sure you link bread­crumb to the cor­rect BreadcrumbList! It needs to be the one on the cur­rent page for it to make any sense.

Blog

You should add the Blog node to your blog’s in­dex or home page. It acts as a step­ping stone be­tween your WebSite and the in­di­vid­ual blog posts you pub­lish.

{ @type”: Blog”, @id”: https://​hawk­sley.dev/​blog/#​blog, isPartOf”: { @id”: https://​hawk­sley.dev/#​web­site }, mainEntityOfPage”: { @id”: https://​hawk­sley.dev/​blog/#​web­page }, name”: Ethan Hawksley’s Blog”, description”: Technical blog of Ethan Hawksley, a UK-based CS stu­dent. Articles on sys­tems pro­gram­ming, low-level com­put­ing, cy­ber­se­cu­rity, and com­puter sci­ence.”, inLanguage”: en-GB”, dateModified”: 2026 – 05-17T00:00:00.000Z”, publisher”: { @id”: https://​hawk­sley.dev/#​per­son }, license”: https://​cre­ativecom­mons.org/​li­censes/​by/​4.0/ }

date­Mod­i­fied is a good fresh­ness sig­nal, but if you don’t have it handy, don’t worry. Including li­cense lets crawlers know un­der what cir­cum­stances they can use your prose.

If you’ve done prior re­search into JSON-LD, you may be sur­prised that the pub­lisher prop­erty is set to be a Person, not an Organization. Although it used to re­quire one, Google’s doc­u­men­ta­tion has since been re­laxed and Person is en­tirely valid too, and ar­guably more ac­cu­rate for a per­sonal web­site.

BlogPosting

The last node we’ll be cov­er­ing is BlogPosting. It should be in­cluded on all pub­lished blog posts, pro­vid­ing added in­for­ma­tion to crawlers so they can more ac­cu­rately rep­re­sent them, in­clud­ing both more ac­cu­rate place­ment and richer de­tails in search re­sults.

{ @type”: BlogPosting”, @id”: https://​hawk­sley.dev/​blog/​need-for-post-quan­tum-cryp­tog­ra­phy/#​blog­post­ing, url”: https://​hawk­sley.dev/​blog/​need-for-post-quan­tum-cryp­tog­ra­phy/, mainEntityOfPage”: { @id”: https://​hawk­sley.dev/​blog/​need-for-post-quan­tum-cryp­tog­ra­phy/#​web­page }, isPartOf”: { @id”: https://​hawk­sley.dev/​blog/#​blog }, headline”: The Need for Post-Quantum Cryptography”, description”: Quantum com­put­ers are closer to break­ing RSA and ECC than we thought. Learn what post-quan­tum cryp­tog­ra­phy is and how to start mi­grat­ing.”, articleSection”: cybersecurity”, keywords”: cybersecurity, quan­tum”, inLanguage”: en-GB”, datePublished”: 2026 – 04-13T00:00:00.000Z”, dateModified”: 2026 – 04-17T00:00:00.000Z”, author”: { @id”: https://​hawk­sley.dev/#​per­son }, publisher”: { @id”: https://​hawk­sley.dev/#​per­son }, image”: { @type”: ImageObject”, @id”: https://​hawk­sley.dev/​blog/​need-for-post-quan­tum-cryp­tog­ra­phy/#​blog­post­ing-im­age, url”: https://​hawk­sley.dev/​og/​blog/​need-for-post-quan­tum-cryp­tog­ra­phy.png, width”: 1200, height”: 630 }, license”: https://​cre­ativecom­mons.org/​li­censes/​by/​4.0/ }

Since this is a per­sonal site, it is al­right for au­thor and pub­lisher to both point to­wards the same Person node. The im­age prop­erty should mir­ror the OG im­age that the post al­ready uses for link pre­views.

Conclusion

Congrats, that’s all the JSON-LD a per­sonal site needs! I’ve struc­tured this post to make it as easy as pos­si­ble for you to copy-paste and im­ple­ment into your own per­sonal site. Even if you run a sta­tic site with­out a build step, you can still ben­e­fit from adding at a min­i­mum WebSite, ProfilePage, and Person to the root page of your site.

If you have any ques­tions, you can get in touch via email, and I’ll do my best to help.

To add this web app to your iOS home screen tap the share button and select "Add to the Home Screen".

10HN is also available as an iOS App

If you visit 10HN only rarely, check out the the best articles from the past week.

Visit pancik.com for more.