4 ms·
> Safe programming languages solve the easy problems: memory leaks, use-after-free errors, array overruns, etc. Safe languages provide no help beyond ordinary C
by geofft 5y ago
> Safe programming languages solve the easy problems: memory leaks, use-after-free errors, array overruns, etc. Safe languages provide no help beyond ordinary C code in solving the rather more difficult problem of computing a correct answer to an SQL statement.
I see where the author is coming from, but I don't think this is quite true. The way that safe programming languages work is that they have a richer type system that knows about the semantic context of variables, which in turn is a tool that helps a lot with the "more difficult problems".
For instance, one of the tools Rust uses for enforcing memory safety (data races and use-after-free, in particular) is that there's a distinction between "mutable" and "constant" references. But this is, really, a distinction between unique and shared references. If I am statically guaranteed the only holder of a reference to X, I can modify it; if some other part of the code might have a reference to X, I cannot.
This is essentially a readers/writer lock enforced at compiled time, and it therefore is a pattern that makes it much easier to use actual readers/writer locks: the lock-for-read function gets you a shared reference and the lock-for-write function gets you an immutable one. And Rust makes it easy to say, you cannot unlock the lock (in either variant) until you return the reference, and you cannot accidentally leak the reference out of the scope of the lock.
If you're using a readers-writer lock on, say, the schema of a table (many simultaneous readers can use a table, but only one task can alter the table and nothing else can touch the table while it's being altered), having the tools to meaningfully distinguish the cases and enforce that your mutable references don't get copied does actually make it easier to compute the correct answer to a SQL statement that's running at roughly the same time as an ALTER TABLE.
Another of the tools Rust uses is tagged unions: a C construct like union U {char x; int y;} would be memory-unsafe, so Rust is obligated to forbid it in safe code. Instead, you get an enum type that C would describe something like struct U {int tag; union {char x; int y;};}. If tag == 0, then you're on the first variant; if tag == 1, then you're on the second variant, and the compiler ensures that (in safe code) tag is never equal to anything else, never uninitialized, etc. And there are a bunch of language constructs to assist with this - for instance, the 'match' keyword lets you write cases for each variant, allowing access to x only if tag == 0 and y only if tag == 1. You're not allowed to access x or y directly at all outside of a match keyword or equivalent (like 'if let'), because that would defeat memory safety.
But because you've got good syntax and compiler-checked support for handling tagged unions, you may as well use it for problems even if you don't care about memory safety / security. Take this union from the SQLite source code, for instance: https://www.sqlite.org/cgi/src/file?ci=trunk&name=src/sqliteInt.h&ln=2234 https://www.sqlite.org/cgi/src/file?ci=trunk&name=src/sqlite...
There are three types of tables (eTabType), normal, virtual, or view. There are three union variants with different data. Even ignoring the fact that some of the variables are pointers and others are non-pointers, the data doesn't make semantic sense when interpreted as the wrong variant. If you have code that handles just a normal table, and you extend it to handle virtual tables or views too, you will need to make sure you're not unconditionally accessing addColOffset, pFKey, or pDfltList, because the information you get will be wrong. Rust's enforcement of memory safety means it also prevents you from making this logical mistake.
I think we've been selling memory-safe languages as a tool for security, and I don't mean to detract from that argument at all - but there's also the fact that Rust and Go (and D and Vala and even modern C++) are newer languages that have been able to implement more things than C can, which in turn makes it easier to write correct programs in general.
- pjmlp 5y agoWe already had languages like that 10 years before C was invented. https://en.m.wikipedia.org/wiki/Burroughs_large_systems https://en.m.wikipedia.org/wiki/Burroughs_large_systems https://en.m.wikipedia.org/wiki/JOVIAL https://en.m.wikipedia.org/wiki/JOVIAL There are plenty of other examples when one looks for what was happening outside AT&T. C apologists like to pretend C is some kind of special gift to mankind in systems programming languages, and nothing was happening before C and UNIX came into scene.
- jstimpfle 5y agoAll it would take a "C apologist" to explain why they don't want to use JOVIAL for example is that it is cumbersome to type programs in uppercase. The only one I've ever seen talking of a "special gift" was you; most C programmers I know are very honest about the fact that C sucks in some ways. The typical experience is just that it sucks less than many others. What I appreciate most is that it gets out of my way. I don't want to be fighting a language, I want to concentrate on the problem I'm trying to solve.
- pjmlp 5y agoTime to broaden your horizons, I have met plenty of C advocates and UNIX books that tell the story before C there was only Assembly as system programming language. If they actually acknowledged C sucks, lint would have been long adopted instead of being ignored since 1979 until clang tidy was born, and something like bds for strings and vectors would have been long part of the standard library.
- Nicksil 5y ago>Time to broaden your horizons, I have met plenty of C advocates and UNIX books that tell the story before C there was only Assembly as system programming language. Without plenty of examples, one can only assume what you've experienced is outlier. I can't imagine any significant number of experienced software developers think that. Hell, other systems languages born before C are still being discussed today; go back in time and it only becomes more prominent. Unless a developer has been significantly sheltered, your assertion just isn't reasonable.