10 interesting stories served every morning and every evening.

Your First API Call | DeepSeek API Docs

api-docs.deepseek.com

The DeepSeek API uses an API for­mat com­pat­i­ble with OpenAI/Anthropic. By mod­i­fy­ing the con­fig­u­ra­tion, you can use the OpenAI/Anthropic SDK or soft­wares com­pat­i­ble with the OpenAI/Anthropic API to ac­cess the DeepSeek API.

* The model names deepseek-chat and deepseek-rea­soner will be dep­re­cated on 2026/07/24. For com­pat­i­bil­ity, they cor­re­spond to the non-think­ing mode and think­ing mode of deepseek-v4-flash, re­spec­tively.

Invoke The Chat API​

Once you have ob­tained an API key, you can ac­cess the DeepSeek model us­ing the fol­low­ing ex­am­ple scripts in the OpenAI API for­mat. This is a non-stream ex­am­ple, you can set the stream pa­ra­me­ter to true to get stream re­sponse.

For ex­am­ples us­ing the Anthropic API for­mat, please re­fer to Anthropic API.

curl

python

nodejs

curl https://​api.deepseek.com/​chat/​com­ple­tions \ -H Content-Type: ap­pli­ca­tion/​json” \ -H Authorization: Bearer ${DEEPSEEK_API_KEY}” \ -d { model”: deepseek-v4-pro”, messages”: [ {“role”: system”, content”: You are a help­ful as­sis­tant.“}, {“role”: user”, content”: Hello!“} ], thinking”: {“type”: enabled”}, reasoning_effort”: high”, stream”: false }’

Are you a robot?

www.bloomberg.com

Please make sure your browser sup­ports JavaScript and cook­ies and that you are not block­ing them from load­ing. For more in­for­ma­tion you can re­view our Terms of Service and Cookie Policy.

Why I Cancelled Claude: Token Issues, Declining Quality, and Poor Support

nickyreinert.de

First en­thu­si­asm

A cou­ple of weeks ago I sub­scribed to Claude Code, and dur­ing the first few weeks I had a re­ally nice ex­pe­ri­ence. It was fast, the to­ken al­lowance was fair, and the qual­ity was good.

I learned they had

raised the to­ken al­lowance for non-rush hours

, and since they op­posed some gov­ern­men­tal rules, it felt good to sup­port the right cause.

(づ  ̄ ³ ̄)づ

However… for about three weeks now my ini­tial en­thu­si­asm has been rapidly wan­ing.

It be­gan with an is­sue three weeks ago. I started work­ing in the morn­ing af­ter about a ten-hour break; enough time for my to­kens to re­fresh.

I sent two small ques­tions to Claude Haiku. They were sim­ple ques­tions, not even re­lated to the repos­i­tory.

Suddenly, to­ken us­age spiked to 100%.

Have a nice break…

I con­tacted their AI sup­port bot”, which re­turned some de­fault sup­port non­sense and did­n’t re­ally un­der­stand the prob­lem. So I asked for hu­man sup­port. A cou­ple of days later a - what ap­peared to be - hu­man sup­port per­son sent a re­ply. It be­gan like this:

Our sys­tems are de­tect­ing your in­quiry is re­gard­ing us­age lim­its on your Pro or Max plan.”

Yeah, well — it’s the Pro plan. Seems like your sys­tems weren’t ac­tu­ally queried; it was just a de­fault in­tro and prob­a­bly a de­fault an­swer, be­cause:

This was fol­lowed by an ex­ten­sive what seems to be copy-and-paste an­swer from their docs ex­plain­ing how daily and weekly lim­its work.

And it closed with the typ­i­cally frus­trat­ing line, that no cus­tomer likes to read at the end of an e-mail and which is just the clas­si­cal mid­dle-fin­ger of cus­tomer sup­port - we don’t care if your prob­lem is solved or not, we de­clared it closed.

Note that fur­ther replies to this ticket may not be mon­i­tored. If your re­quest is not re­gard­ing us­age lim­its on your Pro or Max plan, or you need ad­di­tional sup­port, please visit our help page at”

Great! Sending an au­to­mated e-mail that does not re­fer to the ac­tual prob­lem and then clos­ing the chan­nel. Thanks for noth­ing, I guess? Or was I wrong. I asked Claude Haiku:

@Haiku:

See the cus­tomer’s re­quest here and the re­sponse from the AI and later W***** - did they an­swer the con­cern/​ques­tion of the cus­tomer?

See the cus­tomer’s re­quest here and the re­sponse from the AI and later W***** - did they an­swer the con­cern/​ques­tion of the cus­tomer?

(╯°_°)╯︵ ┻━┻

Declining qual­ity

In the fol­low­ing days and weeks, the qual­ity was far from sat­is­fy­ing my needs or match­ing my ini­tial ex­pe­ri­ence. While I used to be able to work on up to three pro­jects at once, now the to­ken limit was ex­hausted af­ter two hours on a sin­gle pro­ject.

