281 karma · joined May 31, 2019
That's the core of the difference, to me. But the projects also have a pretty different ethos. SQLite has always prioritized simplicity, often at the expense of features, whereas DuckDB's approach to features seems to be "the more the merrier." E.g. the star feature of this new release, client/server mode. Plenty of people would love to see something similar in SQLite, but it doesn't seem likely.
Good, you might say, and I wouldn't disagree, but Google et al sure would.
There's even a package manager, test harness, etc. And of course it's JVM hosted so it's fairly easy to use Java stuff (stdlib of otherwise) if what you need doesn't exist in CF.
Simon Willison has a good explainer on CaMeL: https://simonwillison.net/2025/Apr/11/camel/
I laugh every time I see someone on HN asserting that the web "shouldn't" be used for anything beyond "documents and lightly interactive content", which is not uncomment. There's some real old-man-yelling-at-clouds energy there.
I was never able to trigger it again, so I have no idea whether it was a race condition or some other random one-in-a-million happenstance, but it makes a fun theory at least.
That's my impression, at least. Like I said, I've never actually used a Lisp. Maybe I'm put off by the smug superiority of so many Lisp people who presume that using Lisp makes them better at programming, smarter, and probably morally superior to me.
E.g. if the select is a list of US states, type "N" and it will jump to Nebraska. Continue into "New" and you'll get New Hampshire, etc.
This is better than nothing (and I personally use it all the time) but not a patch on an actual proper select-with-filtering which, yes, you still need JS to implement properly.
I do like dataclasses, though. I find them sneaking into my code more and more as time goes on. Having a declared set of properties is really useful, and it doesn't hurt either that they're syntactically nicer to use.
Even with a cold cache, `bun install` with a large-ish dependency graph is significantly faster than `npm install` in my experience.
I don't know if Deno does that, but some googling for "deno install performance vs npm install" doesn't turn up much, so I suspect not?
As a runtime, though, I have no opinion. I did test it against Node, but for my use case (build tooling for web projects) it didn't make a noticeable difference, so I decided to stick with Node.
I don't think languages should try to include _everything_ in their stdlib, and indeed trying to do so tends to result in a lot of legacy cruft clogging up the stdlib. But I think there's a sweet spot between having a _very narrow_ stdlib and having to depend on 160 different 3rd-party packages just to make a HTTP request, and having a stdlib with 10 different ways of doing everything because it took a bunch of tries to get it right. (cf. PHP and hacks like `mysql_real_escape_string`, for example.)
Maybe Python also has a historical advantage here. Since the Internet was still pretty nascent when Python got its start, it wasn't the default solution any time you needed a bit of code to solve a well-known problem (I imagine, at least; I was barely alive at that point). So Python could afford to wait and see what would actually make good additions to the stdlib before implementing them.
Compare to Rust which _immediately_ had to run gauntles like "what to do about async", with thousands of people clamoring for a solution _right now_ because they wanted to do async Rust. I can definitely sympathize with Rust's leadership wanted to do the absolute minimum required for async support while they waited for the paradigm to stabilize. And even so, they still get a lot of flak for the design being rushed, e.g. with `Pin`.
So it's obviously a difficult balance to strike, and maybe the solution isn't as simple as "do more in the stdlib". But I'd be curious to see it tried, at least.
Like another commenter said, I do think it's partially just because dependency management is so easy in Rust compared to e.g. C or C++, but I also suspect that it has to do with the size of the standard library. Rust and JS are both famous for having minimal standard libraries, and what do you know, they tend to have crazy-deep dependency graphs. On the other hand, Python is famous for being "batteries included", and if you look at Python project dependency graphs, they're much less crazy than JS or Rust. E.g. even a higher-level framework like FastAPI, that itself depends on lower-level frameworks, has only a dozen or so dependencies. A Python app that I maintain for work, which has over 20 top-level dependencies, only expands to ~100 once those 20 are fully resolved. I really think a lot of it comes down to the standard library backstopping the most common things that everybody needs.
So maybe it would improve the situation to just expand the standard library a bit? Maybe this would be hiding the problem more than solving it, since all that code would still have to be maintained and would still be vulnerable to getting pwned, but other languages manage somehow.
One question, more out of curiosity than any genuine need: do you (or do you plan to) support any kind of trait/interface based polymorphism? E.g. it's a pretty common idiom to have a function that works on "any iterable type" and that sort of thing, which seems like it would be best modeled as an interface. I guess you could argue that's at odds with Python's tradition of "duck typing" but then again, so is static typing in general so I'm not sure.
To answer your questions in order,
a) I haven't done much work with embedded Python, but like any dynamically-typed language that runs in a VM there's a lot of runtime infrastructure that adds latency, complexity, energy consumption, bundle size, etc. It sounds like this project aims to remove the vast majority of that. So take startup time, for instance: Normal Python takes ~50ms to fire up the interpreter and get into actual user code. If I'm understanding it correctly, with PyXL that would be vastly lower. Although I guess the ARM chip still has to load the code onto the FPGA, so maybe not, idk.
b) and c) are kind of the same question, to me - at least, "why use Python for embedded" is a subset of "why use Python at all."
For me, Python more than any other language is great at getting out of its own way, so that you can spend your precious brain energy on whatever problem you're solving and less on the tool you're using to solve it. This is maybe less true in recent years, as later Pythons have added a lot more complex features (like async/await, for instance, which I actually really like in Python but definitely adds complexity to the language).
Finally, I think a lot of it comes down to personal style/taste/chance (i.e. if Python is the first language you encounter, you're probably more likely to end up liking Python.) The Zen of Python[0], which you may have seen, does a good job of explaining the Python way of approaching problems, although like I said a few of those principles have been less-rigidly adhered to in recent years (like "there should be only one way to do it.")
If you hang out in Python circles, you'll probably come across the phrase "Python fits your brain." I'm not sure where it was originally coined but it very definitely describes my experience with Python: it (mostly) just works like I expect it to, whether that's with regard to syntax, semantics, stdlib, etc.
Not that it doesn't have its bad points, of course. Dependency management, as you mentioned, can be a bit hellish at times. A lot of it comes down to the fact that dependencies in Python were originally conceived as systemwide state, much like dynamically-loaded C libs on Linux. This works fine until you need to use two different, mutually-incompatible versions of the same lib, at which point all hell breaks loose. There have been various attempts to improve on this more recently, so far uv[1] looks pretty promising, but time will tell.
The one saving grace of Python dependencies is that it has a very rich standard library, so the average Python project tends to have way fewer total dependencies than the average project in, say, JS or Rust.
The typing story for Python is also a bit lacking. Yes, there are now optional type hints and things like MyPy to make use of them, but even if your own code is all completely typed, in my experience it's usually not long before you need to call out to something that isn't well-typed and then your whole house of cards starts to fall apart.
Anyway, just my rambling $0.02.
* Being able to specify a db at startup would be pretty cool. I'm teaching a class on SQL this summer and I'm already envisioning workflows where a gatekeeper proxy spins up duckdb-ui containers on-demand for users as they log in/out, and it would be much better if the UI can be pre-seeded with an existing database.
* This is maybe a big ask, but markdown cells in notebooks would be nice. Again thinking of my classroom use-case, it would be nice to distribute course materials (lessons/exercises/etc) as notebooks, but that's a bit of a non-starter without markdown or some equivalent content-centric cell type.
* Not a feature request, I just have to say I'm a big fan of how well it handles displaying massive datasets with on-demand streaming and all. I was imagining that I'd have to introduce the `LIMIT` clause right off the bat so that people don't swamp themselves with 100k's of rows, but if I end up using this then maybe I can hold off on that and introduce it at a more natural time.
Regardless, this is great and I definitely have uses for it outside the class I mentioned, so thanks!
To expand: At $dayjob we use AWS, and we have no plans to switch because we're tiny, like ~5000 DAU last I checked. Our AWS bill is <$600/mo. To get anything remotely resembling the reliability that AWS gives us we would need to spend tens of thousands up-front buying hardware, then something approximating our current AWS bill for colocation services. Or we could host fully on-prem, but then we're paying even more up-front for site-level stuff like backup generators and network multihoming.
Meanwhile, RDS (for example) has given us something like one unexplained 15-minute outage in the last six years.
Obviously every situation is unique, and what works for one won't work for another. We have no expectation of ever having to suddenly 10x our scale, for instance, because we our growth is limited by other factors. But at our scale, given our business realities, I'm convinced that the cloud is the best option.
Lowering prices sounds nice, but my understanding has always been that it would come at the cost of less actual wealth overall.
So that leaves the various automatic options, either synchronous, debounced, or the fancy targeted version. This seems like a pretty straightforward complexity/performance tradeoff to me, with the synchronous version being the simplest (both to implement and to understand) and going up from there.
With that in mind, I'm inclined toward the middle option (changes are synced automatically, but batched in the next microtask) since it feels like the best balance of complexity/usability. Seems like it would eliminate some of the biggest performance footguns, without being too much of a bear to implement or too difficult to understand.
On the other hand, I would personally also be ok with no syncing at all, just the initial clone when an option is selected, if it would mean we get this feature sooner. Really looking forward to not having to roll my own dropdowns.
Anyway, if this is where to share our trashy fantasy guilty pleasures, I recently discovered and devoured the Cradle series by Will Wight. Fun if you're at all into "progression fantasy" (also known as LitRPG) where the characters go through a very clearly-delineated "leveling up" process.
Also the only books I've ever run across with outtakes at the end, which I thought was fun.
That said, I do agree that too many red flags like that and I will put down a book. And some are stronger than others; I'm 100% with you on the harem thing because any book like that is most likely just an excuse for all the sex scenes.