the example about C at Apple Computer is accurate. The MPW group had a tool suite but it was a niche project at the time (mid-80s). Influential engineers had a great pascal compiler and dropped into assembler for the fine points, quite a lot. The environment at DeAnza 3 where TechSupport lived was a place of change for Apple at that time. Within a few years, C was popular as an application language, some drivers for the new Mac II, and lots of community code was generated.
edit thinking about it, the resistance to C at the time was for real reasons.. common microcomputer C famously shipped with a minimal language but the I/O and string handling libs made the environment a useful runtime. Interfaces to anything more than that on a microcomputer were adhoc. But many professionals at that time knew about the larger *nix systems, and wanted the kinds of pipes and task management interfaces that they knew. This was the wrong model for the Mac OS, which emphasized graphical user interfaces at every step. There were no terminal windows in the background at all, no pipes and no standardized processes.
It was the courage to break away from "grown up" multi-user system, incremental engineering and make a completely mouse-driven interface that made the Mac great. Later when C interfaces to ROM Toolbox calls were built, they were used to support the Mac OS, not drag in tons of technical debt and character-stream kinds of ideas to this new computer.
For what is is worth, K&R and UCSD Pascal were contemporaneous, so it could have gone either way. As it happened, Bill Atkinson convinced Steve Jobs to support Pascal on the Apple ][. And the Apple ][ was the original development environment for the Lisa, which was the original development environment for the Macintosh.
Was it Pascal in general that was slow, or just USCD?
Was that the p-code system? Or was it a true compiler? Was it slow because it was p-code?
I wasn't on UCSD, but I don't recall Pascal being particularly slow compared to C. I never benchmarked them against each other, but it wasn't noticeably slower to my eyeball.
It was slow because the P-system was an interpreter, not native code. Java fixed that problem with the JIT. (Steve Russell created the first JIT for Java, and the result was spectacular.)
that's not entirely true, for example, Microsoft Word for the Mac (and PC) was p-code C, because p-code is a lot smaller. I think UCSD pascal was, yes, slow because of p-code, but also pascal is a very limited language compared to C. P-code with pointers is going to be a lot faster than p-code with no pointers.
the Apple compilers were good enough, with a lot of ASM.. the other comment is trying to change the subject to Sun things, which is like England vs France topic
In the DOS world, there were "near" and "far" pointers that would allow access to different memory segments. Even with this extra complexity, C did well.
I understand that Microsoft tried to get these into ANSI C, but they were forcefully kiboshed.
Around that time we had K&R c, which I liked because no really messing around with prototypes. Were Pascal, IIRC you had to deal with prototypes and variable types and other things.
Since then, we have ANCI c, which I got use to prototypes, but I still prefer K&R. At least for now, ANSI has yet to get anal about variable types and memory. I hope that never happens but I fear c is heading in that direction because of what the rust people are doing.
There are times when I work with old C code. Just the other day, I added proper C prototypes to a project, and immediately found several bugs with the code, like "this function is expecting a char **, the variable being passed in is char **, but it the address to the char ** is being passed" type bugs because the programmer wasn't able to keep all the details in their head.
The "Likeability" of C is very underestimated. Many people think that system code _should_ be written in other language, but people who _want_ to actually write, and maintain system software want to do so in C.
A programming language has to be enjoyed, if someone is going to dedicated a significant part of their lives o writing opensource software in it. C is on paper not a safe language, but almost all of the most trusted safety critical software is written in it, so from a Darwinistic point of view it has produced more trusted software. I strongly suspect that a big reason for this is that C is enjoyable enough for maintainers stick around long enough shake out all the issues.
Things have changed a lot since 2012. The Asahi Linux devs have said positive things about writing OS code in Rust. They have built a full M1 GPU driver in Rust which says a lot for the future of system code in safer languages.
Misra C is not normal likeable C. And while people have written safety critical code in normal likeable C, that isn't at all common. Ada, more recently spark, and various c++ subsets are all far more common. But yes Misra C is very common.
Zig seems likeable, but I haven't tried it yet. And rust is enjoyable now that I'm into it as my daily driver. The complexity is only there if I go looking. Mostly.
You stack allocate, you statically allocate. Anything growable either doesn’t grow, or preallocates (on the stack or statically) an upper limit and “grows” within that.
Often for dsp type stuff you'd blow out the stack for the size of a time series or image buffer. I typically preallocate when the size is known and reuse. Is yhere a good way to do that statically.
In Rust? Simplest thing is to declare an array as a static. Mutable statics do require unsafe, because it's inherently not threadsafe, but if you wanted to stay away from that directly, just depends on what kinds of tradeoffs you're interested in making.
I didn't realize who I was replying to! But yes in rust. I have messed with mutable statics with a mutex and maybeuinit mostly for exporting stuff as a cdylib that has mutable state, and found I lose some of what I love about rust. So I heap allocate once and do borrows for each stage in my pipeline (SDR stuff). Sometimes a stage copies to cuda device mem, or back, or doesn't and just carries a device pointer through behind an abstraction. Is there a good reason to avoid preallocation on the heap?
That's not always viable. Allowing heap allocation only at init is pretty common in embedded. Read config to get sizes, allocate at startup, never call free().
I don't understand what you mean by "That's not always viable." You can either call malloc, or you can't. If you can only call it at startup, only call it at startup. Every project has different requirements, and Rust will let you satisfy any of them.
I liked C perfectly well, and for over 25 years I wrote software in it, including both Free Software you may have used and in-house software I was directly employed to write for a large corporation. However I began learning Rust back in 2021 and not only do I now not want to write any more C, I want to rewrite my C software in Rust, although obviously 25 years worth of software means that's a whole lot of work and in a few cases I don't own the rights.
> but people who _want_ to actually write, and maintain system software want to do so in C.
At the time this article was written, you would probably be correct. But for about the past 5 or so years, there's been quite a few people in this space who have entertained the use of Rust instead. This includes people who write firmware, people who write drivers, even some of the people who work on the large operating system kernels themselves--you'll find examples of people who have indicated a desire to at least explore using Rust instead of C. And there's more languages in this space that have come out after Rust (Zig perhaps the most notable of those). While this view is far from universal, it's definitely the case that there's a large number of systems programmers who are interested in no longer writing in C.
> C is on paper not a safe language, but almost all of the most trusted safety critical software is written in it, so from a Darwinistic point of view it has produced more trusted software.
My understanding of things like MISRA C is that it's almost a completely different language--to turn C into something you can use for safety-critical stuff, you need to start ripping out or at least heavily curtail basically all of C's differentiating features.
Clearly that's a matter of taste. The popularity of rust shows that some people prefer writing it to writing C or C++, otherwise they'd just write C or C++. And yeah, personally I'd rather spend time fixing compile time errors, directly in the editor as I type, than hunting segfaults with gdb later.
Personally — and I know this isn't a good philosophy for secure software, I'm just commenting purely on the enjoyability aspect — I much prefer the logic game of hunting memory errors over the frustration of one of my tools refusing to do what I'm telling it to do.
(Like Brian Kernighan, I usually use judicious printf()s rather than gdb or lldb.)
I care to disagree. I'd much rather fight with my compiler than play the game of "oops, I segfaulted, let me recompile with -g so I can rerun with gdb so I can figure out where I crashed." Or more minor stuff, like trying to track down which header file actually contains the implementation of, say, struct mcontext_t so I can remember how to set the value of RSP in a signal handler.
I've grown to enjoy the Rust programming far more. Having a language, and associated tooling, that's woken up to the 21st century is far more enjoyable. (Really, why is it acceptable that a major language in 2023 still defaults to providing absolutely no diagnostic information on a fault?)
Fighting with the compiler just means you have the wrong frame of thinking. Once you learn how to express things in ways that are verifiably safe, there is no fighting because you’ll get it mostly correct the first time.
I agree, but I think you should then look at SPARK2014 [1]. Rust just has better marketing and a bigger company behind it, but SPARK2014 is simpler and has been delivering Rust's bullet list for almost 10 years.
I'm going to butt in with a counterpoint, since every time someone mentions "c" on the internet a bunch of Rust people come out of the woodwork and give this impression that Rust is taking over, everything is Rust now, everyone loves Rust, etc.
I've been a mobile OS developer for a decade now. Basically nobody uses Rust in the real world of firmware/kernel engineering. There are a few public examples of doing Rust in linux and Google, but the vast majority of work is still done in c or c-flavored c++.
Maybe it'll catch on some day, but it's definitely NOT catching on in the real world of making actual products.
Anyway you’re not wrong that Rust is still a tiny portion of this kind of thing, but it is growing, and quickly. Only time will tell.
(I work at a company writing firmware (and virtually everything else) in Rust, but as a startup I don’t expect that to carry as much weight as big established companies, of course.)
Man oh man. I realized I'd never even seen Rust code once in my life, so I loaded up some random Rust book and skimmed through it. I know HackerNews doesn't like half-informed angry opinions, so I'll just say "I really hope Rust never takes off" and leave it at that.
Your loss. I tried three times to learn Rust and I had plenty of doubts, but 3rd time I struck to it and it took maybe a year before I would reach for Rust before C (I have 40 years of C muscle memory so that's saying something). Some things _are_ awkward in Rust (eg. occasionally the explicit "a[x as usize]" casts are tiring), but the payoff is awesome.
ADD: what finally worked for me was to not read the book [linearly], but instead jumping between tons of sources, lots of exercises, and generally not stressing about getting everything in all the [ample] detail. And of course doing it and doing it every day. I definitely still have lots of holes (hello async) and I'm not shy about Cloning/Copying liberally unless it really matters for performance.
Especially on that area of Posrgresql mutants: similar ideas came to a lot of great minds: yugabyte, neondb, cockroach DB, timescaledb, even Amazon (Aurora) an MS here.
They are trying to do different things but common:
- they're all tweaking storage in very strange directions
- compatibility with core postgres - importance on top
(timescale is still an extension to PG)
- they all trying to achive a goal of cloud-native DB
And one thing is common: Rust!
(cocroachdb are still on golang but they are exception)
And if look what's going inside core postgres you will discover that almost all APIs of PG are duplicated in Rust so in future we'll see quite rusty PG
> And if look what's going inside core postgres you will discover that almost all APIs of PG are duplicated in Rust so in future we'll see quite rusty PG
Even right now rust is quite adopted in PG community.
Looking on trend I expect that in near future it will be even more:
- extensions - I expect rust to become first choice
- core postgresql - I expect that rust to appear first in pg tools and then in postgres itself
Agree with your points. There is a big difference between hype and actual change. That some hardcore fans want their favorite language to take over, is far different from their language being anywhere near to surpassing or replacing C or being at the top.
C is more than just another language, it's a quasi protocol that other languages communicate among each other with. Sorry to say, but neither Rust or Zig are likely to ever reach that level of popularity, nor are other languages going to create FFIs for them to that extent.
Another way to look at this. People run around saying Object Pascal/Pascal/Delphi is a "dead" language (despite how its still widely used), yet it stays around #15 on the TIOBE index, and has done so for years. Rust has barely reached #20 on that ranking site and various others. Zig is nowhere to be seen on various rankings and has yet to reach 1.0, though its going on 8 years into its development. These languages have yet to catch up to and surpass so-called "dead" Object Pascal/Pascal, much less have any shot at C, debatably in the next 10 years or ever.
Instead of just thinking about maybe only the USA or a favorite site that one might like, look at it from a wider and world perspective. You have entire school systems of various countries that use Delphi/Object Pascal. South Africa, Turkey, Jamaica, Russia, etc... To include Embarcadero is very aggressive in its outreach to schools and pushing its software and licenses, to the tune of many millions of copies (and many years). There are reasons why Embarcadero and Delphi are still very much around.
There are numerous dialects, IDEs, compilers, and interpreters of Object Pascal/Pascal all over the place (including for embedded and numerous platforms). Delphi (including Turbo Pascal nostalgia), Oxygene, Free Pascal/Lazarus/CodeTyphon, PascalABC, Pascal Script, DWScript, etc...
There are still tons of YouTube videos, books, and websites that are Delphi/Object Pascal/Pascal related. Millions upon millions of lines of code, that people still maintain, or are being produced by small businesses, independents, hobbyists, etc...
The sum total of it, plus the years that Pascal/Object Pascal has been around, means a much greater penetration and usage than many people realize, and much more than the recently trendy or fad languages people might be thinking of.
As much as people might have recently started talking about Rust or Zig on "hip" or "techie" sites, the languages are simply not that known or used to such an extent outside certain circles. Rust and Zig are not being taught like Pascal/Object Pascal was and still is in schools. They haven't been as widely written about or have as many books out about them. They aren't used as much, trusted, or relied upon. A lot more people than one might think, are on the fence, undecided, or only seldomly experimenting with them or something else. Even more, for a language to reach wide spread usage, takes more time and a lot more years than many are aware of or will admit it takes.
Lots of people are _entertaining_ Rust as an option, but that's very different from C being defecto. I don't know of a single peace of software I have used written in Rust.
A lot of people have in the past had very good arguments for why their language (C++, D Java, OCaml, Objective-C) should replace C but after decades they still haven't. The C-is-dead argument predates Rust by a lot, and Rust is already 10 years old.
C may at some point be replaced, but I'm not holding my breath especially given that I think Cs success is so poorly understood, especially by people who come from other languages.
Sure, Rust isn't there yet; C is still undisputably the king of system languages. But it's honestly the first language to crack the chink of C's dominance in low-level programming--C no longer looks unstoppable, in a way that C++ or D never managed to achieve.
It's like Chesterton's Fence. If you don't understand why C is used, you aren't going to be able to convince people that they ought to use something else. And you for certain are not going to be able to create a language to replace it.
> My understanding of things like MISRA C is that it's almost a completely different language
MISRA's rules aren't that distinct from a C coding style you've probably used if you're an experienced C programmer. Any competent C programmer can easily read and understand code that obeys the rules - it's just C, but maybe somebody with no prior experience of MISRA might trip on some of the rules because they're unnatural. For example if you like recursive code, MISRA hates that, so don't do that (call stacks are finite). If you're used to doing shenanigans with pointers (e.g. XOR linked list), MISRA hates that too, C's pointers are just magic, don't try to fiddle with them.
I'd guess that 90+% of code I wrote with no intention for it to be MISRA would, in fact, pass MISRA rules or would pass with some minor tweaks. Some of MISRA's dozens of rules are forbidding stuff no sane C programmer writes unless it's for a contest or something, so you just won't hit those. Some require practices which were recommended in like the ANSI document, that's over 30 years ago, hopefully you are doing that already.
My annecdata: my first language after BASIC was Pascal and I worked professionally for a couple of years using Turbo Pascal, yet I preferred C. I think the reasons were (in order): verbosity and flexibility.
I always hated Wirth's obsession with bloated keywords. I like conciseness (though J might be jumping the shark).
The latter point is just a reflection of how awkward it is to the break the rules in Pascal, which was necessary for many real-world applications.
And yes, I'm also a Rust convertee (sorry haters); I can do everything I did in C in Rust and for most parts it's more readable and frankly less work. I think my biggest regret is that while I know I could write a C compiler, I don't think I could write a Rust compiler [in my lifetime].
I love J and APL, but April takes the cake for me[1]. APL in Lisp.
I also prefer SPARK2014 instead of Rust if I am not going to use C. I've started learning Rust a few times. SPARK2014 is easier to get going for me, and it has been used to produce high-integrity software and real-world applications for over a decade, and more if you include Ada from which it sprang[2].
April is interesting, thanks. Aside: I worked professionally in Scheme for a few years, but Haskell (and ghci) is my favorite language (thus my handle) for experimenting with non-trivial derivations and quick one-off experiments. Rust gives me some of what I love in Haskell (type classes, polymorphic types, sum types, some type inference, rich and ergonomic library, some functional style, ...) without the sad part (space leaks, unpredictable runtime, completely insane defaults from a perf POV)
I find APL and J to be functional enough and terse to a point of beauty once you get it. Look at solutions on rosettacode.org between Haskell and J or APL to get a feel for what I am saying. Rust's syntax is a turn off, but that is a personal bias against my C background once I embraced Haskell, J, APL, Forth, Lisp, etc...
SPARK2014 covers me for the things Rust is striving for with a longer legacy of doing so for real world systems. It's also a simpler syntax (Ada, Pascal).
I like C quite a bit for systems programming because it's design is simple, minimalistic, and cohesive - especially given its age. It does not restrict how I design my software. I'm (usually) unsurprised when reviewing the generated assembly. I wish C "successors" would show more restraint. They _usually_ fail on at least one of these points. With that said, I am keeping my eye on Zig, Hare, C3, and a few others.
I very much agree. Rust has some good ideas but the more I've tried it and played with it it lacks that restraint you mentioned. Sooo many concepts, so many sub-languages for different parts. Don't get me wrong, I like the memory safety and that is an honorable goal, but I am not even sure I think ownership / uniqueness types are the best solution for that. There are so many other interesting solutions to memory safety that I think needs to be investigated and tried and I am getting a bit upset that Rust people seem so "our way is the only way"-sounding. But maybe that is just me, as I said I like some parts of the language.
Like you I am looking at Zig and a few others. A recent one I that really caught my eye was Austral (which uses linear types which is the more restrained cousin to Rusts ownership for example).
Does that exist? Is it only found in expensive, narrow verticals? Because general purpose free or retail software has been blowing up randomly for my entire career. At this point I believe conforming C can be generated, but I doubt a human being can write much at all.
The first "real programming language" I learned was Pascal. This was back in the 90s. Switching to C was like taking off a straight-jacket. I think it's hard to explain how much more freely you were able to code to someone who didn't go through the experience. Pascal was derogatorily referred to as a "Bondage and Discipline Language" by C programmers.
Of course I've matured a bit and I see a value in discipline and having the language get in the way of doing error prone things more now, but even so I'd still choose K&R 2nd edition ANSI C over late 80s and early 90s vintage Pascal if I had to pick one today.
From my perspective, there is a certain truth to this. I started out as an assembler programmer in the early 80s, just a kid messing about with the machines of the time (Z80, 6510 based). There was BASIC on various machines, but it was slow and clunky, and you just didn't get enough control or speed to do the things that a kid in the 80s wanted to do (write games!).
When I first came across C, it was around the time i'd been writing 68k for the first time, and intel assembler was very confusing, and already had a heap of different models to consider.
So, C allowed the majority of stuff to be written once, with calls to library functions written in assembler. All of a sudden, we went from 0% portability to 95% portability. C could be written like assembler, basic types which map directly to registers and memory locations, and so really it was a simple step to write not great C, with obvious benefits.
The first non-C language I came across was Fortran, closely followed by Modula-2, and neither of these were in any way as close to what i'd been writing in assembler, and so didn't connect in the same way.
I don't think i'm unusual in this regard, transitioning from assembler to C. Of course these days there is a new generation of programmers who haven't that experience, and are happier with higher level abstractions, and so it must look weird to them to see the fascination with C, and it probably has outlived it's expected life - i'm certainly surprised we're not all functional by now for example.
Despite enjoying the terseness of C, with curly braces and short notations, many "normalized" things in C used to trip up math students I would tutor in elementary programming classes. "Why is `=` assignment and not `==`? How can a function not produce a value? Why does `||` mean "or"?, etc.
Pascal family languages usually end up much more long winded, but can often be more easily explained to non-programmers than C solutions. I spent a couple years doing down the Ada rabbit hole in open source and was amazed how many elements of the problem domain you express directly with the language, and how you can constrain your program to catch domain-specific issues with the compiler.
With the rise of things like ChatGPT, I'm curious if the next revolution for programming languages is focusing on constraints to verify correctness rather than expression of what to do. This might help help an AI model develop code and provide validity checks on the generated solution.
I love C. As far as I can tell, there isn't anyone on the face of the planet trying to build anything like C in order to replace it. Rust isn't it. Rust is decidedly a "C++ replacement," if anything. Go is the closest in terms of philosophy, but Go isn't it either, because its standard implementation is garbage collected, among a number of other concerns.
There is almost certainly SOMEONE out there, a random nobody on GitHub or elsewhere actually trying to write something that is as close to C in terms of philosophy and execution but utilizes some modern niceties, but I don't know who they are.
If you want to replace C, though, you actually have to get in C's skin, and undulate and move like C does.
But here's the kicker: absolutely no major language seems to want to do this, so they're all dead on arrival.
No other language has the same ability to interop with other languages. No other language gets nearly as close to writing something that you can have an idea of what the underlying assembly looks like when you write it. No other language seems to care about the surrounding ecosystems C operates in or think about topics like ELF/Portable Executable/Mach-O.
Why? Because all of them operate in their own little bubble. No other language wants to expose those details to you. They want you to operate in the world of MyWorldLang. What's "name mangling?" What are "shared libraries?"
But you can't displace C if you don't care at all about POSIX or FFIs or assembly output or the host OS, and none of them do.
If you operate in the world of VegetableLang, they want you to work with "CarrotLib" and "Tomato constructs," and "VegThreads." And all of this other nonsense that has nothing to do with hardware. And then we end up with all of this garbage software and fewer and fewer opportunities for people to learn how to utilize their hardware, because guess what, there is no abstraction layer that will automagically help you get your records into cache lines. You HAVE to count those bytes yourself somewhere, sometime.
C is so powerful and long lasting because people who want to displace C and related languages aren't even in the same ballpark. They're on another planet. In another universe. Apparently working with a CPU or RAM to them is like asking how relevant it is for someone to be able to throw a golf ball into a basketball hoop from the three-pointer line in the fourth quarter of a football game.
Thank you for mentioning this! I wonder if Zig is the closest modern thing to C that we have? D seems to not want to fill the ANSI C role. Walter Bright seems to be a bright guy, but I want a programming language that follows the philosophies embodied and manifested in C. You can sort of get the idea that the guys behind Go roughly had this sort of Unix-esque philosophy mentality, but they never come out and explicitly say it[1][2], and so I think it wasn't an explicit goal for them.
> I want a programming language that follows the philosophies embodied and manifested in C
I don't really know what is missing on that front in DasBetterC. D can call any C code directly, D even has a built in assembler. D can import C code. And you can program free of the depredations of the C preprocessor.
When my dad was in the Air Force, the commander assigned Major Smart to be his office mate, for the sole purpose of putting "Bright & Smart" on the door. He figured nothing could go wrong in that department.
The problem is that alternatives to C can be built, it's a matter that its usage will become so widespread that it will be viewed and used as a replacement. Lots of people keep viewing C as just another language, versus it being a quasi protocol that other languages communicate through and defacto standard.
Zig is still in beta and has to reach 1.0, to even realistically enter such discussions (like you can with Rust), and it appears to be years away from achieving even that. C is at the top of the ladder, and Zig is around the bottom, trying to climb up. Zig is not even on many language rankings or at the bottom of them. It's not even anywhere near the top on just GitHub rankings, even when adjusted for year creation date.
The odds of making it to the top 5 languages used and widespread acceptance are very slim, no matter how much forced hype, zealotry, or evangelism.
> So I wanted templates from C++. And atomics from C++11. But that's about it. Other than that, I want to code like I'm in C. The beauty of C-style coding is that the control flow is so simple, it's impossible to not know what code is doing. Contrast that with fancy C++ stuff and you never know what's going to happen or what each line of code is going to do.
> I figured out how to have my cake and eat it too. I discovered that you can compile with g++ and link with gcc, like so:
> As long as you don't use anything from the C++ standard library, you end up with working code that was compiled with the C++ compiler and does not depend on libstdc++.
> With clang it's even easier, just don't put -lstdc++ on the linker line.
Very interesting! I meant though that you're not a "nobody." People know of Zig, but might be people like me who don't know a tremendous amount about Zig.
I'm being a little cheeky, but I'm pointing out that actually, in fact, I was exactly this nobody that you are talking about for a period of time, and I had a very similar inner thought process as you do in the parent comment :)
It's essentially D without the garbage collector or D runtime library. Just the C runtime library.
Das Better C has C syntax and semantics, but leaves behind the C preprocessor. It adds modules, metaprogramming and memory safety (has bounds checked arrays, for example). C compatibility is arranged with ImportC.
a few days ago somebody here poked fun at a guy on another (linked from here) forum, for jumping into a discussion of a project's decision to rewrite from C++ to Rust. What had the guy being criticized done to receive rebuke? Suggested they should stop and look at D! I admit I thought to myself, "uh oh, Walter's at it again, all over the internet now!" :)
> But you can't displace C if you don't care at all about POSIX or FFIs or assembly output or the host OS, and none of them do.
As someone who cares about FFIs, I really hate C in that it is just so limiting in its ability to express FFI. C can't support things like multiple return values, unwind, or vector types (and this is before we get to higher-level language concepts!), and since most languages don't attempt to support an FFI interface that isn't based on C, you're stuck not being able to support these in your own interface. And worse, that we're largely stuck with the POSIX interface to the OS, we're forced to use unholy abominations like errno or POSIX signals that really should have died thirty years ago.
Yeah, I think the issue with things like this is simply that developers don't like to promote. Clearly right here you can see I'm learning more about Zig, and about features of D I hadn't heard of before, and that's from guys who DO promote.
Exactly. All this "C killer" talk, is a bit too much, and in many cases way too premature. Better to have strong C interop, be a demonstrably useful alternative language for its users, then see how the dice rolls.
A "script" file is straight code, like a script. For a package, it is equivalent to `init()` functions for packages in Go. For a program, the main script file is the `main()`. A script file looks like this: https://git.yzena.com/Yzena/Yc/src/commit/c0ade4cc5b/build.r... .
Note: once the compiler/interpreter is at MVP, those two files will be working code. They will be the build scripts of the repo.
Speaking of the build scripts, the language has a way to allow users to define keywords. The build system already uses that to define its own keywords, turning Yao into a build system DSL.
(Yes, the first program written in Yao will be used to build Yao. It's a great test of the language.)
I think that should be enough links to get you started.
Pay particular attention to the example.y file w.r.t. C interoperability. The basic points are:
* Every function and type is associated with a C symbol, even if overloaded.
* Structs are laid out exactly like C. (There will be another compound type that won't have that guarantee, but it won't be default, and it, too, will have a C ABI.)
* It will have unions and enums like C.
* It will always use the C ABI, defining extensions to it for things like methods, and those definitions will be defined in the spec that every Yao compiler has to adhere to.
* It will always have the option to compile to C. C will be its bootstrap language.
That said, I still think there are many weaknesses in Yao compared to C. I don't have much confidence it will actually be a C killer, mostly because I'm not sure anymore that it is possible to add to C and kill it.
Yep. I learned Pascal in high school, but when I got my first Mac in college and needed to write apps for it, I fumbled with Symantec's Think Pascal for a while and ditched it for Think C in short order, even though I was still learning C at the time (and managed to completely corrupt my hard drive requiring a full reinstall because I used the low-level I/O APIs incorrectly).
You can do a lot in Pascal, and Delphi was an outstanding development environment for Windows app, but C is just so much more powerful.
this is a reasonable historical point buried in some nonsense:
>all sorts of people in the 1980s wanted a low level programming language, C was around, and so they seized on it. Any similar language would have done; it's just that C was lucky enough to be the one that came out on top, partly because of network effects.
any similar language would have done? there were no other similar languages for the low level programmers who wanted one, none, zero. So the "network effect" of C was that it had all the users in it because it was the only option.
There were some predecessors and pretenders to the throne--PL/I, BLISS, B, BCPL... pascal? forth? nah, c'mon--but they were not as good as C. C was small, and C had pointers that would increment by sizeof(type): indispensable.
The sudden need for a low level language for a lot of programmers at the same time was the birth of the microprocessor personal computer. These were new architctures, and there were no standard operating systems for them yet (there was competition for them, and the ones that emerged were bare bones) and programmers needed to write apps. Lotus 1-2-3 "won" by being written in assembly, there was still room for that choice.
Those other languages (mentioned above) existed on other architectures but not on these new microprocessors, and if you were going to start/port from scratch, you weren't going to reach for those, some were too big (PL/I), some were already archaic or tied to narrow architectures (BLISS was all DEC and DEC was very busy trying to pretend that microprocessors needed to be shoehorned into the minicomputer architecture), and none had any network effect to speak of in this adjacent community. If you were graduating with a CS degree at that time, you barely wanted to work on primitive microprocessors, they didn't have all the fancy CS features you were used to in school, the tech at that time had a much more (but by no means exclusive) self-taught and trade school by the seat of pants type engineering vibe.
C also had wonderfully unspecified behaviors to allow flexibility to the definition by the implementation on particular architectures (did your ISA detect 2s complement overflow? was your architecture 2's complement? if you need that, figure it out, if you don't, don't waste the cycles) and that was incredibly useful and incredibly efficient. (the people who went to the school-of-prissy-compiling who are throwing that all away now are polluting the world, spewing suffocating carbon dioxide more than a bitcoin miner using their optimizations. there's nothing wrong with what compiler writers want, they want features equally as cool are as cool as C's undefined behaviors (not really C's, the defined behaviors of various architectures), but you can implement these new features without stomping all over features that other people use)
104 comments
[ 2.0 ms ] story [ 188 ms ] threadedit thinking about it, the resistance to C at the time was for real reasons.. common microcomputer C famously shipped with a minimal language but the I/O and string handling libs made the environment a useful runtime. Interfaces to anything more than that on a microcomputer were adhoc. But many professionals at that time knew about the larger *nix systems, and wanted the kinds of pipes and task management interfaces that they knew. This was the wrong model for the Mac OS, which emphasized graphical user interfaces at every step. There were no terminal windows in the background at all, no pipes and no standardized processes.
It was the courage to break away from "grown up" multi-user system, incremental engineering and make a completely mouse-driven interface that made the Mac great. Later when C interfaces to ROM Toolbox calls were built, they were used to support the Mac OS, not drag in tons of technical debt and character-stream kinds of ideas to this new computer.
https://www.folklore.org/StoryView.py?story=Joining_Apple_Co...
Was that the p-code system? Or was it a true compiler? Was it slow because it was p-code?
I wasn't on UCSD, but I don't recall Pascal being particularly slow compared to C. I never benchmarked them against each other, but it wasn't noticeably slower to my eyeball.
I understand that Microsoft tried to get these into ANSI C, but they were forcefully kiboshed.
https://en.m.wikipedia.org/wiki/Far_pointer
Since then, we have ANCI c, which I got use to prototypes, but I still prefer K&R. At least for now, ANSI has yet to get anal about variable types and memory. I hope that never happens but I fear c is heading in that direction because of what the rust people are doing.
Many languages are trying to replace C++ and failing to do so.
https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2841.htm (90% sure but not 100% sure that’s the actual final link, if I’m wrong happy to be corrected!)
Rust is not mentioned as a justification.
A programming language has to be enjoyed, if someone is going to dedicated a significant part of their lives o writing opensource software in it. C is on paper not a safe language, but almost all of the most trusted safety critical software is written in it, so from a Darwinistic point of view it has produced more trusted software. I strongly suspect that a big reason for this is that C is enjoyable enough for maintainers stick around long enough shake out all the issues.
Zig seems likeable, but I haven't tried it yet. And rust is enjoyable now that I'm into it as my daily driver. The complexity is only there if I go looking. Mostly.
I would imagine banning the use of malloc would make C easier, not harder to code in.
You stack allocate, you statically allocate. Anything growable either doesn’t grow, or preallocates (on the stack or statically) an upper limit and “grows” within that.
Seems to have worked. But it would be a mess to use only stack and static memory for today's large applications.
And then you re-use your existing buffers.
At the time this article was written, you would probably be correct. But for about the past 5 or so years, there's been quite a few people in this space who have entertained the use of Rust instead. This includes people who write firmware, people who write drivers, even some of the people who work on the large operating system kernels themselves--you'll find examples of people who have indicated a desire to at least explore using Rust instead of C. And there's more languages in this space that have come out after Rust (Zig perhaps the most notable of those). While this view is far from universal, it's definitely the case that there's a large number of systems programmers who are interested in no longer writing in C.
> C is on paper not a safe language, but almost all of the most trusted safety critical software is written in it, so from a Darwinistic point of view it has produced more trusted software.
My understanding of things like MISRA C is that it's almost a completely different language--to turn C into something you can use for safety-critical stuff, you need to start ripping out or at least heavily curtail basically all of C's differentiating features.
Constantly fighting with your compiler is not how I would imagine a good time.
(Like Brian Kernighan, I usually use judicious printf()s rather than gdb or lldb.)
I've grown to enjoy the Rust programming far more. Having a language, and associated tooling, that's woken up to the 21st century is far more enjoyable. (Really, why is it acceptable that a major language in 2023 still defaults to providing absolutely no diagnostic information on a fault?)
[1] https://www.adacore.com/about-spark
I've been a mobile OS developer for a decade now. Basically nobody uses Rust in the real world of firmware/kernel engineering. There are a few public examples of doing Rust in linux and Google, but the vast majority of work is still done in c or c-flavored c++.
Maybe it'll catch on some day, but it's definitely NOT catching on in the real world of making actual products.
You know it’s kinda funny, I read this comment and then tabbed over to twitter and then read this: https://blogs.blackberry.com/en/2023/02/this-is-the-kind-of-...
Anyway you’re not wrong that Rust is still a tiny portion of this kind of thing, but it is growing, and quickly. Only time will tell.
(I work at a company writing firmware (and virtually everything else) in Rust, but as a startup I don’t expect that to carry as much weight as big established companies, of course.)
Especially on that area of Posrgresql mutants: similar ideas came to a lot of great minds: yugabyte, neondb, cockroach DB, timescaledb, even Amazon (Aurora) an MS here.
They are trying to do different things but common: - they're all tweaking storage in very strange directions - compatibility with core postgres - importance on top (timescale is still an extension to PG) - they all trying to achive a goal of cloud-native DB
And one thing is common: Rust! (cocroachdb are still on golang but they are exception)
And if look what's going inside core postgres you will discover that almost all APIs of PG are duplicated in Rust so in future we'll see quite rusty PG
What do you mean by this?
Looking on trend I expect that in near future it will be even more: - extensions - I expect rust to become first choice - core postgresql - I expect that rust to appear first in pg tools and then in postgres itself
C is more than just another language, it's a quasi protocol that other languages communicate among each other with. Sorry to say, but neither Rust or Zig are likely to ever reach that level of popularity, nor are other languages going to create FFIs for them to that extent.
Another way to look at this. People run around saying Object Pascal/Pascal/Delphi is a "dead" language (despite how its still widely used), yet it stays around #15 on the TIOBE index, and has done so for years. Rust has barely reached #20 on that ranking site and various others. Zig is nowhere to be seen on various rankings and has yet to reach 1.0, though its going on 8 years into its development. These languages have yet to catch up to and surpass so-called "dead" Object Pascal/Pascal, much less have any shot at C, debatably in the next 10 years or ever.
not a snowman's chance that "Object Pascal/Pascal/Delphi" is, by ANY measure, in top 15 programming languages by usage or importance in 2023...
There are numerous dialects, IDEs, compilers, and interpreters of Object Pascal/Pascal all over the place (including for embedded and numerous platforms). Delphi (including Turbo Pascal nostalgia), Oxygene, Free Pascal/Lazarus/CodeTyphon, PascalABC, Pascal Script, DWScript, etc...
There are still tons of YouTube videos, books, and websites that are Delphi/Object Pascal/Pascal related. Millions upon millions of lines of code, that people still maintain, or are being produced by small businesses, independents, hobbyists, etc...
The sum total of it, plus the years that Pascal/Object Pascal has been around, means a much greater penetration and usage than many people realize, and much more than the recently trendy or fad languages people might be thinking of.
As much as people might have recently started talking about Rust or Zig on "hip" or "techie" sites, the languages are simply not that known or used to such an extent outside certain circles. Rust and Zig are not being taught like Pascal/Object Pascal was and still is in schools. They haven't been as widely written about or have as many books out about them. They aren't used as much, trusted, or relied upon. A lot more people than one might think, are on the fence, undecided, or only seldomly experimenting with them or something else. Even more, for a language to reach wide spread usage, takes more time and a lot more years than many are aware of or will admit it takes.
A lot of people have in the past had very good arguments for why their language (C++, D Java, OCaml, Objective-C) should replace C but after decades they still haven't. The C-is-dead argument predates Rust by a lot, and Rust is already 10 years old.
C may at some point be replaced, but I'm not holding my breath especially given that I think Cs success is so poorly understood, especially by people who come from other languages.
If yes, you are using software written in Rust.
Fastly? Same. Python? there is a good chance you are using cryptography, which is partially in Rust.
Firefox? Rust is in there.
And i could keep doing, at this point it is slowly creeping everywhere :)
MISRA's rules aren't that distinct from a C coding style you've probably used if you're an experienced C programmer. Any competent C programmer can easily read and understand code that obeys the rules - it's just C, but maybe somebody with no prior experience of MISRA might trip on some of the rules because they're unnatural. For example if you like recursive code, MISRA hates that, so don't do that (call stacks are finite). If you're used to doing shenanigans with pointers (e.g. XOR linked list), MISRA hates that too, C's pointers are just magic, don't try to fiddle with them.
I'd guess that 90+% of code I wrote with no intention for it to be MISRA would, in fact, pass MISRA rules or would pass with some minor tweaks. Some of MISRA's dozens of rules are forbidding stuff no sane C programmer writes unless it's for a contest or something, so you just won't hit those. Some require practices which were recommended in like the ANSI document, that's over 30 years ago, hopefully you are doing that already.
I always hated Wirth's obsession with bloated keywords. I like conciseness (though J might be jumping the shark).
The latter point is just a reflection of how awkward it is to the break the rules in Pascal, which was necessary for many real-world applications.
And yes, I'm also a Rust convertee (sorry haters); I can do everything I did in C in Rust and for most parts it's more readable and frankly less work. I think my biggest regret is that while I know I could write a C compiler, I don't think I could write a Rust compiler [in my lifetime].
I also prefer SPARK2014 instead of Rust if I am not going to use C. I've started learning Rust a few times. SPARK2014 is easier to get going for me, and it has been used to produce high-integrity software and real-world applications for over a decade, and more if you include Ada from which it sprang[2].
[1] https://github.com/phantomics/april
[2] https://www.adacore.com/about-spark
SPARK2014 covers me for the things Rust is striving for with a longer legacy of doing so for real world systems. It's also a simpler syntax (Ada, Pascal).
I like C quite a bit for systems programming because it's design is simple, minimalistic, and cohesive - especially given its age. It does not restrict how I design my software. I'm (usually) unsurprised when reviewing the generated assembly. I wish C "successors" would show more restraint. They _usually_ fail on at least one of these points. With that said, I am keeping my eye on Zig, Hare, C3, and a few others.
Like you I am looking at Zig and a few others. A recent one I that really caught my eye was Austral (which uses linear types which is the more restrained cousin to Rusts ownership for example).
Does that exist? Is it only found in expensive, narrow verticals? Because general purpose free or retail software has been blowing up randomly for my entire career. At this point I believe conforming C can be generated, but I doubt a human being can write much at all.
Of course I've matured a bit and I see a value in discipline and having the language get in the way of doing error prone things more now, but even so I'd still choose K&R 2nd edition ANSI C over late 80s and early 90s vintage Pascal if I had to pick one today.
When I first came across C, it was around the time i'd been writing 68k for the first time, and intel assembler was very confusing, and already had a heap of different models to consider.
So, C allowed the majority of stuff to be written once, with calls to library functions written in assembler. All of a sudden, we went from 0% portability to 95% portability. C could be written like assembler, basic types which map directly to registers and memory locations, and so really it was a simple step to write not great C, with obvious benefits.
The first non-C language I came across was Fortran, closely followed by Modula-2, and neither of these were in any way as close to what i'd been writing in assembler, and so didn't connect in the same way.
I don't think i'm unusual in this regard, transitioning from assembler to C. Of course these days there is a new generation of programmers who haven't that experience, and are happier with higher level abstractions, and so it must look weird to them to see the fascination with C, and it probably has outlived it's expected life - i'm certainly surprised we're not all functional by now for example.
Pascal family languages usually end up much more long winded, but can often be more easily explained to non-programmers than C solutions. I spent a couple years doing down the Ada rabbit hole in open source and was amazed how many elements of the problem domain you express directly with the language, and how you can constrain your program to catch domain-specific issues with the compiler.
With the rise of things like ChatGPT, I'm curious if the next revolution for programming languages is focusing on constraints to verify correctness rather than expression of what to do. This might help help an AI model develop code and provide validity checks on the generated solution.
Of course: curly braces and BEGIN-END and 'for' is much more elegant but conceptually they are the same.
Borland it demonstrated with CBuilder and Delphi.
Sometimes I wrote program in both of them.
There is almost certainly SOMEONE out there, a random nobody on GitHub or elsewhere actually trying to write something that is as close to C in terms of philosophy and execution but utilizes some modern niceties, but I don't know who they are.
If you want to replace C, though, you actually have to get in C's skin, and undulate and move like C does.
But here's the kicker: absolutely no major language seems to want to do this, so they're all dead on arrival.
No other language has the same ability to interop with other languages. No other language gets nearly as close to writing something that you can have an idea of what the underlying assembly looks like when you write it. No other language seems to care about the surrounding ecosystems C operates in or think about topics like ELF/Portable Executable/Mach-O.
Why? Because all of them operate in their own little bubble. No other language wants to expose those details to you. They want you to operate in the world of MyWorldLang. What's "name mangling?" What are "shared libraries?"
But you can't displace C if you don't care at all about POSIX or FFIs or assembly output or the host OS, and none of them do.
If you operate in the world of VegetableLang, they want you to work with "CarrotLib" and "Tomato constructs," and "VegThreads." And all of this other nonsense that has nothing to do with hardware. And then we end up with all of this garbage software and fewer and fewer opportunities for people to learn how to utilize their hardware, because guess what, there is no abstraction layer that will automagically help you get your records into cache lines. You HAVE to count those bytes yourself somewhere, sometime.
C is so powerful and long lasting because people who want to displace C and related languages aren't even in the same ballpark. They're on another planet. In another universe. Apparently working with a CPU or RAM to them is like asking how relevant it is for someone to be able to throw a golf ball into a basketball hoop from the three-pointer line in the fourth quarter of a football game.
To the best of my knowledge this is what Zig is trying to do.
https://ziglang.org/
[1]: https://go.dev/blog/5years
[2]: https://commandcenter.blogspot.com/2012/06/less-is-exponenti...
Edit: Hahaha, I didn't catch myself with the "bright" thing.
[1] https://dlang.org/spec/betterc.html
I had to change my born name from Walter Dummkopf.
I don't really know what is missing on that front in DasBetterC. D can call any C code directly, D even has a built in assembler. D can import C code. And you can program free of the depredations of the C preprocessor.
When my dad was in the Air Force, the commander assigned Major Smart to be his office mate, for the sole purpose of putting "Bright & Smart" on the door. He figured nothing could go wrong in that department.
Zig is still in beta and has to reach 1.0, to even realistically enter such discussions (like you can with Rust), and it appears to be years away from achieving even that. C is at the top of the ladder, and Zig is around the bottom, trying to climb up. Zig is not even on many language rankings or at the bottom of them. It's not even anywhere near the top on just GitHub rankings, even when adjusted for year creation date.
The odds of making it to the top 5 languages used and widespread acceptance are very slim, no matter how much forced hype, zealotry, or evangelism.
But you're not the "nobody on GitHub" person I'm describing so I guess we need more people talking about and promoting Zig.
I suppose these things just take time.
In particular:
> So I wanted templates from C++. And atomics from C++11. But that's about it. Other than that, I want to code like I'm in C. The beauty of C-style coding is that the control flow is so simple, it's impossible to not know what code is doing. Contrast that with fancy C++ stuff and you never know what's going to happen or what each line of code is going to do.
> I figured out how to have my cake and eat it too. I discovered that you can compile with g++ and link with gcc, like so:
> As long as you don't use anything from the C++ standard library, you end up with working code that was compiled with the C++ compiler and does not depend on libstdc++.> With clang it's even easier, just don't put -lstdc++ on the linker line.
Das Better C: https://dlang.org/spec/betterc.html
It's essentially D without the garbage collector or D runtime library. Just the C runtime library.
Das Better C has C syntax and semantics, but leaves behind the C preprocessor. It adds modules, metaprogramming and memory safety (has bounds checked arrays, for example). C compatibility is arranged with ImportC.
Book by Alexandrescu was like a fantasy novel for young programmers in company where I worked.
One of us discovered this book and tell others. A bit later everybody was "infected".
Mostly javers and dotnetters and it was constant "Wow! It's possible to do such way? Why we don't do that?"
So, you influenced a lot of my friends in a right way.
Thank you!
As someone who cares about FFIs, I really hate C in that it is just so limiting in its ability to express FFI. C can't support things like multiple return values, unwind, or vector types (and this is before we get to higher-level language concepts!), and since most languages don't attempt to support an FFI interface that isn't based on C, you're stuck not being able to support these in your own interface. And worse, that we're largely stuck with the POSIX interface to the OS, we're forced to use unholy abominations like errno or POSIX signals that really should have died thirty years ago.
They're just not very popular.
(And well, I would like to add.)
Yeah because it would be a bad idea.
I think Zig is the best at pretending to operate with C, but it's still pretend. You need to do special stuff to interoperate with C.
Disclaimer: I'm biased because I'm trying make a C killer even better than Zig is.
It's called Yao. The main repo is https://git.yzena.com/Yzena/Yc , which is a monorepo that has other stuff as well.
Yao defines two types of files.
A "package" file defines stuff that a package can export. A package file looks like this: https://git.yzena.com/Yzena/Yc/src/commit/c0ade4cc5b/build.p... .
A "script" file is straight code, like a script. For a package, it is equivalent to `init()` functions for packages in Go. For a program, the main script file is the `main()`. A script file looks like this: https://git.yzena.com/Yzena/Yc/src/commit/c0ade4cc5b/build.r... .
Note: once the compiler/interpreter is at MVP, those two files will be working code. They will be the build scripts of the repo.
Speaking of the build scripts, the language has a way to allow users to define keywords. The build system already uses that to define its own keywords, turning Yao into a build system DSL.
(Yes, the first program written in Yao will be used to build Yao. It's a great test of the language.)
An example file, with explanation comments, is at https://git.yzena.com/Yzena/Yc/src/commit/c0ade4cc5b/src/yao... . All of the docs are at https://git.yzena.com/Yzena/Yc/src/commit/c0ade4cc5b/docs/ya... , but they are mostly design docs.
I think that should be enough links to get you started.
Pay particular attention to the example.y file w.r.t. C interoperability. The basic points are:
* Every function and type is associated with a C symbol, even if overloaded.
* Structs are laid out exactly like C. (There will be another compound type that won't have that guarantee, but it won't be default, and it, too, will have a C ABI.)
* It will have unions and enums like C.
* It will always use the C ABI, defining extensions to it for things like methods, and those definitions will be defined in the spec that every Yao compiler has to adhere to.
* It will always have the option to compile to C. C will be its bootstrap language.
That said, I still think there are many weaknesses in Yao compared to C. I don't have much confidence it will actually be a C killer, mostly because I'm not sure anymore that it is possible to add to C and kill it.
You can do a lot in Pascal, and Delphi was an outstanding development environment for Windows app, but C is just so much more powerful.
But my first work was in Delphi. I've grown a lot as a programmer exploring VCL, professional tools but I still thought that C and C++ are superior.
My second work was in C. I was happy.
But then .. I started to see that not everything so beatyful.
It was like meeting with a girl you had a crush as teenager but now .. she's just normal
>all sorts of people in the 1980s wanted a low level programming language, C was around, and so they seized on it. Any similar language would have done; it's just that C was lucky enough to be the one that came out on top, partly because of network effects.
any similar language would have done? there were no other similar languages for the low level programmers who wanted one, none, zero. So the "network effect" of C was that it had all the users in it because it was the only option.
There were some predecessors and pretenders to the throne--PL/I, BLISS, B, BCPL... pascal? forth? nah, c'mon--but they were not as good as C. C was small, and C had pointers that would increment by sizeof(type): indispensable.
The sudden need for a low level language for a lot of programmers at the same time was the birth of the microprocessor personal computer. These were new architctures, and there were no standard operating systems for them yet (there was competition for them, and the ones that emerged were bare bones) and programmers needed to write apps. Lotus 1-2-3 "won" by being written in assembly, there was still room for that choice.
Those other languages (mentioned above) existed on other architectures but not on these new microprocessors, and if you were going to start/port from scratch, you weren't going to reach for those, some were too big (PL/I), some were already archaic or tied to narrow architectures (BLISS was all DEC and DEC was very busy trying to pretend that microprocessors needed to be shoehorned into the minicomputer architecture), and none had any network effect to speak of in this adjacent community. If you were graduating with a CS degree at that time, you barely wanted to work on primitive microprocessors, they didn't have all the fancy CS features you were used to in school, the tech at that time had a much more (but by no means exclusive) self-taught and trade school by the seat of pants type engineering vibe.
C also had wonderfully unspecified behaviors to allow flexibility to the definition by the implementation on particular architectures (did your ISA detect 2s complement overflow? was your architecture 2's complement? if you need that, figure it out, if you don't, don't waste the cycles) and that was incredibly useful and incredibly efficient. (the people who went to the school-of-prissy-compiling who are throwing that all away now are polluting the world, spewing suffocating carbon dioxide more than a bitcoin miner using their optimizations. there's nothing wrong with what compiler writers want, they want features equally as cool are as cool as C's undefined behaviors (not really C's, the defined behaviors of various architectures), but you can implement these new features without stomping all over features that other people use)