And the qual­ity was de­grad­ing. I am fully aware this is quite sub­jec­tive and that the qual­ity of the agent is al­ways heav­ily im­pacted by the op­er­a­tor. The fail­ure usu­ally ap­pears in front of the screen. But hey, I also de­velop us­ing Github’s Copilot, OpenAI’s Codex and I am run­ning my own in­fer­ence with OMLX and Continue us­ing Qwen3.5 – 9B. I’m not the ex­pert, I’m lazy some­times but I prob­a­bly know a thing or two.

Let me give you this won­der­ful ex­am­ple: yes­ter­day I asked Claude Opus to refac­tor a pro­ject.

While I was brows­ing the mod­el’s think­ing log - which I strongly sug­gest do­ing not only oc­ca­sion­ally - I found this:

Rather than edit­ing every slider in JSX, I’ll add a generic ini­tial­izer in ui-events.js that auto-in­jects value dis­plays for all range in­puts that lack one.

Rather than edit­ing every slider in JSX, I’ll add a generic ini­tial­izer in ui-events.js that auto-in­jects value dis­plays for all range in­puts that lack one.

This is clearly bad prac­tice. It’s a cheap workaround you would­n’t ex­pect even from a ju­nior dev; it reads like some­one who just does­n’t want to de­liver a good re­sult. My re­sponse:

you can’t be se­ri­ous — is this how you fix things? just WORKAROUNDS????”

At least Opus ad­mit­ted:

You’re right, that was lazy. Let me do it prop­erly — add the la­bels di­rectly in the JSX and wire them ex­plic­itly.”

Needless to say, this short­cut cost me around 50% of my five-hour to­ken al­lowance.

(ง •̀_•́)ง

And even more…

Now this cache topic comes up

-

among oth­ers

. at least they are talk­ing about it openly. The prob­lem was: when you get back to work af­ter some time, your con­ver­sa­tion cache is gone and the model starts read­ing your code­base again. Cost-wise this is smart. But ex­pe­ri­ence-wise? It means you paid to­kens for the ini­tial load and, af­ter a forced break be­cause the five-hour to­ken win­dow hit its limit, you pay again for the same load.

Think that’s all? Wait, I also got this funny anec­dote: all of a sud­den the weekly win­dow changed from to­day to Monday. OK, I was thank­ful be­cause it came with a re­set to zero. But still: what is go­ing on, Anthropic? Not only that — while I was work­ing on my pro­ject, watch­ing to­ken us­age with Argus-eyed vig­i­lance, this lit­tle warn­ing popped up:

Wait, what? I’m nei­ther part of an or­ga­ni­za­tion nor do I see any hint why I sud­denly have to worry about a monthly us­age limit” — also the hourly and weekly lim­its were still not ex­ceeded. What is hap­pen­ing right now?

Turns out — two hours later - it al­lowed me to con­tinue work­ing. The warn­ing was gone.

At least

this doc­u­men­ta­tion

does not men­tion a monthly us­age limit. And the set­tings page only lists the lim­its for the cur­rent ses­sion and week.

So… what is this monthly limit all about, Anthropic?

Sorry to let you down, Anthropic

I am a huge fan of the prod­uct. Theoretically every­thing just works like a charm; it of­fers so many op­por­tu­ni­ties. I built my

US special forces soldier arrested after allegedly winning $400,000 on Maduro raid

www.cnn.com

A US spe­cial forces sol­dier in­volved in the cap­ture of Venezuelan President Nicolás Maduro was ar­rested and charged for al­legedly bet­ting on that op­er­a­tion, net­ting him $400,000 in prof­its.

According to an in­dict­ment un­sealed Thursday, Master Sgt. Gannon Ken Van Dyke opened an ac­count in late December on Polymarket, one of the best-known pre­dic­tion mar­kets. He wa­gered over $32,000 that Maduro would be out” by January. The bet was a long-shot.

But Van Dyke was in­volved in the plan­ning and ex­e­cu­tion of Operation Absolute Resolve, pros­e­cu­tors al­lege, and had ac­cess to clas­si­fied in­for­ma­tion be­fore he placed the bet. His win­nings, though anony­mous, caught the at­ten­tion of law en­force­ment al­most im­me­di­ately.

Van Dyke, an ac­tive duty sol­dier sta­tioned at Fort Bragg, faces five crim­i­nal charges for steal­ing and mis­us­ing con­fi­den­tial gov­ern­ment in­for­ma­tion, theft and fraud.

He ap­peared in court in North Carolina on Friday and paid a $250,000 bond. He is set to be ar­raigned in New York City on Tuesday and also had to sur­ren­der his pass­port.

Van Dyke al­legedly made 13 bets from December 27 to January 2, the last be­ing hours be­fore the overnight cap­ture. Prosecutors said Van Dyke sent his more than $400,000 in prof­its to a for­eign cryp­tocur­rency vault be­fore he de­posited them in an on­line bro­ker­age ac­count.

