Hacker Newsnew | past | comments | ask | show | jobs | submit | EliasWatson's commentslogin

I had Claude run a benchmark on scriptc vs node: https://github.com/EliasWatson/Primes/tree/typescript-script...

Looking at the byte-array results (best case): scriptc is about 7.5x slower than Node 24, even after Claude tried making some scriptc-specific optimizations. But the executable starts up 12x faster (1.5 ms vs 18.6 ms), uses 72x less memory (2.5 MiB vs 181 MiB), and is a single 370 KB executable with no runtime dependencies.


https://code.claude.com/docs/en/prompt-caching#on-a-claude-s...

"On a Claude subscription, Claude Code requests the one-hour TTL automatically. Usage is included in your plan rather than billed per token, so the longer TTL costs you nothing extra and only affects how long your cache stays warm. If you’ve gone over your plan’s usage limit and Claude Code is drawing on usage credits, you are billed for that usage, so Claude Code automatically drops the TTL to five minutes."


Yea, they had so much demand for Kimi K3 that they hit the limits of their compute: https://news.ycombinator.com/item?id=48969291

ADHD can sometimes be a superpower


For exhaustive searches, a library like or-tools or clingo can speed things up a lot. But first you have to figure out how to express your problem declaratively.


A couple things off the top of my head:

- You aren't forced to resolve rebase/merge conflicts immediately. You can switch branches halfway through resolving conflicts and then come back later and pick up where you left off. You can also just ignore the conflicts and continue editing files on the conflicted branch and then resolve the conflicts later.

- Manipulating commits is super easy (especially with jjui). I reorder commits all the time and move them between branches. Of course you can also squash and split commits, but that's already easy in git. Back when I was using git, I would rarely touch previous commits other than the occasional squash or rename. But now I frequently manipulate the commit history of my branch to make it more readable and organized.

- jj acts as a VCS for your VCS. It has an operation log that is a history of the state of the git repository. So anything that would be destructive in git (e.g. rebase, pull, squash, etc) can be undone.

- Unnamed branches is the feature that has changed my workflow the most. It's hard to explain, so I probably won't do it justice. Basically you stop thinking about things in terms of branches and instead just see it as a graph of commits. While I'm experimenting/exploring how to implement or refactor something, I can create "sub-branches" and switch between them. Similar to stashes, but each "stash" is just a normal branch that can have multiple commits. If I want to test something but I have current changes, I just `jj new`. And if I want to go back, I just make a new commit off of the previous one. And all these commits stick around, so I can go back to something I tried before. Hopefully this made some sense.

Also note that jj is fully compatible with git. I use it at work and all my coworkers use git. So it feels more like a git client than a git replacement.


All of these features sound like the recipe for a confusing nightmare!

"You can switch branches halfway through resolving conflicts and then come back later and pick up where you left off. You can also just ignore the conflicts and continue editing files on the conflicted branch and then resolve the conflicts later."

"Similar to stashes, but each "stash" is just a normal branch that can have multiple commits. If I want to test something but I have current changes, I just `jj new`. And if I want to go back, I just make a new commit off of the previous one. And all these commits stick around, so I can go back to something I tried before."


I thought the same until I started using it.

Turns out, git sorta trains you to be very, very afraid of breaking something.

jj answers this in a few ways:

1. everything is easily reversible, across multiple axes.

2. yes, everything is basically a stash, and it's a live stash — as in, I don't have to think about it because if it's in my editor, it's already safely stored as the current change. I can switch to a different one, create a new one, have an agent work on another one, etc, all without really caring about "what if I forgot to commit or stash something". Sounds like insanity from a git POV but it really is freeing.

3. Because of 2, you can just leave conflicts alone and go work on something else (because they are, like you said, essentially stashed). It's fine and actually very convenient.

The thing the article doesn't mention, that makes this all safe, is that trunk / "main" is strictly immutable. All this flexibility is *just* for unmerged WIP. (There are escape hatches though, naturally!)


The "you don't need to worry about resolving conflicts" thing is confusing when you hear it with words, so let me show you what it looks like in practice.

Let's say I have two branches off of trunk. They each have one commit. That looks like this (it looks so much nicer with color, I'm going to cut some information out of the default log so that it's easier to read without the color):

    @  vvxvznow 
    │  (empty) (no description set)
    │ ○  uuowqquz 
    ├─╯  foo
    │ ○  uvlpytpm 
    ├─╯  bar
    ◆  lwywpyls trunk
    │  feat: blah blah blah
So both `foo` and `bar` are on top of trunk, and I'm also working on a third branch on top of trunk (@). Those vvxv and such are the change ids, and you can also see the named trunk there as well.

