18 ms·
C Is Best (2025)
- alexpadula 9mo agoDRH writing truth! People love to jump to Rust or C++.
- dfedbeef 9mo agoC is good
- kayo_20211030 9mo agoYup. But, they're all good in their own way. They're just a means to an end. If the end result is good, reliable, maintainable: whatever you use is good.
- sylware 9mo agoWRONG! Plain and simple C is, by far, one of the current _LESS WORSE_ performant alternatives which can be used, actually, from low level to large applications. C syntax is already waaaaay to rich and complex (and ISO is a bit too much pushing feature creep over 5/10 years cycles).
- alexpadula 9mo agoInteresting! Let’s start this debate! I love C, when I wrote my first programs in it as a teenager, I loved the simplicity, I love procedural code. Large languages like C++ and or Rust are just too much for ME. Too much package. I like writing code in a simple way, if I can do that with a small amount of tools, I will. You can learn C and be efficient in it within a couple weeks. C systems are just built better, faster, more stable, portable, and more! This is my 2 cents.
- sylware 9mo agoIt is a complex matter. But it narrows down to one thing: the number of real-life alternative compilers, which is in direct relation to this benchmark: can a small team of average devs, or an individual average dev, develop with reasonable effort and time and near 0 technical dependence, a real-life alternative of a compiler. It is a protection of developer/vendor lock-in, in the SDK realm. Most honnest software developers know the answer: for any computer language with an ultra-complex syntax(c++,etc) or which requires an intrusive and tricky runtime (java,etc), the answer is obvsiously "nope". But we all know, for plain and simple C, the answer is "yes" (have a look at cproc and QBE, or scc, tinycc, etc). The new C I am talking about should reduce the effort related to such compiler developement and "fix" all C implicit stuff hiding too much things, kind of error prone. There is a huge pitfall though: linux is not coded in plain and simple C, but in GCC C... which is VERY different, a GCC C alternative, is clancg/llvm, those are not to be called reasonable in any capacity. If linux code would care about having clean assembly source files on top of plain and simple C code, unfortunately it would be slower. BUT, you guess what, for the ability to compile linux with an _REAL ALTERNATIVE_ C compiler (and a small assembler), I will happily accept to have a "slower" kernel.
- kitd 9mo agoThat's the first time I've heard the C syntax being called "too rich". It's the epitome of succinctness IMHO (too a fault, even, or maybe I'm just old). Are you confusing it with C++? If so, you have a point.
- alexpadula 9mo agoHuh. I don’t think I miswrote yes I’m talking about a larger language like c++.
- huhtenberg 9mo agoForgot to switch the account?
- pjerem 9mo agohahaha
- deleted 9mo ago[deleted]
- alexpadula 9mo agoHuh, what switch account I have one account.
- kibwen 9mo agoC's syntax is pretty lacking by modern standards, requiring gross things like The Lexer Hack to resolve ambiguities that other languages just don't suffer from: https://en.wikipedia.org/wiki/Lexer_hack https://en.wikipedia.org/wiki/Lexer_hack . To say nothing of the madness that is C's type declaration syntax, necessitating tools like https://cdecl.org/ https://cdecl.org/ and "the spiral rule" for reading type declarations (which doesn't actually produce the correct result anyway).
- bluecalm 9mo agoSo "modern standard" is to make it easier for compiler writers instead of programmer to read the code? Thanks god C designers had their priorities elsewhere. >>"the spiral rule" Not a problem in 99.99% of cases where it's just: type name = something; with maybe * and [] somewhere.
- hbbio 9mo agoMakes a lot of sense for SQLite to be written in C. It's a heavily optimized and debugged database implementation: Just look at btree.c with all its gotos :) The only language that would make sense for a partial/progressive migration is zig, in huge part due to its compatibility with C. It's not mentioned in the article though.
- alexpadula 9mo agoMaybe DRH will see this and update the page !
- bobajeff 9mo agoZig hasn't even had it's first release yet. And projects written in it still break in new releases. Given their stance on boringness and maturity it would make no sense for Sqlite to consider zig yet.
- alexpadula 9mo agoSQLite is never gonna be rewritten by its creators in another language. That is highly doubtful considering the age of SQLite and the roadmap for support I think until 2060 or mid 2050s based on what I’ve read.
- nicoburns 9mo ago> SQLite is never gonna be rewritten by its creators in another language. Almost certainly correct. It is however being rewritten in Rust by other people https://github.com/tursodatabase/turso https://github.com/tursodatabase/turso. This is probably best thought of as a seperate, compatible project rather than a true rewrite.
- przmk 9mo agoI'm biased but when I see Discord as the only way of communication, it doesn't make for a serious project. I wish more projects would rely on IRC/Matrix + forums.
- graphviz 9mo agoAbsolutely.
- klaussilveira 9mo ago> Rust needs a mechanism to recover gracefully from OOM errors. Linus also brought this up: https://lkml.org/lkml/2021/4/14/1099 https://lkml.org/lkml/2021/4/14/1099
- silon42 9mo agoHe's not wrong, but needs to clean own house a bit.
- kibwen 9mo agoNone of Rust's language features allocate; not arrays, not closures, not iterators. Everything is stack-allocated by default. Rust code doesn't malloc unless you use a library that calls malloc; in other words, exactly like C. Rust fully supports turning off the parts of the standard library that perform allocation, and this is precisely what embedded code and the Linux kernel does. So Rust already gives you full control.
- alexpadula 9mo agoGreat to know!
- jsheard 9mo agoYeah, it's not ideal that the standard library currently has blind spots around allocation and I hope those get resolved eventually, but if you're rolling everything from scratch in C anyway then it's not much of a stretch to likewise roll your own Rust primitives in places where the included batteries don't work for you.
- nialv7 9mo agowell, as an example, Vec::push doesn't have a way to report allocation failure. it will just panic, which is not acceptable in the kernel.
- imglorp 9mo agoThat seems like an enormous question. Is anyone working on it?
- ForHackernews 9mo agoThere's already attempted re-implementations of SQLite in Rust, so if it really is a good approach, time should tell. https://turso.tech/blog/introducing-limbo-a-complete-rewrite-of-sqlite-in-rust https://turso.tech/blog/introducing-limbo-a-complete-rewrite...
- alexpadula 9mo agoReally time will tell indeed. It’s too early.
- kayo_20211030 9mo agoWhen the Rust version has the same take-up as the C version I know and trust, I might use it. Until then I'll wait. What's available now is good. I'm in no hurry to use an alternative. I like the idea of a reliable black-box, and I don't overly care how the black-box does its magic.
- enricozb 9mo agoThe final comments in this text seem sobering and indicate an openness to change. I worked recently on a project to migrate RediSearch to Rust, and this was partially motivated by a decent number of recent CVEs. If SQLite doesn't have this problem, then there needs to be some other strong argument for moving to Rust. I also think it's important to have really solid understandings (which can take a few decades I imagine) to understand the bounds of what Rust is good at. For example, I personally think it's unclear how good Rust can be for GUI applications.
- deleted 9mo ago[deleted]
- kibwen 9mo agoIt's nice that they don't dismiss out-of-hand the idea of using a language other than C (the conclusion is far less dogmatic than the editorialized title here suggests (the actual title of the page being "Why Is SQLite Coded In C?")). But let's be clear that the stability and "boringness" that C currently enjoys took literal decades to realize (pre-ANSI C was a wild-west shitshow that makes pre-ECMA Javascript look tame by comparison), and giving the same leeway to other languages probably doesn't suggest using e.g. Rust until at least 2040 or so.
- elcritch 9mo agoSomething like Ada/SPARK might be a better choice for something like SQLite as well.
- feverzsj 9mo ago*C-API is the best. As a language, it's too basic. Almost every C projects try to mimic what C++ already has.
- alexpadula 9mo agoThat’s not true, give me an example used in real code out in the wild?
- pjmlp 9mo agoSince I am feeling generous, here are two examples, https://docs.gtk.org/glib/ https://docs.gtk.org/glib/ https://github.com/antirez/sds https://github.com/antirez/sds
- alexpadula 9mo agoThank you
- pjmlp 9mo agoI considered it outdated back in 1993, when all major GUI based systems (Apple, IBM, Microsoft) were going with C++ for userspace applications. Then came the rise of FOSS adoption, with the GNU manifest asserting to use only C as compiled language. "Using a language other than C is like using a non-standard feature: it will cause trouble for users. Even if GCC supports the other language, users may find it inconvenient to have to install the compiler for that other language in order to build your program. So please write in C." The GNU Coding Standard in 1994, http://web.mit.edu/gnu/doc/html/standards_7.html#SEC12 http://web.mit.edu/gnu/doc/html/standards_7.html#SEC12
- 112233 9mo agoFor big, fixed environments like Qt — sure. For embedded? Please no. Basic is good. Feel free to reimplement C++, your C library still will not have: most of STL as a dependency; unwind tables in all code (including C!); ctor/dtor arrays; insane kilobyte-sized symbols.
- psychoslave 9mo ago2017 at least[1] but "This page was last updated on 2025-05-09 15:56:17Z." [1] https://web.archive.org/web/20170701061906/https://sqlite.org/whyc.html https://web.archive.org/web/20170701061906/https://sqlite.or...
- alexpadula 9mo agoI’m sure it’ll be updated more
- baq 9mo agoI'd like to see Steve Yegge unleash his Gas Town with a convoy or whatever it's called to rewrite the sqlite in Rust obviously preserving 100% test coverage. Results are a guaranteed bombshell regardless of whether it succeeds or fails.
- sph 9mo agoWhat’s Steve Yegge got to do with Rust? And who’s gonna sponsor some 10,000 hours to “rewrite the sqlite in Rust obviously preserving 100% test coverage”? Will he do it just for the memes, or did you think Rust is so cool there is no effort involved? Let’s be serious now.
- baq 9mo agoWhat's not serious? He's got a tool which he claims should be able to handle projects of this scale, the existing test coverage is what makes it not immediately impossible and about the memes, have you read his gas town post? Of course it's for the memes, but more importantly it'll validate his vision of the future in the eyes of quite literally everyone if successful.
- lapcat 9mo agoThe only changes in 2025 were a few minor typos fixed. Nothing substantial.
- dkdcio 9mo agoprevious discussion a few months ago: https://news.ycombinator.com/item?id=45584464 https://news.ycombinator.com/item?id=45584464 I believe this article is from a few years ago
- alexpadula 9mo agoUpdated quite often I see.
- grougnax 9mo agoC is considered harmful. They should rewrite it in Rust.
- huhtenberg 9mo agoIt's either trolling or sarcasm. May be both.
- grougnax 9mo agoNot trolling. Everyone knows C is not safe.
- alexpadula 9mo agoC is safe if you know how to write it. Jokes aside yes you need to be more careful.
- Rochus 9mo agoLife as a whole is not safe, and not everyone seems to be aware of this.
- rvz 9mo agoThey actually should. As such a rewrite went so well for sudo-rs.
- 112233 9mo agoThe article mentions 100% code coverage with tests as one of requirements from their users, and having "safe languages" emit defensive asserts and checks when compiling correct code means 100% branch coverage is impossible. How do you propose to address it with rust?
- alexpadula 9mo agoWhat
- Rochus 9mo ago
- lordnacho 9mo agoThe bit about why not OOP seems a bit old. I think we're past a point where people are going for OOP as the default shape of code. Overall, it makes sense. C is a systems language, and a DB is a system abstraction. You shouldn't need to build a deep hierarchy of abstractions on top of C, just stick with the lego blocks you have. If the project had started in 2016, maybe they would have gone for c++, which is a different beast from what it was pre-2011. Similarly, you might write SQLite in Rust if you started today.
- alexpadula 9mo agoI think they would have still gone with C. I still do.
- mrweasel 9mo agoThe author of ZMQ had an article about regretting not using C over C++. Picking Rust for a "modern" version of SQLite could easily go down a similar route in the end. https://web.archive.org/web/20250130053844/https://250bpm.com/blog:4/ https://web.archive.org/web/20250130053844/https://250bpm.co...
- scottlamb 9mo agoRegret is possible with any language, but I'd be surprised if someone regretted choosing Rust for the reasons in the article you linked: * Error handling via exceptions. Rust uses `Result` instead. (It has panics, but they are meant to be strictly for serious logic errors for which calling `abort` would be fine. There's a `Cargo.toml` option to do exactly that on panic that rather than unwinding.) (btw, C++ has two camps here for better or worse; many programs are written in a dialect that doesn't use exceptions.) * Constructors have to be infallible. Not a thing in Rust; you just make a method that returns `Result<Self, Error>`. (Even in C++ there are workarounds.) * Destructors have to be infallible. This is about as true in Rust as in C++: `Drop::drop` doesn't return a `Result` and can't unwind-via-panic if you have unwinding disabled or are already panicking. But I reject the characterization of it as a problem compared to C anyway. The C version has to call a function to destroy the thing. Doing the same in Rust (or C++) is not really any different; having the other calls assert that it's not destroyed is perfectly fine. I've done this via a `self.inner.as_mut().expect("not terminated")`. They say the C only has two states: "Not initialised object/memory where all the bets are off and the structure can contain random data. And there is initialised state, where the object is fully functional". The existence of the "all bets are off" state is not as compelling as they make it out to be, even if throwing up your hands is less code. * Inheritance. Rust doesn't have it.
- baranul 9mo agoEvery project and programmer shouldn't feel they have to justify their choice not to use Rust (or Zig), who seem to be strangely and disproportionately pushed on Hacker News and specific other social media platforms. This includes the pressure, though a bit less in recent years, to use OOP. If they are getting good results with C and without OOP, and people like the product, then those from outside the project shouldn't really have any say on it. It's their project.
- alexpadula 9mo agoI get asked this all the time regarding TidesDB. Why didn’t you choose Rust? Well. Yeah this super common. Great comment.
- misnome 9mo ago> strangely and disproportionately pushed on Hacker News There is literally nothing strange or disproportionate. It's incredibly obvious that new languages, that were designed by people who found older languages lacking, are of interest to groups of people interested in new applications of technology and who want to use their new languages. > then those from outside the project shouldn't really have any say on it. It's their project. People outside the project are allowed to say whatever the hell they want, the project doesn't have to listen.
- shevy-java 9mo agoI am pretty certain Rust is pushed more than other languages. Whether warranted or not is another topic, but I think the OP has a point here.
- whatamidoingyo 9mo ago"having a say on something", in OP's context, means authority and influence over decisions... People can say whatever they want, yes, but not everyone can "have a say on something".
- hu3 9mo agoI understand "shouldn't really have any say on it" as shouldn't expect to infuence the project. Not that they are not allowed to say anything. Otherwise they would have written something along the lines of "shouldn't say anything about it".
- publicdebates 9mo ago> Rust needs to mature a little more, stop changing so fast, and move further toward being old and boring. One of the very strange things about C is that it is designed by a committee that is inherently conservative and prefers to not add new features, especially if they have any chance of breaking any compatibility. This seems necessary before Rust ever becomes an old, boring language. But I don't see Rust ever going in such a direction. It seems fundamentally opposed to Rust's philosophy, which is to find the best solution to the problems it's trying to solve, at any cost, including breaking compatibility, at least to some degree.
- alexpadula 9mo agoUh oh! I think Rust may settle down eventually. Who knows, maybe one of the devs will chime in.
- IshKebab 9mo agoIt's pretty settled now.
- pie_flavor 9mo agoThe 'some degree' is pretty important, though. The Rust language undergoes backwards incompatible changes sometimes, but the Rust tools do not. The 2024 edition has breaking changes since the 2021 edition, but all compilers can compile all historical editions and will do so forever, and new language features are available in as many editions as possible, and editions can be mixed in a dependency tree, so you do not ever have to update your 2015 edition code for anything.
- TZubiri 9mo agoSounds like textbook bc break. I'm curious as to what you think a bc break would look like? Consider python2 and python3, you don't need to update your python2 code really, you can just use the python2 interpreter.
- 9mo ago
- bobajeff 9mo agoI love C and Assembly and I'm impressed by the things people can build in those languages and often (not always) I can understand the code written in it. It's also true that code written in it is available to every other language. For that I'm very happy, as I'm mostly working in higher level languages that can call things like sqlite. Just imagine if all of Chromium was written in C and used simpler tools like GNU Make and Git for it's projects.
- jll29 9mo agoBTW, the study referred to in 1.2, which claims that SQLite was faster than the file system is not supported by the numbers in the study referenced: https://github.com/chrisdavies/dbench https://github.com/chrisdavies/dbench
- shakna 9mo ago> For a my real(ish) world scenario, SQLite-- once warmed up-- is roughly twice as fast as the file system.
- signa11 9mo agois that actually surprising ? once data leaves the fs and is all (or in part) bought into a processes memory, access is just limited by the memory bandwidth. ofcourse if you start touching uncached data things slow down, but just for a short while…
- lapcat 9mo agoThis submission title has been editorialized, contrary to the HN guidelines. The article title is actually "Why Is SQLite Coded In C". Also, the article appears to be quite old, so the submission should have a year appended. See also previous discussions, the last of which was only a few months ago: https://hn.algolia.com/?dateRange=all&page=0&prefix=false&query=https%3A%2F%2Fsqlite.org%2Fwhyc.html&sort=byDate&type=story https://hn.algolia.com/?dateRange=all&page=0&prefix=false&qu...
- alexpadula 9mo agoIt was updated in 2025.
- lapcat 9mo agoI just did a diff with the Wayback Machine. Have you? The only changes were a few minor typos fixed. I would strongly urge you to read and respect the HN guidelines and FAQ. https://news.ycombinator.com/newsguidelines.html https://news.ycombinator.com/newsguidelines.html https://news.ycombinator.com/newsfaq.html https://news.ycombinator.com/newsfaq.html
- nu11ptr 9mo agoI am a pretty serious "Rustacean", but I like to think "for the right reasons". A rewrite in Rust of the main project would make very little sense, unless there is some objective the project wants that can't be met with C (see below). This person presents a well thought out case on why it makes little sense to rewrite, especially in the final section. Rust is great for many things, but when you have something old that is already so well tested and accessible on all sorts of obscure platforms, it makes little sense to rewrite, and the likely result would be more bugs, not less, at least in the short term. All that said, some have found reasons to rewrite in Rust, and are currently working on that: https://turso.tech/blog/introducing-limbo-a-complete-rewrite-of-sqlite-in-rust https://turso.tech/blog/introducing-limbo-a-complete-rewrite...
- alexpadula 9mo agoI agree. We will see how Limbo turns out :)
- giancarlostoro 9mo agoI forgot what Limbo was, Rust rewrite of SQLite, now called Turso. https://github.com/tursodatabase/turso https://github.com/tursodatabase/turso I could see it being useful for pure Rust projects once its completed. I mean in Java / Kotlin land, I prefer to use H2 in some cases over SQLite since its native to the platform and H2 is kind of nice altogether. I could see myself only using this in Rust in place of SQLite if its easy to integrate and use on the fly.
- erichocean 9mo agoThe equivalent "platform native" database for Clojure is Datalevin [0], which has a Datomic-like Datalog query language with SQLite-style semantics. Recommended. [0] https://github.com/juji-io/datalevin https://github.com/juji-io/datalevin
- gwbas1c 9mo agoHonestly, instead of porting SQLite to Rust, IMO, it makes more sense to make an easier-to-use embedded database (in Rust) first.
- a-dub 9mo agoi haven't seen any rust projects yet that maximize embeddability, portability, space and transparency. maybe an argument could be made for the linux kernel stuff, but nothing like a sqlite that gets compiled and included in a million things on a million platforms ranging from high level interpreter wrappers on general purpose computers to teeny microcontrollers where the operating system is a library or some jump targets in rom. that said, just because c is best for sqlite today, doesn't mean c is best for you or what you're trying to do.
- WhyNotHugo 9mo ago> Nearly all systems have the ability to call libraries written in C. This is not true of other implementation languages. This is no longer true. Rust, Zig and likely others satisfy this requirements. > Safe languages usually want to abort if they encounter an out-of-memory (OOM) situation. SQLite is designed to recover gracefully from an OOM. It is unclear how this could be accomplished in the current crop of safe languages. This is a major annoyance in the rust stdlib. Too many interfaces can panic (and not just in case of an OOM), and some of them don’t even document this.
- ethin 9mo ago> This is no longer true. Rust, Zig and likely others satisfy this requirements. Rust and Zig satisfy this by being C ABI-compatible when explicitly requested. I'm pretty sure that that solution is not actually what the author meant. When you don't explicitly use `extern "C"` in Rust or `export` in Zig, the ABI is completely undefined and undocumented. I would go as far as arguing that the ABI problem, with Rust at least, is even worse than the ABI problem C++ has. Especially since Distros are (if memory serves) starting to ship Rust crates...
- goku12 9mo agoThe only reasonable way to solve that problem is to design a standard ABI that supports expression of all features in modern compiled languages like Rust, Go, Zig, Haskell, Ada, etc. It doesn't make any sense to design stable ABIs for each language separately, because then you'll end up with a system directory full of dynamic libraries of several distinct ABIs.
- selfmodruntime 9mo agoEh. I write quite a bit of Rust and this story is not as simple as you tell it.
- Ragnarork 9mo ago> Libraries written in C++ or Java can generally only be used by applications written in the same language. It is difficult to get an application written in Haskell or Java to invoke a library written in C++. On the other hand, libraries written in C are callable from any programming language. Not saying they should have picked C++ but that's a bit untrue. It's quite easy given some thought into the API to invoke C++ code in basically any language which can invoke C code, since you can wrap a C++ implementation in a C interface. I've done it multiple time throughout my career (that ended up being called from Python, Swift, Objective-C/C++, Swift, Java, and Kotlin). And as a side note, you don't have to do object-oriented programming in C++ if you don't want to.
- MeetingsBrowser 9mo ago> It's quite easy given some thought into the API to invoke C++ code in basically any language which can invoke C code, since you can wrap a C++ implementation in a C interface Is it easy to write a nice C interface for C++ that makes heavy use of templates, smart pointers, and move semantics? I've only seen it done for C++ that is more C than C++, or for libraries that were designed to "bail out" to a C interface.
- hmry 9mo agoThat's definitely true. Can't have generics / compile time evaluation across languages. Need to design your code around that restriction ahead of time. SQLite being dynamically typed luckily doesn't have any problems with that. I've actually run into a similar problem with a C library before, because it heavily used macros as part of its API. Glad most developers don't do that.
- Ragnarork 9mo ago> Is it easy to write a nice C interface for C++ that makes heavy use of templates, smart pointers, and move semantics? If the interface itself has or leaks those features, no that's not easy indeed. But if those do not leak, then they can be used internally yes. My point was not that it's easy to wrap a currently existing C++ library that has modern features in its interface in a C interface, especially post-C++11. But that if you design something from the ground up, then it's rather easy (with a certain set of constraints). My bad for not conveying that better.
- uecker 9mo agoI agree that C is best. I think Rust is actually a language with some severe downsides, despite having including some very good ideas and C having some real issues. But it will take a couple of years before one can discuss this rationally without being flamed at.
- MeetingsBrowser 9mo ago> Rust is actually a horrible language Can you expand a little?
- darkhorse13 9mo agoThey never said it's a horrible language.
- MeetingsBrowser 9mo agoThe original comment was edited after I replied.
- uecker 9mo agoYes, sorry, apparently not quick enough. I actually do not think it is horrible. It is a nice language, but I still do not like it and see many downsides. What I hate though is how aggressively it is marketed. See my other response for details.
- MeetingsBrowser 9mo agoThat is fair. Rust is my most used language, and I agree Rust has many downsides and pain points. But for my work, the positives outweigh the downsides of other languages I've used (including Python, Java, C++, and C). But it ultimately depends on your situation. People elsewhere on this post are listing weaknesses of Rust that I consider to be strengths and vice versa.
- IshKebab 9mo ago
- talkingtab 9mo agoOh look. Something works. Lets not break it? How crazy is that? I sometimes wonder if what happens is like this: 1. Have problem. Need higher level computer language. 2. Think about problem. 3. Solve problem - 'C' 4. Think about problems with 'C' 5. Attempt to fix problems with 'C' - get C++ 6. Think about problems with C & C++ 7. Get: Go, F#, Rust, Java, JavaScript, Python, PHP, ...other etc. I tend to do this. The problem is obvious, that I do not repeat step #2. So then I move to the next step. 8. Thinking about how to fix C, C++, Go, F#, Rust, Java, JavaScript, Python, PHP, ...other is too hard. 9. Stop thinking.
- tialaramex 9mo agoAlthough Mozilla's reason to pay for Rust R&D was because of problems with C++ it's probably not most helpful to think of Rust (let alone F#) as an attempt to specifically fix those problems. C is a Worse is Better language (https://en.wikipedia.org/wiki/Worse_is_better https://en.wikipedia.org/wiki/Worse_is_better). The bet is that if it's simpler to implement then the fact that what you're implementing isn't great will be dwarfed by that ease of implementation. And it worked for decades which is definitely a success. You can make a similar argument for Go, but not really for Rust. The other side of the Worse is Better coin is that maybe you could make the Right Thing™ instead. Because implementing C is so easy and implementing the Right Thing™ is very difficult, the only way this would compete is if almost nobody needs to implement the Right Thing™ themselves. In 1970 that's crazy, each Computer is fairly custom. But by 1995 it feels a lot less "out there", the Intel x86 ISA is everywhere, Tim's crap hypermedia experiment is really taking off. And when Rust 1.0 shipped in 2015 most people were able to use it without doing any implementation work, and the Right Thing™ is just better so why not? Now, for an existing successful project the calculation is very different, though note that Fish is an example of this working in terms of full throated RIIR. But in terms of whether you should use C for new work it comes out pretty strongly against C in my opinion as a fairly expert C programmer who hasn't written any C for years because Rust is better.
- kristianpaul 9mo agoTittle should be "C is a Standard"
- nativeit 9mo agoTitle should actually be “Why Is SQLite Coded In C”, since that’s the title of the article.
- alexpadula 9mo agoWell, take "C Is Best" For someone who might not think so they may think "Why?" and click it. I think this makes a bit more sense.
- RcouF1uZ4gsC 9mo agoThis makes sense with the quality and quantity of testing they do. https://sqlite.org/testing.html https://sqlite.org/testing.html >As of version 3.42.0 (2023-05-16), the SQLite library consists of approximately 155.8 KSLOC of C code. (KSLOC means thousands of "Source Lines Of Code" or, in other words, lines of code excluding blank lines and comments.) By comparison, the project has 590 times as much test code and test scripts - 92053.1 KSLOC.
- alexpadula 9mo agoThat's an enormous test suite but considering how large the SQL spec is it makes sense.
- simonw 9mo ago"In a more complete build, SQLite also uses library routines like malloc() and free() and operating system interfaces for opening, reading, writing, and closing files." Whoa. TIL there's a minimal build of SQLite that doesn't even need malloc() and free() ! Presumably for embedded devices. I'd love to see examples of that being used in the wild.
- brightbed 9mo agoWhat does “Go hates assert()” mean?
- nativeit 9mo agoActual title: Why Is SQLite Coded In C
- a_random_user 9mo ago.. one of the safe languages like.. Go.. o_O
- guywithahat 9mo agoGo is a safe language? It has garbage collection and performs checks for things like buffer overflows and use-after-free
- tialaramex 9mo agoYou can have data races in "safe" Go. If you race a trivial object [such as an integer] it's just radioactive and so long as you didn't need it to have any particular value (e.g. you were just going to write it to a log anyway, or you just discard it) you're fine. However if you race a non-trivial object then that's immediately Undefined Behaviour. Of course Go programmers will say "Just don't do that" but that's exactly what C programmers told us about bounds misses, use after free and so on...
- goku12 9mo ago(Memory) safe languages are allowed to guarantee memory safety at any stage, including at runtime using GC and bound checks. That makes every GC language memory safe to a reasonable extend. The novelty in Rust is that it does the same at compile time, mostly automatically.
- Drew_ 9mo ago> Safe languages usually want to abort if they encounter an out-of-memory (OOM) situation. SQLite is designed to recover gracefully from an OOM. As someone who runs into this problem a lot, this is pretty cool! Does anyone know how they can recover from this in SQLite?
- JackSlateur 9mo agoAn oom is when malloc failed So you have to ensure that in such situation, you can execute code that does not require more memory: ensure that the rest only free stuff, or preallocate structures for that purpose
- lelanthran 9mo ago> As someone who runs into this problem [OOM]a lot, this is pretty cool! Does anyone know how they can recover from this in SQLite? How are you running into it? If you're writing in C, idiomatic code works (check the return values of functions that allocate!) If you're in C++, Rust or similar, you have to write pretty non-idiomatically to recover from an allocation failure.
- zabzonk 9mo agohow exactly do you think C and C++ differ here?
- lelanthran 9mo ago> how exactly do you think C and C++ differ here? `new` throws, `malloc` returns. That's a pretty big difference! Idiomatic C++ code never puts a `try` around `new`, while idiomatic C code always checks the return from an allocation.
- zabzonk 9mo agoWell: https://en.cppreference.com/w/cpp/memory/new/nothrow.html https://en.cppreference.com/w/cpp/memory/new/nothrow.html I thought you were talking about the use of malloc in both languages - you never mentioned new in your first post. and i think we have different views on what is "idiomatic" in the languages.
- notorandit 9mo agoI long to see an sq-rust project!
- goku12 9mo agoLike this? https://github.com/tursodatabase/turso https://github.com/tursodatabase/turso Disclaimer: Credit goes to whoever mentioned this in this discussion before me.
- lucasyvas 9mo agoWell they don’t have to wait for Rust in the way they said - they’ve already been forked by Turso which has been moving along for a while now. I wouldn’t mind hearing from them how that’s been going.
- staticassertion 9mo agoThe title is "Why Is SQLite Coded In C", not "C Is Best". The content is far more nuanced than this specific section title suggests.
- fithisux 9mo agoWhat the post says is that you can do software engineering in C and be portable.
- yomismoaqui 9mo agoAs an outsider when I read about Rust it seems like it is positioning itself as the language to rewrite things that already work. It's just the simplistic first feeling of a language, in the same way I feel like Go is the language for Kubernetes/cloud/net servers, Ruby is for Rails, JS is the browser/bootcamp language, Python is Data Science and AI... Sure, you get that safety but you are also throwing the stability that an old (and maintained) codebase has just for the sake of being patched to handle the presssure from the real world. Maybe it's time Rust positions itself as something more than "the language of rewrites".
- knowitnone3 9mo agowho is this that you are claiming is "positioning" itself??? the Rust maintainers? No. Programmers are choosing to write something in Rust and it just so happens they are interested in rewriting something that already exists because they can. You write as if Rust is an entity that chose to position itself. What is your argument here? Rust should just go do something else? You wouldn't dare say that about Python. Also, how dare you put these languages in a corner. I've use ruby for many things other than Rails. JS is much more than a browser language now, and python is much more than data science and AI. Go is much more than Kubernetes/cloud/net servers.
- codr7 9mo ago...at what it does, couldn't agree more. https://github.com/codr7/hacktical-c https://github.com/codr7/hacktical-c
- emorning4 9mo agoI can't imagine how writing C directly could possibly be better than using a language like Dafny and then generating C code. Edit: Dafny: A verification language capable of enforcing invariants
- emorning4 9mo agoDown-voting me without providing a counter comment is just pathetic.
- shevy-java 9mo agoWell, can't argue with it. Ruby and Python are written mostly in C underneath. Many try to replace C. All failed. I'd love to see a language that could satisfy both high end needs and low need needs. I would not know how such a language would look though.
- goku12 9mo ago> Ruby and Python are written mostly in C underneath. > > Many try to replace C. All failed. What do you mean by all failed? Rust supports CPython modules using PyO3 [1]. Even the popular polars dataframe library [2] uses it. [1] https://github.com/PyO3/pyo3 https://github.com/PyO3/pyo3 [2] https://github.com/pola-rs/polars https://github.com/pola-rs/polars
- d_burfoot 9mo agoGiven SQLite's amazing battery of test code, it seems like it would be valuable, illuminating, and not too difficult to write a test implementation in Rust. Can you get the Rust implementation to pass the test suite? Either answer to that question would be interesting.
- EricRiese 9mo agoSQLite's test suite is proprietary. A Rust implementation exists. It's called turso https://github.com/tursodatabase/turso https://github.com/tursodatabase/turso There's a whole company around it.
- alexpadula 9mo agoDid they rename from Limbo to Torso?
- dkdcio 9mo agoyes, mentioned in https://turso.tech/blog/upcoming-changes-to-the-turso-platform-and-roadmap#renaming-limbo-to-turso https://turso.tech/blog/upcoming-changes-to-the-turso-platfo...
- CyberDildonics 9mo agoThe actual title is "Why Is SQLite Coded In C"
- raffael_de 9mo agono, triples is best!
- philipwhiuk 9mo agoGiven they added Section 2 and 3 in response to previous commentary: https://news.ycombinator.com/item?id=16585120 https://news.ycombinator.com/item?id=16585120 it seems rather stupid to take a sub-heading as the title.
- alexpadula 9mo agoI'm certain you can think why I chose that second heading.
- philipwhiuk 9mo agoYeh, clickbait
- IvanK_net 9mo agoMany non-programmers think that programming languages get outdated, just like operating systems or computer hardware, or even some software (old algorithms replaced by better algorithms), and each programmer should "follow trends", since using the same programming language for 10+ years sounds wrong. But programming languages are like Math. It is like saying "multiplying is outdated" or "the square root is outdated".
- knowitnone3 9mo agoif you don't think programming languages can get outdated then why is assembly, fortran, lisp, smalltalk, pascal, basic practically disappeared? programming languages are not like math, it's like the moon
- goku12 9mo agoMany of those are still under active development (both language and tooling) and code is still being written in them. They have hardly disappeared.
- IshKebab 9mo agoNonsense, unless you think the entire field of PL research is doing nothing. The industry learns things and gradually improves, on average. Do you still write FORTRAN and Perl?
- tialaramex 9mo ago> But no other language claims to be faster than C for general-purpose programming, because none are. The "faster than C for general-purpose programming" is a pretty woolly claim so I'm not entirely surprised nobody claims that, but equally I think to be sure that "because none are" would need some serious caveats to make it true. In particular you're going to have to say you think it doesn't matter how much developer time is needed. A project where C programmers spend five hours to make it run in 4 seconds is in this caveat "20% faster" than a project where Alt Lang programmers spend five minutes to make it run in 5 seconds - because only those seconds count. This is not how the real world works so it's a pretty nasty caveat.
- j_w 9mo agoOf course it's true in the case of sqlite. It's one of the most used pieces of software ever, and user cpu time spent is going to dwarf any developer time. Your example should instead be: - 5 hours of developer time to run in 4 seconds * n - 5 minutes of developer time to run in 5 seconds * n As long as n <= 17,700, then the developer time is "not worthwhile." This assumes that you value user time as much as developer time. In the case of sqlite, the user time may as well be infinite for determining that side of the equation. It's just that widely used.
- astrobe_ 9mo agoAlso battery life. 20% less time, 20% more battery. But OP is correct, companies don't care as long as it doesn't translate into higher sales (or lower sales because the competitor does better). That's why you see that sort of optimization mainly in FOSS projects, which are not PDD (profits-driven development).
- bluecalm 9mo ago>>A project where C programmers spend five hours to make it run in 4 seconds is in this caveat "20% faster" than a project where Alt Lang programmers spend five minutes to make it run in 5 seconds - because only those seconds count. This is not how the real world works so it's a pretty nasty caveat. For any project with non-trivial amount of users the C programmer did better. I mean I know companies like to save money and move the costs (time, electricity, hardware costs) to customers but if you care about users any non-trivial speed improvement is worth a lot in aggregate, surely more than your time implementing it.
- stackedinserter 9mo agoAda is best. No UB, strict types, contracts that can be formally proven, runtime checks, better (than phthreds) concurrency, certifiable. It's bitch sometimes but you'll thank it after release.
- senfiaj 9mo agoC is fast and maybe has predictable performance, but, for example, strcmp(), strlen(), strncmp() are not as fast (and also secure) as C++ std::string analogs, unless you don't help a bit by storing the string lengths.
- scottlamb 9mo agoI'm a little surprised they're at all open to a rewrite in Rust: > All that said, it is possible that SQLite might one day be recoded in Rust. ...followed by a list of reasons why they won't do it now. I think the first one ("Rust needs to mature a little more, stop changing so fast, and move further toward being old and boring.") is no longer valid (particularly for software that doesn't need async and has few dependencies), but the other ones probably still are. I write Rust code and prefer to minimize non-Rust dependencies, but SQLite is the non-Rust dependency I mind the least for two reasons: * It's so fast and easy to compile: just use the `rusqlite` crate with feature `bundled`. It builds the SQLite "amalgamation" (its entire code basically concatenated into a single .c file). No need to have bazel or cmake or whatever installed, no weird library dependency chains, etc. * It's so well-tested that the unsafety of the language doesn't bother me that much. 100% machine branch coverage is amazing.
- thisislife2 9mo agoFrom what they have written, the only other language that meets their requirement seems to be Ada: 1. Stability: Ada is an "old and boring" language (aka stable and reliable - the first standard for the language was issued in 1983 and created for the Defence industry) - https://learn.adacore.com/courses/intro-to-ada/chapters/introduction.html#history https://learn.adacore.com/courses/intro-to-ada/chapters/intr... 2. Compatibility: Interoperability features is built-in, allowing you to create Ada libraries that can be used with other languages - https://piembsystech.com/interfacing-ada-programming-with-c-and-other-languages/ https://piembsystech.com/interfacing-ada-programming-with-c-... 3. Embedded Programming: Ada has been designed for embedded programming and the language includes constructs for directly manipulating hardware, for example, and direct interaction with assembly language. - https://learn.adacore.com/courses/intro-to-embedded-sys-prog/chapters/introduction.html https://learn.adacore.com/courses/intro-to-embedded-sys-prog... 4. Ada supports processes / suites to comply with Branch coverage in ISO 26262 ( https://github.com/NVIDIA/spark-process https://github.com/NVIDIA/spark-process ) and Decision coverage in DO-178C ( https://learn.adacore.com/booklets/adacore-technologies-for-airborne-software/index.html https://learn.adacore.com/booklets/adacore-technologies-for-... ). 5. Ada has features supporting memory safety to avoid many memory issues in the first place ( https://www.adacore.com/blog/memory-safety-in-ada-and-spark-through-language-features-and-tool-support https://www.adacore.com/blog/memory-safety-in-ada-and-spark-... ) and using its exception handling and programming techniques (like pre-allocating "guard" memory) can allow Ada programs to tackle fringe OOM errors. 6. Performance: Ada is built for systems programming, is just as fast as C ( https://learn.adacore.com/courses/Ada_For_The_Embedded_C_Developer/chapters/08_Performance.html https://learn.adacore.com/courses/Ada_For_The_Embedded_C_Dev... ), with the added bonus of "modern" programming features that can generate more "reliable" code
- uticus 9mo agoNo it's not. Arch is the best. https://wiki.archlinux.org/title/Arch_is_the_best https://wiki.archlinux.org/title/Arch_is_the_best
- cesaref 9mo agoThe problem with articles like this is that they read a little like justifying a decision that has already been made. I've a feeling that if it was written in C++/Rust/Go/whatever, it would also be possible to justify that decision with similar reasoning.
- dieggsy 9mo agoI think you're not wrong, but it's not necessarily a problem? I might argue that's actually part of the main point the article is making. The software is already written in C, well understood and optimized in that language, and quite stable, so they'd need very compelling reasons for a rewrite. I think the "lingua franca" argument for C and the points at the end about what they'd need from Rust to switch do go beyond merely justifying a decision that's already been made, though.
- epolanski 9mo ago> The C language is old and boring. It is a well-known and well-understood language. This is such an under appreciated feature. I'm tired of languages that just keep adding and adding to a language. Work on the standard library or ecosystem, but stop changing the language otherwise you'll never end up anywhere because there is always going to be something that would benefit from some love. Hell, I'd say the same is true for many libraries.
- goku12 9mo ago> It is a well-known and well-understood language. This isn't entirely true. There are a bunch of UBs that you have to be very careful about. C has the right idea about simplicity. But deterministic behavior is also important because someone will find a way to make use of UBs in their code.
- bluecalm 9mo agoWhat I like about C is that when they do add features they are just useful non-controversial features with maybe one exception of VLAs (that one was controversial). Designated initializers, compound literals, binary literals and the way to printf numbers in binary, constexpr, alignas, #embed, stdbit.h, memset_explicit, restrict to name the ones I really like.
- christophilus 9mo agoThis is one of the things I love about Clojure. It's a simple, elegant, stable language.
- somewhereoutth 9mo agoI've often said (at least half jokingly) - C for systems programming, Javascript for everything else! This artical makes the case for C as a low level language, I then offer Javascript as a functional-ish language for manipulating domain model data structures on the top.
- jimmytucson 9mo ago> Safe languages insert additional machine branches to do things like verify that array accesses are in-bounds. In correct code, those branches are never taken. That means that the machine code cannot be 100% branch tested, which is an important component of SQLite's quality strategy. Doesn't the language compiler write the code that checks if the array access is in-bounds? Why would you need to test the compiler's code?
- scottlamb 9mo agoThey talk about this here: https://sqlite.org/testing.html#statement_versus_branch_coverage https://sqlite.org/testing.html#statement_versus_branch_cove... ...saying that for a statement `if( a>b && c!=25 ){ d++; }`, they use 100% machine-code branch coverage as a way of determining that they've evaluated this in `a<=b`, `a>b && c==25`, and `a>b && c!=25`. (C/C++) branch coverage tools I've used are less strict, only requiring that takes both if and else paths. One could imagine a better high-level branch coverage tool that achieves this intent without dropping to the machine code level, but I'm not sure it exists today in Rust (or any other language for that matter). There might also be an element of "we don't even trust the compiler to be correct and/or ourselves to not have undefined behavior" here, although they also test explicitly for undefined behavior as mentioned later on the page.
- jimmytucson 9mo agoHmm, so in a language that does automatic bounds checking, the compiler might translate a line of source code like: let val = arr[i] to assembly code like: cmp rdx, rsi ; Compare i (rdx) with length (rsi) jae .Lpanic_label ; Jump if i >= length ; later... .Lpanic_label: call core::panicking::panic_bounds_check Are they saying with "correct code" the line of source code won't be covered? Because the assembly instruction to call panic isn't ever reached?
- scottlamb 9mo agoI think they're saying it's not covered: not only because `call` isn't ever reached but also because they identify `jae` as a branch and see it's always not taken. (If there were no lines in your `; later...` section and the branch were always taken, they'd still identify the `jae` as not covered.) It might be reasonable to redefine their metric as "100% branch coverage except for panics"...if you can reliably determine that `jae .Lpanic_label` is a panic jump. It's obvious to us reading your example of course but I don't know that the compiler guarantees panics always "look like that", and only panics look like that.
- mkl95 9mo agoC is like a classic car. It's cool and you might have fun with it, but if something goes wrong out there, there's a significant chance you'll end up in a very bad shape.
- alexpadula 9mo agoWhat! Classic cars are preferred. I'd trust an old muscle car more than a shiny new one ANY DAY OF THE WEEK. Ah gosh. New cars are trash. Never in my life had a good experience with a new car besides the smell. I've had many new cars and the car I drive today is a classic, I love it. Takes me everywhere, replace the parts and still goes. No rust. Can't say the same for a new car. I had a brand new truck a few years ago and I sold it. I had way too many problems. Doors being not aligned, electrical problems. Just shit all around. I had a Ford Focus ST as well for a for awhile too and I hated it. I couldn't even go in a car wash without it leaking through the roof, new car as well. Crazy!!!
- llmslave2 9mo agoSounds like it's an accurate analogy after all haha
- deleted 9mo ago[deleted]
- kensai 9mo agoC3 is bester?
- jonny_eh 9mo ago> So, for example, Android applications written in Java are able to invoke SQLite (through an adaptor). Maybe it would have been more convenient for Android if SQLite had been coded in Java as that would make the interface simpler. However, on iPhone applications are coded in Objective-C or Swift, neither of which have the ability to call libraries written in Java. Thus, SQLite would be unusable on iPhones had it been written in Java. This feels like they're responding to people asking for SQLite to be rewritten in Java. Who are these people?!
- UltraSane 9mo agoThe performance/memory security tradeoffs that C made made sense when computers were 100000 times slower and not connected to the internet but now when nearly all software is connected to the Internet it is a disaster.
- IshKebab 9mo ago> Safe languages insert additional machine branches to do things like verify that array accesses are in-bounds. In correct code, those branches are never taken. That means that the machine code cannot be 100% branch tested, which is an important component of SQLite's quality strategy. I don't think they thought about this too much. In the C code are they testing the "branch" into Undefined Behaviour?
- JosephusAMiller 9mo ago> Recoding SQLite in Go is unlikely since Go hates assert() I've heard it said you shouldn't use asserts in production code, but handle errors and exceptions instead? That said, can't you just 'if !condition() {panic...}' to simulate the behavior? Or are they talking about something specific about Golang?
- nu-world-odor 9mo ago[dead]
- throwaway81523 9mo ago1. This isn't a 2025 article, it's much older but it received some updates in 2025. 2. Ada is about as old as C so should have been considered as a possible safe language. It's safer than Rust in my opinion. GNAT was released in 1995 while SQLite is from 2000, so it was a possibility. C++ was also around: still unsafe, though less so than C.
- ongytenes 9mo agoI've started using SQLite years ago for its use of a single file to store data. Along the way, I found more reasons to like it. Today, I discovered a new reason when I read this article. I also noticed many software companies have been switching to SQLite for storing data. Audacity has switched from using hundreds of tiny audio files in multiple folders for a single recording to a single file using SQLite. I suspect it is the reliability that comes from sticking to C
- lasgawe 9mo agoC is the first language where I actually felt like I was programming. After using C and assembly for a few projects, every other language started to feel extremely slow. Even now, when programming with TS, my mind always goes to legacy features that offer better performance at the nanosecond level.