A mas­ter sergeant in the Army is a se­nior non­com­mis­sioned of­fi­cer, con­sid­ered a key tac­ti­cal leader and tech­ni­cal ex­pert and serv­ing as the prin­ci­pal NCO typ­i­cally at the Army bat­tal­ion level. Senior NCOs are of­ten looked to for set­ting and up­hold­ing the stan­dard for more ju­nior sol­diers in the unit.

Video Ad Feedback

US spe­cial forces sol­dier ar­rested af­ter al­legedly win­ning $400,000 on Maduro raid

0:40

• Source:

CNN

US spe­cial forces sol­dier ar­rested af­ter al­legedly win­ning $400,000 on Maduro raid

0:40

Those en­trusted to safe­guard our na­tion’s se­crets have a duty to pro­tect them and our armed ser­vice mem­bers, and not to use that in­for­ma­tion for per­sonal fi­nan­cial gain,” said Jay Clayton, US at­tor­ney for the Southern District of New York.

Van Dyke was pho­tographed just af­ter the op­er­a­tion — and from when he placed his fi­nal bet — on what ap­pears to be the deck of a ship at sea, at sun­rise wear­ing U.S. mil­i­tary fa­tigues, and car­ry­ing a ri­fle, stand­ing along­side three other in­di­vid­u­als wear­ing U.S. mil­i­tary fa­tigues,” court doc­u­ments say.

Van Dyke prof­ited more than $400,000, pros­e­cu­tors say. He then al­legedly moved those win­nings to a for­eign cryp­tocur­rency vault be­fore he de­posited them in an on­line bro­ker­age ac­count in what pros­e­cu­tors called an at­tempt to con­ceal their ori­gin.

The Commodity Futures Trading Commission filed a re­lated com­plaint against Van Dyke on Thursday, seek­ing resti­tu­tion, dis­gorge­ment and civil mon­e­tary penal­ties.

CNN re­ported last month that fed­eral pros­e­cu­tors were in­ves­ti­gat­ing the Maduro trade, ac­cord­ing to a per­son fa­mil­iar with the mat­ter. The chiefs of the se­cu­ri­ties and com­mod­ity fraud unit at the US at­tor­ney’s of­fice in Manhattan met with rep­re­sen­ta­tives at Polymarket last month.

After the bets were placed, the US mil­i­tary launched a covert op­er­a­tion that ex­tra­dited Maduro from the pres­i­den­tial palace in Caracas in an overnight cap­ture while com­ing un­der heavy fire. Maduro was trans­ported to New York to face fed­eral drug-traf­fick­ing re­lated charges. He has pleaded not guilty.

Polymarket in a post on X said, When we iden­ti­fied a user trad­ing on clas­si­fied gov­ern­ment in­for­ma­tion, we re­ferred the mat­ter to the DOJ & co­op­er­ated with their in­ves­ti­ga­tion. Insider trad­ing has no place on Polymarket. Today’s ar­rest is proof the sys­tem works.”

ABC News first re­ported Thursday’s ar­rest.

Trading on pre­dic­tion mar­kets has ex­ploded the past year, with users now spend­ing a few bil­lion dol­lars each week on such sites.

Lawmakers in Congress have in­tro­duced more than a dozen new bills this year to fur­ther reg­u­late pre­dic­tion mar­kets. Some of the bills, which gained bi­par­ti­san sup­port, would stiffen penal­ties against gov­ern­ment of­fi­cials who en­gage in in­sider trad­ing.

Trump told re­porters Thursday he is con­cerned about the grow­ing trend of bet­ting on geopo­lit­i­cal events. Asked about the charges against the US sol­dier, the pres­i­dent said he was not fa­mil­iar with the specifics of the in­ci­dent but com­pared it to base­bal­l’s all-time hit leader Pete Rose.

That’s like Pete Rose bet­ting on his own team,” Trump said, re­fer­ring to the late base­ball player who was banned from base­ball for gam­bling.

Pressed on whether he is con­cerned about bet­ting tied to the war with Iran, Trump said it’s a global is­sue.

Well I think that the whole world, un­for­tu­nately, has be­come some­what of a casino,” Trump said, adding that such bet­ting is hap­pen­ing all over the world, and every place they’re do­ing these bet­ting things.”

Now, I think that I’m not happy with it,” he con­cluded.

The Trump ad­min­is­tra­tion ap­proved Polymarket last year to start of­fer­ing trades for American cus­tomers, but its US-facing site is­n’t fully op­er­a­tional yet. The Maduro-related trades oc­curred on Polymarket’s highly pop­u­lar in­ter­na­tional site.

That site op­er­ates out of the reach of US reg­u­la­tions — which is how it’s able to of­fer mar­kets re­lated to war, which is il­le­gal un­der fed­eral law. But ex­perts say Americans can eas­ily ac­cess the off­shore site with a vir­tual pri­vate net­work, or VPN.

There is a de­bate in the pre­dic­tion mar­ket in­dus­try over the role of in­sid­ers in pre­dic­tion mar­kets. Some ex­perts see these mar­kets as a ve­hi­cle for in­for­ma­tion to flow more freely from in­sid­ers to the gen­eral pub­lic.

Asked about in­sider trad­ing risks, Polymarket’s CEO told Axios in November it was super cool” that his plat­form creates this fi­nan­cial in­cen­tive for peo­ple to go and di­vulge the in­for­ma­tion to the mar­ket,” in­clud­ing in­sid­ers.

Polymarket rolled out new rules in March, to clarify three core cat­e­gories of pro­hib­ited in­sider trad­ing con­duct.”

They banned trades based on in­for­ma­tion that users were legally re­quired to keep con­fi­den­tial, and trades based on tips from some­one with the same oblig­a­tion. They also said peo­ple in a po­si­tion of au­thor­ity or in­flu­ence” to af­fect the out­come of an event can­not par­tic­i­pate in any re­lated mar­kets.

This story has been up­dated fol­low­ing Van Dyke’s court ap­pear­ance on Friday.

CNNs Marshall Cohen, Haley Britzky and Alejandria Jaramillo con­tributed to this re­port.

Are you a robot?

www.bloomberg.com

Please make sure your browser sup­ports JavaScript and cook­ies and that you are not block­ing them from load­ing. For more in­for­ma­tion you can re­view our Terms of Service and Cookie Policy.

On sabotaging projects by overthinking, scope creep, and structural diffing

kevinlynagh.com

Hi friends,

I’ll be at­tend­ing Babashka Conf on May 8 and Dutch Clojure Days on May 9.

If you’re at­tend­ing ei­ther (or just vis­it­ing Amsterdam), drop me a line!

When I have an idea for a pro­ject, it tends to go in one of these two di­rec­tions:

I just do it. Maybe I make a few mi­nor re­vi­sions, but of­ten it turns out ex­actly how I’d imag­ined and I’m happy.

I just do it. Maybe I make a few mi­nor re­vi­sions, but of­ten it turns out ex­actly how I’d imag­ined and I’m happy.

I think, I should look for prior art”. There’s a lot of prior art, deal­ing with a much broader scope than I’d orig­i­nally imag­ined. I start to won­der if I should in­cor­po­rate that scope. Or per­haps try to build my thing on top of the ex­ist­ing sorta-nearby-so­lu­tions. Or maybe I should just use the pop­u­lar thing. Although I could do a bet­ter job than that thing, if I put a bunch of time into it. But ac­tu­ally, I don’t want to main­tain a big pop­u­lar pro­ject, nor do I want to put that much time into this pro­ject. Uh oh, now I’ve spent a bunch of time, hav­ing nei­ther ad­dressed the orig­i­nal is­sue nor ex­pe­ri­enced the joy of cre­at­ing some­thing.

I think, I should look for prior art”. There’s a lot of prior art, deal­ing with a much broader scope than I’d orig­i­nally imag­ined. I start to won­der if I should in­cor­po­rate that scope. Or per­haps try to build my thing on top of the ex­ist­ing sorta-nearby-so­lu­tions. Or maybe I should just use the pop­u­lar thing. Although I could do a bet­ter job than that thing, if I put a bunch of time into it. But ac­tu­ally, I don’t want to main­tain a big pop­u­lar pro­ject, nor do I want to put that much time into this pro­ject. Uh oh, now I’ve spent a bunch of time, hav­ing nei­ther ad­dressed the orig­i­nal is­sue nor ex­pe­ri­enced the joy of cre­at­ing some­thing.

I pre­fer the first out­come, and I think the piv­otal fac­tor is how well I’ve in­ter­nal­ized my own suc­cess cri­te­ria.

For ex­am­ple, last week­end I hosted my friend Marcin and we de­cided it’d be fun to do some wood­work­ing, so we threw to­gether this shelf and 3d-printed hang­ers for my kitchen:

Absolute banger of a pro­ject:

brain­stormed the de­sign over cof­fee

did a few 3d-print it­er­a­tions for the Ikea bin hang­ers (OnShape CAD, if you want to print your own)

used ma­te­r­ial left­over from my work­bench

rounded the cor­ner by eye with a palm sander

sealed the raw ply­wood edge with some left­over paint from a friend

done in a week­end

The main suc­cess cri­te­ria was to jam on wood­work­ing with a friend, and that helped me not over­think the ob­ject-level suc­cess cri­te­ria: Just make a shelf for my ex­act kitchen!

In con­trast, this past Friday I no­ticed diff­tas­tic did a poor job, so I de­cided to shop around for struc­tural/​se­man­tic diff tools and re­lated work­flows (a topic I’ve never stud­ied, that I’m in­creas­ingly in­ter­ested in as I’m re­view­ing more and more LLM-generated code).

I spent 4 hours over the week­end re­search­ing ex­ist­ing tools (see my notes be­low), go­ing through dark pe­ri­ods of both semantic tree diff­ing is a PhD-level com­plex prob­lem” and why do all of these have MCP servers? I don’t want an MCP server”, be­fore I came to my senses and re­mem­bered my orig­i­nal suc­cess cri­te­ria: I just want a nicer diff­ing work­flow for my­self in Emacs, I should just build it my­self — should take about 4 hours.

I’m cau­tiously op­ti­mistic that, hav­ing had this re­al­iza­tion and com­mit­ting my­self to a min­i­mal scope, I’ll be able to knock out a pro­to­type be­fore run­ning out of mo­ti­va­tion.

However, other long-run­ning in­ter­ests of mine:

in­ter­faces for pro­to­typ­ing hard­ware (discussed September 2023)

a pro­gram­ming lan­guage that fuses what I like about Clojure and Rust (November 2023)

a pro­gram­ming lan­guage for CAD (constraints, bidi­rec­tional edit­ing, other du­bi­ous ideas)

seem to be deep in the well of out­come #2.

That is, I’ve spent hun­dreds of hours on back­ground re­search and lit­tle pro­to­types, but haven’t yet syn­the­sized any­thing that ad­dresses the orig­i­nal mo­ti­vat­ing is­sue.

It’s not quite that I re­gret that time — I do love learn­ing by read­ing — but I have a nag­ging sense of un­ease that my in­ner critic (fear of fail­ure?) is si­lenc­ing my gen­er­a­tive ten­den­cies, keep­ing me from the much more en­joy­able (and pro­duc­tive!) learn­ing by do­ing.

I think in these cases the suc­cess cri­te­ria has been much fuzzier: Am I try­ing to re­place my own us­age of Rust/Clojure?

Only for some sub­set of prob­lems?

Or is it that I ac­tu­ally just need a play­ground to learn about lan­guage de­sign/​im­ple­men­ta­tion, and it’s fine if I don’t end up us­ing it?

Ditto for CAD: Am I try­ing to re­place my com­mer­cial CAD tool in fa­vor of my own?

Only for some sub­set of sim­ple or par­tic­u­larly para­met­ric parts?

Do I care if it’s use­ful for oth­ers?

Does my tool need to be leg­i­bly dif­fer­ent from ex­ist­ing open-source tools?

It’s worth con­sid­er­ing these ques­tions, sure.

But at the end of the day, I’d much rather have done a lot than have only con­sid­ered a lot.

So I’m try­ing to em­brace my in­ner clue­less 20-year-old and just do things — even if some turn out to be obviously bad” in hind­sight, I’ll still be com­ing out ahead on net =D

Conservation of scope creep

Of course, there’s only so much time to just do things”, and there’s a bal­ance to be had. I’m not sure how many times I’ll re-learn YAGNI (“you ain’t gonna need it”) in my ca­reer, but I was re­minded of it again af­ter writ­ing a bunch of code with an LLM agent, then even­tu­ally com­ing to my senses and throw­ing it all out.

I wanted a Finda-style filesys­tem-wide fuzzy path search for Emacs.

Since I’ve built (by hand, typ­ing the code my­self!) this ex­act func­tion­al­ity be­fore (walk filesys­tem to col­lect paths, in­dex them by tri­gram, do fast fuzzy queries via bitmap in­ter­sec­tions), I fig­ured it’d only take a few hours to su­per­vise an LLM to write all the code.

I started with a plan mode” chat, and the LLM sug­gested a li­brary, Nucleo, which turned up since I wrote Finda (10 years ago, eek!).

I read through it, found it quite well-de­signed and doc­u­mented, and de­cided to use it so I’d get its smart case and Unicode nor­mal­iza­tion func­tion­al­ity.

(E.g., query foo matches Foo and foo, whereas query Foo won’t match foo; sim­i­larly for cafe and café.)

Finding a great li­brary was­n’t the prob­lem, the prob­lem was that Nucleo also sup­ported some ex­tra func­tion­al­ity: an­chors (^foo only matches at the be­gin­ning of a line).

This got me think­ing about what that might mean in a cor­pus that con­sists en­tirely of file paths.

Anchoring to the be­gin­ning of a line is­n’t use­ful (everything starts with /), so I de­cided to try and in­ter­pret the an­chors with re­spect to the path seg­ments.

E.g., ^foo would match /root/foobar/ but not /root/barfoo/.

But to do this ef­fi­ciently, the in­dex needs to keep track of seg­ment bound­aries so that the query can be checked against each seg­ment quickly.

But then we also need to han­dle a slash oc­cur­ring in an an­chored query (e.g., ^foo/bar) since that would­n’t get matched when only look­ing at seg­ments in­di­vid­u­ally (root, foo, bar, and baz of a match­ing path /root/foo/bar/baz/).

Working through this took sev­eral hours: first throw­ing around de­sign ideas with an LLM, hav­ing it write code to wrap Nucleo’s types, then re­al­iz­ing its code was bloated and did­n’t spark joy, so fi­nally writ­ing my own (smaller) wrap­per.

Then, af­ter a break, I re­al­ized:

I can’t think of a sit­u­a­tion where I’d ever wished Finda had an­chor func­tion­al­ity

In a cor­pus of paths, I can an­chor by just adding / to the start or end of a query (this works for every­thing ex­cept an­chor­ing to the end of a file­name).

So I tossed all of the an­chor­ing code.

I’m pretty sure I still came out ahead com­pared to if I’d tried to write every­thing my­self sans LLM or dis­cus­sion with oth­ers, but I’m not cer­tain.

Perhaps there’s some kind of con­ser­va­tion law here: Any in­creases in pro­gram­ming speed will be off­set by a cor­re­spond­ing in­crease in un­nec­es­sary fea­tures, rab­bit holes, and di­ver­sions.

Structural diff­ing

Speaking of un­nec­es­sary di­ver­sions, let me tell you every­thing I’ve learned about struc­tural diff­ing re­cently — if you have thoughts/​feel­ings/​ref­er­ences in this space, I’d love to hear about em!

When we’re talk­ing about code, a diff” usu­ally means a sum­mary of the line-by-line changes be­tween two ver­sions of a file.

This might be ren­dered as a unified” view, where changed lines are pre­fixed with + or - to in­di­cate whether they’re ad­di­tions or dele­tions.

For ex­am­ple:

We’ve re­moved cof­fee and added ap­ple.

The same diff might also be ren­dered in a side-by-side view, which can be eas­ier to read when there are more com­plex changes:

The prob­lem with these line-by-line diffs is that they’re not aware of higher-level struc­ture like func­tions, types, etc. — if some braces match up some­how be­tween ver­sions, they might not be shown at all, even if the braces belong” to dif­fer­ent func­tions.

There’s a won­der­ful tool, diff­tas­tic, which tries to ad­dress this by cal­cu­lat­ing diffs us­ing treesit­ter-pro­vided con­crete syn­tax trees.

It’s a huge im­prove­ment over line-based diffs, but un­for­tu­nately it does­n’t al­ways do a great job match­ing en­ti­ties be­tween ver­sions.

Here’s the diff that mo­ti­vated this en­tire foray:

Note that it does­n’t match up struct PendingClick, it shows it deleted on the left and added on the right.

I haven’t dug into why diff­tas­tic fails to match here, but I do feel like it’s wrong — even if the over­all diff would be longer, I’d still rather see PendingClickRequest and PendingClick matched up be­tween both sides.

Here’s a sum­mary of tools / ref­er­ences in the space:

The most baked” and thought­ful se­man­tic diff tool I found is, per­haps un­sur­pris­ingly, se­man­ticd­iff.com, a small German com­pany with a free VSCode plu­gin and web app that shows diffs for github PRs. Unfortunately they don’t have any code li­braries I can use as a foun­da­tion for the work­flow I want.

this se­man­ticd­iff vs. diff­tas­tic blog post cov­ers a lot of great de­tails (including that diff­tas­tic does­n’t even show se­man­ti­cally mean­ing­ful in­den­ta­tion changes in python !!!)

one of the au­thors has great HN com­ments with hard-won back­ground knowl­edge. E.g., they moved away from treesit­ter be­cause it’s un­re­li­able for se­man­tics:

Context-sensitive key­words in par­tic­u­lar were a con­stant source of an­noy­ance. The gram­mar looks cor­rect, but it will fail to parse be­cause of the way the lexer works. You don’t want your tool to abort just be­cause some­one named their pa­ra­me­ter async”.

The most baked” and thought­ful se­man­tic diff tool I found is, per­haps un­sur­pris­ingly, se­man­ticd­iff.com, a small German com­pany with a free VSCode plu­gin and web app that shows diffs for github PRs. Unfortunately they don’t have any code li­braries I can use as a foun­da­tion for the work­flow I want.

this se­man­ticd­iff vs. diff­tas­tic blog post cov­ers a lot of great de­tails (including that diff­tas­tic does­n’t even show se­man­ti­cally mean­ing­ful in­den­ta­tion changes in python !!!)

one of the au­thors has great HN com­ments with hard-won back­ground knowl­edge. E.g., they moved away from treesit­ter be­cause it’s un­re­li­able for se­man­tics:

Context-sensitive key­words in par­tic­u­lar were a con­stant source of an­noy­ance. The gram­mar looks cor­rect, but it will fail to parse be­cause of the way the lexer works. You don’t want your tool to abort just be­cause some­one named their pa­ra­me­ter async”.

Context-sensitive key­words in par­tic­u­lar were a con­stant source of an­noy­ance. The gram­mar looks cor­rect, but it will fail to parse be­cause of the way the lexer works. You don’t want your tool to abort just be­cause some­one named their pa­ra­me­ter async”.

diff­sit­ter

built on treesit­ter, has MCP server. README in­cludes list of sim­i­lar pro­jects.

lots of github stars, but does­n’t seem par­tic­u­larly well-doc­u­mented; I could­n’t find an ex­pla­na­tion of how it works, but the diff­tas­tic wiki says it runs longest-com­mon-sub­se­quence on the leaves of the tree”

diff­sit­ter

built on treesit­ter, has MCP server. README in­cludes list of sim­i­lar pro­jects.

lots of github stars, but does­n’t seem par­tic­u­larly well-doc­u­mented; I could­n’t find an ex­pla­na­tion of how it works, but the diff­tas­tic wiki says it runs longest-com­mon-sub­se­quence on the leaves of the tree”

gumtree

re­search / aca­d­e­mic ori­gin in 2014

re­quires Java, so no-go for my use case of a quick tool I can use via Emacs

gumtree

re­search / aca­d­e­mic ori­gin in 2014

re­quires Java, so no-go for my use case of a quick tool I can use via Emacs

mer­gi­raf: treesit­ter-based merge-dri­ver writ­ten in rust

very nice ar­chi­tec­ture overview; tool uses Gumtree al­go­rithm

docs and adorable il­lus­tra­tions in­di­cate this pro­ject was clearly writ­ten by a thought­ful hu­man

se­man­ticd­iff.com au­thor in HN com­ments:

> GumTree is good at re­turn­ing a re­sult quickly, but there are quite a few cases where it al­ways re­turned bad matches for us, no mat­ter how many fol­low-up pa­pers with im­prove­ments we tried to im­ple­ment. In the end we switched over to a dijk­stra based ap­proach that tries to min­i­mize the cost of the map­ping

mer­gi­raf: treesit­ter-based merge-dri­ver writ­ten in rust

very nice ar­chi­tec­ture overview; tool uses Gumtree al­go­rithm

GitHub - matz/spinel

github.com

Spinel — Ruby AOT Compiler

Spinel com­piles Ruby source code into stand­alone na­tive ex­e­cuta­bles.

It per­forms whole-pro­gram type in­fer­ence and gen­er­ates op­ti­mized C code,

achiev­ing sig­nif­i­cant speedups over CRuby.

Spinel is self-host­ing: the com­piler back­end is writ­ten in Ruby and

com­piles it­self into a na­tive bi­nary.

How It Works

Ruby (.rb)

|

v

spinel_­parse Parse with Prism (libprism), se­ri­al­ize AST

| (C bi­nary, or CRuby + Prism gem as fall­back)

v

AST text file

|

v

spinel_­code­gen Type in­fer­ence + C code gen­er­a­tion

| (self-hosted na­tive bi­nary)

v

C source (.c)

|

v

cc -O2 -Ilib -lm Standard C com­piler + run­time header

|

v

Native bi­nary Standalone, no run­time de­pen­den­cies

Quick Start

# Fetch libprism sources (from the prism gem on rubygems.org):

make deps

# Build every­thing:

make

# Write a Ruby pro­gram:

cat > hello.rb <<‘RUBY’

def fib(n)

if n < 2

n

else

fib(n - 1) + fib(n - 2)

end

end

puts fib(34)

RUBY

# Compile and run:

./spinel hello.rb

./hello # prints 5702887 (instantly)

Options

./spinel app.rb # com­piles to ./app

./spinel app.rb -o myapp # com­piles to ./myapp

./spinel app.rb -c # gen­er­ates app.c only

./spinel app.rb -S # prints C to std­out

Self-Hosting

Spinel com­piles its own back­end. The boot­strap chain:

CRuby + spinel_­parse.rb → AST

CRuby + spinel_­code­gen.rb → gen1.c → bin1

bin1 + AST → gen2.c → bin2

bin2 + AST → gen3.c

gen2.c == gen3.c (bootstrap loop closed)

Benchmarks

74 tests pass. 55 bench­marks pass.

Geometric mean: ~11.6x faster than miniruby (Ruby 4.1.0dev) across

the 28 bench­marks be­low. Baseline is the lat­est CRuby miniruby build

(without bun­dled gems), which is con­sid­er­ably faster than the sys­tem

ruby (3.2.3); Spinel’s ad­van­tage is cor­re­spond­ingly smaller but still

sub­stan­tial on com­pu­ta­tion-heavy work­loads.

Computation

Data Structures & GC

Real-World Programs

Supported Ruby Features

Core: Classes, in­her­i­tance, su­per, in­clude (mixin), at­tr_ac­ces­sor,

Struct.new, alias, mod­ule con­stants, open classes for built-in types.

Control Flow: if/​el­sif/​else, un­less, case/​when,

case/​in (pattern match­ing), while, un­til, loop, for..in

(range and ar­ray), break, next, re­turn, catch/​throw,

&. (safe nav­i­ga­tion).

Blocks: yield, block­_­given?, &block, proc {}, Proc.new,

lambda -> x { }, method(:name). Block meth­ods: each,

each_with­_in­dex, map, se­lect, re­ject, re­duce, sort_by,

any?, all?, none?, times, upto, downto.

Exceptions: be­gin/​res­cue/​en­sure/​retry, raise,