Now, I fetch from my remote, and want to rebase my work on top of them: a `jj git fetch`, and then let's rebase `foo` first: that's `jj rebase uu -o trunk` (you only need uu instead of uuowqquz because it's a non-ambiguous prefix, just like git). Uh oh! a conflict!

    @  vvxvznow
    │  (empty) (no description set)
    │ ×  uuowqquz (conflict)
    │ │  foo
    │ ◆  tswtuqmu
    ├─╯  chore: whatever
    ~  (elided revisions)
    │ ○  uvlpytpm
    ├─╯  bar
    
Note that jj did not put us into a "hey there's a conflict, you need to resolve it" state. It just did what you asked: it rebased it, there's a conflict, it lets you know.

So why is this better? Well, for a few reasons, but I think the simplest is that we now have choice: with git, I would be forced to deal with this conflict right now. But maybe I don't want to deal with this conflict right now: I'm trying to update my branches in general. Is this conflict going to be something easy to resolve? In this case, it's one commit. But what if each of these branches had ten commits, with five of them conflicted and five not? It might be a lot of work to fix this conflict. So the cool thing is: we don't actually have to. We could continue our "let's rebase all the branches" task and rebase bar as well. Maybe it doesn't have a conflict, and we'd rather go work on bar before we come back and deal with foo. Heck, sometimes, I've had a conflicted branch, and then a newer version of trunk makes the conflict go away! I only have to choose to address the conflict at the moment I want to return to work on foo.

There's broader implications here, but in practice, it's just that it's simply nicer to have choice.


In practice, it isn't. What you're identifying as potentially nightmarish - and no doubt quite tedious in git - are things that JJ enables you to do with a small subset of commands that work exactly how you expect them to work _in every workflow context_ in which they are needed.

Thinking specifically about conflicts: being able to defer conflicts until you're ready to deal with them is actually great. I might not be done with what I am actually working on and might want to finish that first. being forced into a possibly complicated conflict resolution when I'm in the middle of something is what I'd actually consider nightmarish.

When you want to solve the conflict: `jj new <rev>`, solve the conflict, then `jj squash`, your conflict resolution is automatically propagated to the chain of child commits from the conflict.


Remember when you used SVN or whatever before git, and you loved git because of how easy it is to make branches?

With branches, jj is to git what git was to SVN. It's an order of magnitude less friction to do branching in jj than git.

Not long ago, I pulled from main and rebased my branch onto it - merge conflicts. But I wanted to work on some other feature at the moment. Why should I have to fix this merge conflict to work on a feature on a totally different branch? With jj, I don't. I just switch to the other branch (that has no conflict), and code my new feature. Whenever I need to work on the conflicted branch, I'll go there and fix the conflict.

Once I started using jj, I realized how silly it was for git to have separate concepts for stash and index. And it's annoying that stash/index is not version controlled in git. Or is it? I have no idea.

In jj, a stash is simply yet another unnamed branch. Do whatever you want there. Add more commits. Then apply it to any branch(es) that you would like to. Or not.

Why does git need a separate concept of a stash? And wouldn't you like a version controlled stash in git?

Have you ever made a ton of changes, done a "git add", accidentally deleted some of the changes in one file, done a "git add", and thought "Oh crap!" I suppose that information can be recovered from the reflog. But wouldn't you wish "git add" was version controlled in the same way everything else is?

That's the appeal of jj. You get a better stash. You get a better index. And all with fewer concepts. You just need to understand what a branch (or graph) is, and you get all of it. Why give it a name like "stash" or "index"?

Why does git insist on giving branches names? Once you get used to unnamed branches, the git way just doesn't make sense. In jj you'll still give names wherever you need to.


Yeah I legit do not understand the appeal. I’m willing to be wrong but it’s not clicking with me at all


Anonymous branches are amazing for when you are trying out a bunch of different approaches to a problem. As I search the space of possible solutions for what I'm really looking for, I end up with a tree of various approaches.

Then when you rebase, the entire tree of anonymous branches can be rebased onto main in 1 command. This is why the first class conflicts and not having to resolve conflicts immediately is so important: when i'm rebasing, an entire tree of branches is getting rebased and so if you had to resolve conflicts right away it would be incredibly cumbersome, because I'm rebasing like 30+ commits and a bunch of anonymous branches in a single operation.

I work on top of an octopus merge of all my in-flight PRs. ON top of that merge commit i have a bunch of anonymous branches with various things going on. When I'm ready to submit a PR, I take one of those anonymous branches and rebase it onto main and make it an additional parent of my 'dev-base' merge commit. Then i give that branch a name and submit it as a PR.

Every day when I start working, I rebase this entire subgraph of branches in a single command onto main. all my PRs are up to date, all my anonymous branches are up to date, etc... Takes like 2 seconds. If some of my anonymous branches are in a conflicted state, that's ok, i don't have to deal with it until I want to work on that change again.

These anonymous branches aren't confusing because they all show up in the default revset that is shown when looking at the jj log. I can easily browse through them with jjui TUI and instantly see which ones are what. It's really not confusing at all.

https://ofcr.se/jujutsu-merge-workflow


typical for experienced git users who already 'just don't do' things which git punishes you for; after a decade it's hard to even imagine any other way, not to mention that it might be better. been there, done that, jj is legit after letting go of (some of) git.


I also like the powerful revision querying mechanisms that they pulled in from mercurial. They seem to work just like mercurial revset queries which can be used in various operations on sets of revisions.

I would like them to have mercurial's awesome hg fa --deleted when it comes to history trawling, but apparently for it to work well, they also need to swap out git's diff format for mercurial's smarter one, so I'll be waiting on that for a while I suppose.


> So anything that would be destructive in git (e.g. rebase, pull, squash, etc) can be undone.

It’s possible to recover from these with git reflog, though.


I've used git for years, and used reflog once or twice.

I've used jj for only a year, and have used "jj undo" countless times.

There's a huge benefit to having a simpler mental model.


From my understanding git reflog works on refs and jj op log works on fhe repo as a whole.

E.g. if I rebase some stacked branches then I want to undo it, with git I would reset each branch separately.

With jj you can timetravel the state of the repo in ine command


`jj undo` compared to what exactly?


jj is very flexible when it comes to workflow. One thing to note is that commits don't have to have messages. What I tend to do is to run `jj new` frequently while I work on something and leave all of them without messages. Then when I'm ready to make my actual commit, I squash the temporary commits together and then add a message. If my changes are separable, I can split the commits before squashing. This workflow acts as a kind of undo history. I can easily go back to what I had 5 minutes ago and try a different approach, but then also jump back to my original changes if I want. It makes experimentation much easier compared to git.


The DGX Spark is probably the best bang for your buck at $4k. It's slower than my 4090 but 128gb of GPU-usable memory is hard to find anywhere else at that price. It being an ARM processor does make it harder to install random AI projects off of GitHub because many niche Python packages don't provide ARM builds (Claude Code usually can figure out how to get things running). But all the popular local AI tools work fine out of the box and PyTorch works great.


It's $4.7K now, darn inflation!

https://marketplace.nvidia.com/en-us/enterprise/personal-ai-...

A small joke at this weeks GTC was the "BOGOD" discount was to sell them at $4K each...


The issue is that you usually aren't buying the ebook. You are buying a license to access that ebook and they can revoke that license at any time. Maybe you're okay with that, but many people want to permanently have access to the things they purchased.


Buying a license if you’re pirating, supports the authors while potentially offering you legal protection on the cheap.


This is the kind of problem that Bitcoin was designed to solve.


Isn't Bitcoin impractical for these sorts of transactions (slow, high fees, no privacy, etc)? People always say Bitcoin was designed to solve this sort of thing but whenever I've looked into it it's been fairly impractical for use in most day-to-day transactions.


Bitcoin is so much faster than a credit card transaction that it's not even close. A lightning transaction is near instant, regular bitcoin transfers take in the order of 10 minutes. Credit card transactions take weeks before you get the money, and after that the money can be yoinked back for a multitude of reasons beyond your control as a merchant. The fees are often lower, too. Bitcoiners are for some reason opposed to solving that last issue (no privacy) despite the technology existing in monero. NIH syndrome, I guess.

The real unsolved issue for cryptocurrency is between chair and keyboard. People make mistakes, people are afraid of being robbed. Your average person does not want to be their own bank. You can have a bank or payment processor manage your money for you, but then we're back to the regulated world where Visa and Mastercard can determine what games you're allowed to buy.


I'll have to look at the lightning transactions. My problems with crypto are generally less philosophical (I've known people who ran legal businesses that had trouble getting access to banks so I'm sympathetic to having ways around traditional banks/payment processors) but more practical, the times I've tried it in the past the experience just hasn't been good.


"Credit card transactions take weeks before you get the money" Where is this the case?

The only time I have experienced this being true is refunds, they usually take a bit longer to clear.

When I pay for something online or in person the payment is cleared within seconds, and I get a notification from my back that it has went through.


You will want to look into Lightning which fixes that issue.


Yes. Thankfully 15 years later we do have crypto solutions addressing previous crypto problems


Honestly buying a digital game is perfect. Steam can just give it to you right away, and if the transaction doesn't clear they can just revoke the game later.


That's only addressing one issue with Bitcoin but the issues abound. I don't know all the issues that would happen but even my rudimentary understanding of payments can see that the high transaction costs are a problem when most of the games I buy are less than 5$.

There are ways to design around these glaring issues but Bitcoin is just a worse product for many transactions (and it's not like payment processors are a particularly good product to begin with).


Only in the presence of DRM—an evil I'd prefer to do without when possible.


It might have been but it is very much not. It's non fungible and transparent resulting in coins, wallets and transactions getting easily traced and blacklisted meaning they can be put into a limbo where nobody is willing to accept them anymore burning there value.

The actual solution would be a fungible and private coin like monero where any of that is impossible by design.


Yes, I agree that Monero is likely a better option. I am also a big fan of Nano because of its instant transactions and zero transaction fees. However it has the same privacy problem as Bitcoin. It would be interesting to see a hybrid of Nano and Monero.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: