barakm
Never mind the shameless self-promotion, doing it while decrying self-promotion means I’m never looking at your app, full-stop.
There's the usual cognitive shift, and in my case a bit of a best-practice shift I had to go through to get comfortable with `jj` -- specifically, keeping the repo directory pristine (and putting my temp output in a git-ignored dir, or outside the repo) because /everything/ is tracked. Flip side being, I've forgotten to `git add` new files at least a few times a year, and now that won't be an issue.
But yeah, can highly recommend, and I'm excited to start to jump between multiple open branches^Wbookmarks at will and learn more about the intricacies of conflict management (and the original link is a good glimpse at that!)
There's a whole operation log (`jj op log`), as another sequence of actions, and you can undo them. It gets crazier from there, but I've also been enjoying jujutsu lately and I had to RTFM a good couple of times to get comfortable with it.
From someone acquired by ServiceNow… I hope your stock options are worth it
Everyone starts with infinite gelt — or at least a liver — and ante/paying into the pot is either taking a drink or paying a drink token. The four actions are then:
- Nothing
- Acquire a newly created token
- Everybody else: drink, or exile a token
- You: drink, or exile a token
Don’t need to run PRISM to figure how quickly that devolves.
Who’s punk what’s the score?”
Get outta here with the gatekeeping
Sharing e2e test suites (realistically, two different test binaries to run at CI time) is something I'm cleaning up right now.
I love Rye. It does what it says on the tin. It makes the whole venv/Python-version/packaging process actually pleasant, and it’s invisible to someone used to Python-official usage (pyproject.toml et al). And it makes Python feel like Cargo, which is a great thing to work with too.
If you have a link for that, I’d be much obliged
I guess I’m confused. This is honestly the problem that most vector storage faces (“curse of dimensionality”) let alone the indexing.
I assume that you meant 768 dimensions * 8 bytes (for a f64) which is 6144 bytes. Usually, these get shrunk with some (hopefully minor) loss, so like a f32 or f16 (or smaller!).
If you can post how you fit 768 dimensions in 96 bytes, even with compression or trie-equivalent amortization, or whatever… I’d love to hear more about that for another post.
Ninja edit: Unless you’re treating each dimension as one-bit? But then I still have questions around retrieval quality
The article is also right that Redis is kinda 'complete' and merely staying the course and slowly maintaining bugs/CVEs/etc. is a vaild type of fork.
If Redict happens to become the standard 'open' alternative (eg, OpenSearch, OpenTofu, etc), I'll suck it up and use his fork. We need less SSPL BS and more just 'complete' software. I may not like that jerk, but I don't like the jerks who made the re-licensing decision much, much more.
The worst part of Rust, too, is that async/await is tacked on— and it’s just a bad primitive to start with.
I have many more thoughts on this that I might like to blog about, but it can be improved by having a async runtime of some kind (we don’t call malloc a runtime, but it is— and you need something similar for ergonomic async) — to wit, the de facto pseudo-answer for this in Rust is tokio (which should just be promoted to the stdlib, at this point; the vast majority of async code depends on it’s particularities).
It’s also causes quote-unquote “function coloring problems” left, right, and center — which is also avoidable. Just for kicks, consider a language with “call-async”/“yield”. Tie that in with a runtime and this whole topic becomes much, much, cleaner. Async at the callsite! (This is the blog I’ve been meaning to write)
Check yourself before you wreck yourself. And yes, check pun intended.
That Rust can check these somewhat more explicitly (rather than via good coding style) and that C++ also allows you to do arbitrary permutations (a la non-const references) is what you’re talking about. But ownership is very very real in C++! Just look at the craziness that is move semantics!
Sorry, it was totally in the tweet. Literally used the word replaced
What you’re saying is true— if you replace an abstract state with an atom — but the problem here is people are thinking about individual atoms, and not static arrangements of atoms in a in a universe.
Edit: Or, put another way, you changed the game. Of course there are more states in a kilobyte than the sheer number of atoms. But when you start claiming multiverses… no, it doesn’t work. Which the tweet did, and it confuses things.
To best guess, there are about 10^24 stars in the sky. That’s about 2^80.
That means you could simply, on Earth-prime, give an id to all the stars in 2^944 universes. Way way less than the multi-multiverse in question, let alone anything atomic.
As my comment below, it’s maybe a couple dozen atoms, in perfect conditions (the conditions are again absurd) so this is some definite jiggery-pokery and let’s focus on what they got right? (Ie, how many states a kilobyte can take)
Even if you had a perfect 3D coordinate system and atoms worked on float64 boundaries, you’d still have 64 bits to represent one atom. So you could fit, at best, 128 atoms. These are the competing scales.
Unless you knew ahead of time the exact state of an entire universe, then the kilobyte would be your key into that value, as it were.
(Ninja edit again: you’d need 3 float64s! So 128/3 atoms in a kilobyte. Not much. Point stands)
I digress. Assume a bit for every “if” statement (branch) that is taken within a function (less those that are deeply nested and don’t affect each other). That’s the Kolomogrov complexity.
Yes, if an atom was compressible to a bit, you could represent this many universes. It’s analogous to a perfect compression dictionary.
But that’s the rub: an atom isn’t compressible to a bit, at least in this universe. So you have these massive scales competing against each other. The more you say about the atom, the fewer multiverses you have (on an exponential scale!)
It’s an okay way of expressing how many states a kilobyte can take, but what that state means (is it a universe per state or an arrangement of about 1024 ascii characters?) is what’s important.
(Ninja edit: That would imply you can arrange 1024 ascii characters in that-many-universes ways! That’s also fun!)
Contrary to your first statement though, there’s very little turnabout in the Go community and your Go-hating child posts fit into the two camps you mention at the end. We wanted it too, even feeling hamstrung!
I’m an old Gopher and I’ve spent a lot of my career in C++ and, now, Rust, so it’s not like I don’t understand generics. But I’ve also seen the space-cadet architectures that come out of overuse thereof. (Rust has a latent version of this, what with Arc<Mutex<T>> being the only way to get things done, come at me).
A common argument from the peanut gallery is that Go folks hate generics. No. I just hate the overly meta use thereof. I’ve long wanted an honest generic in Go for a few container types. This shows up as a desperate need, eh, maybe twice a sizeable project (and in a different way each time!). And I hate working around it but I do.
So it’s disingenuous at best to say Go folks don’t understand generics or are buying a party line thereof. We know it well, and know the nightmares it can lead to. So maybe appreciate some caution in giving the mice a cookie?
This isn’t the first iteration of this war, even. Another thing Go eschewed (that I rarely hear argued) is classes and, particularly, subclasses! Yet, every so often (including a recent project) that would be a really useful paradigm. But OOP is not “in vogue” and so that’s not one of the BS battlegrounds. Point is, all languages have pros and cons and there’s no one right way.
To quote a famous film, “Life is pain. Anyone who says otherwise is selling something” :)
Which is why nothing of value is lost by ignoring it, IMO.
Parent post is right that lower coverage degrades rapidly... the difference between 65% and 75% is huge. But the ancestor post is right that there’s large diminishing returns too.
I’ll qualify this with recommending leaning hard into lints and type checkers and the like. Eliminating whole classes of errors gives the edge; rather than writing test cases in, say, Python to ensure that a string-mangling function raises the “correct” exception if passed an int… just enforce mypy checking instead. And then get your type coverage up to 75-80 percent. Fuzzers too. Get more overall coverage by letting the computer do the work.