cus­tom ex­cep­tion classes.

Types: Integer, Float, String (immutable + mu­ta­ble), Array, Hash,

Range, Time, StringIO, File, Regexp, Bigint (auto-promoted), Fiber.

Polymorphic val­ues via tagged unions. Nullable ob­ject types (T?)

for self-ref­er­en­tial data struc­tures (linked lists, trees).

Global Variables: $name com­piled to sta­tic C vari­ables with

type-mis­match de­tec­tion at com­pile time.

Strings: << au­to­mat­i­cally pro­motes to mu­ta­ble strings (sp_String)

for O(n) in-place ap­pend. +, in­ter­po­la­tion, tr, ljust/​rjust/​cen­ter,

and all stan­dard meth­ods work on both. Character com­par­isons like

s[i] == c” are op­ti­mized to di­rect char ar­ray ac­cess (zero al­lo­ca­tion).

Chained con­cate­na­tion (a + b + c + d) col­lapses to a sin­gle mal­loc

via sp_str_­con­cat4 / sp_str_­con­cat_arr — N-1 fewer al­lo­ca­tions.

Loop-local str.split(sep) reuses the same sp_S­trAr­ray across

it­er­a­tions (csv_process: 4 M al­lo­ca­tions elim­i­nated).

Regexp: Built-in NFA reg­exp en­gine (no ex­ter­nal de­pen­dency).

=~, $1-$9, match?, gsub(/​re/, str), sub(/​re/, str),

scan(/​re/), split(/​re/).

Bigint: Arbitrary pre­ci­sion in­te­gers via mruby-big­int. Auto-promoted

from loop mul­ti­pli­ca­tion pat­terns (e.g. q = q * k). Linked as sta­tic

li­brary — only in­cluded when used.

Ubuntu 26.04 LTS released

lwn.net

Ubuntu 26.04 (“Resolute Raccoon”) LTS has been re­leased

on sched­ule.

This re­lease brings a sig­nif­i­cant up­lift in se­cu­rity, per­for­mance,

and us­abil­ity across desk­top, server, and cloud en­vi­ron­ments. Ubuntu

26.04 LTS in­tro­duces TPM-backed full-disk en­cryp­tion, ex­panded use of

mem­ory-safe com­po­nents, im­proved ap­pli­ca­tion per­mis­sion con­trols, and

Livepatch sup­port for Arm sys­tems, help­ing re­duce down­time and

strengthen sys­tem re­silience. […]

The newest Edubuntu, Kubuntu, Lubuntu, Ubuntu Budgie, Ubuntu Cinnamon,

Ubuntu Kylin, Ubuntu Studio, Ubuntu Unity, and Xubuntu are also be­ing

re­leased to­day. For more de­tails on these, read their in­di­vid­ual re­lease

notes un­der the Official fla­vors sec­tion:

https://​doc­u­men­ta­tion.ubuntu.com/​re­lease-notes/​26.04/#​of­fi­cial-fla­vors

Maintenance up­dates will be pro­vided for 5 years for Ubuntu Desktop, Ubuntu

Server, Ubuntu Cloud, Ubuntu WSL, and Ubuntu Core. All the re­main­ing fla­vors

will be sup­ported for 3 years.

This re­lease brings a sig­nif­i­cant up­lift in se­cu­rity, per­for­mance,

and us­abil­ity across desk­top, server, and cloud en­vi­ron­ments. Ubuntu

26.04 LTS in­tro­duces TPM-backed full-disk en­cryp­tion, ex­panded use of

mem­ory-safe com­po­nents, im­proved ap­pli­ca­tion per­mis­sion con­trols, and

Livepatch sup­port for Arm sys­tems, help­ing re­duce down­time and

strengthen sys­tem re­silience. […]

The newest Edubuntu, Kubuntu, Lubuntu, Ubuntu Budgie, Ubuntu Cinnamon,

Ubuntu Kylin, Ubuntu Studio, Ubuntu Unity, and Xubuntu are also be­ing

re­leased to­day. For more de­tails on these, read their in­di­vid­ual re­lease

notes un­der the Official fla­vors sec­tion:

https://​doc­u­men­ta­tion.ubuntu.com/​re­lease-notes/​26.04/#​of­fi­cial-fla­vors

Maintenance up­dates will be pro­vided for 5 years for Ubuntu Desktop, Ubuntu

Server, Ubuntu Cloud, Ubuntu WSL, and Ubuntu Core. All the re­main­ing fla­vors

will be sup­ported for 3 years.

See the re­lease

notes for a list of changes, sys­tem re­quire­ments, and more.

how to be anti-social

nate.leaflet.pub

Are you a robot?

www.bloomberg.com

Please make sure your browser sup­ports JavaScript and cook­ies and that you are not block­ing them from load­ing. For more in­for­ma­tion you can re­view our Terms of Service and Cookie Policy.

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.

If you like 10HN please leave feedback and share

Visit pancik.com for more.