From the 1st paragraph, that's what I thought they were going to talk about:
totally contradicts real reasons why C is designed the way it is. Even back then, there were better languages/OS's [1] that cheap hardware just hadn't caught up to. That cheap hardware's limitations, and them alone, drove the design decisions of BCPL, B, and then C.
But you're right, they're mostly talking about the compilers.
So anyone who could come up with a high(er) level language that would run on smaller machines was a winner.
I think that's what the Objective-C folks were thinking. I guess the author would lament that they chose C as the other partner.
Only C has survived into the modern era
Forth was around in those days. So was Smalltalk and Lisp. So maybe, "survived as more than a niche language?" (Forth and Smalltalk are really from the 70's. You could argue that only Lisp is from "those days.")
Smalltalk's machines weren't all that large by today's standards, memory was 128kB, expandable to 512kB per Wikipedia, but expansions were addressable only by bank switching. 128kB is the same memory budget as the Unix PDP-11/45's for a single process.
For them, that was some amazing hardware to work with. A lot of new ideas were tested out on the 704.
I grew up with microcomputers. My first machine had 16K, which I think is about what a 704 had. There's a lot you can do with 16K. Altair BASIC ran on 4K machines. Even modern micropython, meant for microcontollers, works in 64K, and that language wasn't designed to be space efficient.
Oh, and from http://edn.embarcadero.com/article/20693 :
> Turbo Pascal version 1.0 shipped on one floppy disk. The total number of files on the disk was 10. Total floppy disk space used was 131,297 bytes. Total size of TURBO.COM (including the integrated development environment with compiler, Wordstar-style editor, and run-in-memory system) was 33,280 bytes.
You're putting a lot of weight into words I wrote casually. The intended meaning was that I hadn't investigated what a good, useful-today implementation of LISP could do in what would be a highly-constrained system today. Particularly, on cheap microcontrollers used in embedded systems. I have seen LISP's like femtolisp that use around 1K for implementation with good performance. So, original LISP being able to run on a 704 implied quite a lot to me.
On other hand, BASIC and Pascal are low-level, static 3GL's. They're easy to compile efficiently into efficient code even without much optimization. I pulled it off for BASIC without knowing much about compilers. I'm sure it took talent to get the mix of functionality and efficiency in stuff like TurboPascal or some of the Altair apps. It's not telling me much about how a dynamic LISP will work on those platforms, though, given its execution style is so different. Especially if I code in a way that doesn't penalize readability or maintenance for efficiency.
Fortunately, there's a pile of papers I can go through if I want to determine an optimal way to do that. Many of which are from 70's-80's. The 704 result just tells me embedded impact could happen if I kept it efficient. Micropython work is also impressive. I hope the point of my reply is more clear now.
https://news.ycombinator.com/item?id=10210931
Quite selective. The obvious counterpoint, which next version of essay will utilize, would be Wirth and Jurg's work in Lilith system. Two pro's + 8 part-timers, two years, plenty constraints, and whole system from HW to OS to apps to do with Pascal philosophy (balancing safety/speed/maintenance). To keep apples to apples, let's focus on language design the main two went with: the Modula-2 language. It's very simple, compiles faster than C due to cleaner grammar, is safe-by-default in a few ways, lets you turn that off where necessary, modular, supported concurrency, and runs fast. This approach got repeatedly iterated into progressively safer and faster systems by amateurs & pro's alike, sometimes just 1-2 students, that crashed less than C apps. Best part relevant to your comment: they built first Modula-2 compiler on a PDP-11. :P
Most of C's advantages, a few more on top of it, fewer problems, and developed on same architecture. Sounds like a clear winner from design standpoint. If you want simpler & faster, the Edison system is a good, extreme example of how ALGOL practitioner might do a C-like project. Too simple vs Modula-2 imho but beats C at its own game of fast minimalism with some Wirth-style benefits. Whole system, with source, got published in one paper.
http://modula-2.info/m2info/pmwiki.php/General/FAQ
I note that Borland brought out a Turbo Pascal to go with Turbo C (fixing some of Pascal's shortcomings in the process), but never bothered with a Turbo Modula-2. If Modula-2 was better than Pascal, why not? (And, since the initial article seemed to be a fan of Algol, why didn't Borland do a Turbo Algol?) Microsoft had their Microsoft C that competed with Borland, but didn't bother to do a Microsoft Pascal. Why not? Because nobody cared about Modula-2, and not enough people cared about Pascal. And why was that? Because in practice, it was easier to write software in C than in Modula-2, or even than in Pascal.
You're idealizing dead languages. They're dead for a reason, and it's not just historical accident. In the real world, they were harder to use than the languages that theory said should be the best.
The point was a research prototype they could use with safety and consistency down to CPU with hopefully benefits for teaching students. It succeeded at all that. The Ceres workstations that followed ran ETH university for a while. Quite useful. The students easily learned, modified, ported, etc the Oberon OS's. The hyperlink-driven GUI, mocked in that time, is also similar to the default method of obtaining information today that you're using to read this.
"but never bothered with a Turbo Modula-2. If Modula-2 was better than Pascal, why not?"
What does a company's marketing strategy tell us about the technical merits of a programming language? I don't know. It could be anything up to and including there were more C and Pascal users so they built C and Pascal compilers. Was my guess.
"And, since the initial article seemed to be a fan of Algol, why didn't Borland do a Turbo Algol?"
I'm fixing that part in next revision. It's coming across to some readers, including you, that I'm pushing for ALGOL itself to be built by 2 people on a PDP-11. That's... probably impossible. It's instead showing C did not have to be built, others did better with ALGOL subsets, most dominant (and productive) languages today have more capabilities in common with ALGOL than BCPL, and therefore that's the approach programmers should aim for instead of C's non-design. The constraints behind BCPL stopped being justified before PDP-11 existed. They definitely aren't now given all the alternatives.
" Because in practice, it was easier to write software in C than in Modula-2, or even than in Pascal."
This could be true for older versions. The question would be whether getting an app working... from prototyping to compiling to debugging to integration... is easier in C than in Wirth languages. I seriously doubt that just reading C programmers' own writings and bug reports. The minimal, extra amount of work is some typing you do that takes minutes but can save hours. They parse & generate faster but type-check more. So, compiler speed probably depends on implementation.
Hard for me to evaluate this one given students all over learn a language like Oberon easily while they struggle with C. Pros struggle to make C correct. How can C be less work?
"They're dead for a reason, and it's not just historical accident."
If that's true, then COBOL is still alive and well processing much of the world's critical transactions on its most reliable systems for a reason that's not historical accident and has everything to do with superiority of COBOL's design. Possibly why non-UNIX OS's dominate desktops, too. If popularity implies better design or usability, then perhaps people that believe that should buy Microfocus COBOL for Windows for their next app to test the theory. Whereas, an ALGOL subset & variant like Modula's, Oberon's or recently Go is probably way easier to work with due to design decisions per my theory. More effective in other metrics outside raw performance, too. Take your pick.
Note: You should also consider psychological and financial factors in the uptake of IT solutions. It might surprise you to find out that many popular things weren't necessarily the most effective solution. Or even most cost-effective.
Exactly. I think once you drop down into assembler it becomes very apparent what C's goal was - to standardize assembly language and make cross CPU coding easier.
If you code in assembly, you eventually need to begin writing your own routines for copying, appending strings/memory, etc. It begins to look suspiciously like the stdlib as it evolves. And consequently, your code begins to look like C with assembly mixed in for the control logic.
The big difference is your source only works on your target CPU. Drat.
That's not in the docs I cited from the inventors. The original goal was ALGOL's benefits. Too hard on an EDSAC. So, chop off anything until you have fastest, most minimal language for an EDSAC. Thompson preferred BCPL over anything else at the time & wanted to do an OS in it on a PDP-7/11. Ritchie too. Mods needed to do that became the earliest C.
Portability across CPU's is never mentioned. UNIX and C were specifically designed for those hardware with holdovers in there to this day. A portable, assembly language from back then that was successful was P-code. It hid CPU/architecture differences, stayed efficient, and was backend of the compiler. Later, they wrote OS's in a mix of HLL's and P-code variant. Exactly the kind of thing you do if designing for portability.
C was ported because it barely had any features. These ports often had to be kludgingly forced into the machines. Quite different.
"If you code in assembly, you eventually need to begin writing your own routines for copying, appending strings/memory, etc. It begins to look suspiciously like the stdlib as it evolves. And consequently, your code begins to look like C with assembly mixed in for the control logic."
You might evolve a stdlib. What it looks like, how safe it is, how efficient it is, and whether it's auto-customized per CPU via macros, etc are totally different depending on your foundation. Most of Oberon System's OS is done like you would ordinary programs with function calls, type-checked arguments, and even garbage collection in later ones. The LISP machines were incredibly different with one able to use macros for API's or bottom layers. The Smalltalk approach was more high-level than most 3GL's with its OOP philosophy. House hid what little unsafe stuff it had in the H-Layer with rest of OS coded in Haskell with type-system & functional benefits.
So, C's style is neither inevitable nor the best. It was a byproduct of its inventors development style on two, specific machines starting with a typeless, low-level language designed for a worse machine. On other extreme, today there's people coding OS kernels, drivers, etc in theorem provers that automatically extract code in C or assembly with safety and/or termination proofs. The only C compiler, CompCert, that passed fuzz testing bug-free in middle-end used such a method whereas those written in C had tons of bugs despite years of bug-hunting. Drat.
It hid CPU/architecture differences
That's not a binary thing. If you hide too many differences you're internalizing limitations of the worst contemporary architecture.Also, I think it would be odd if someone, who as you carefully summarized had written assembler for a half dozen different architectures, didn't have in mind some loose notion of portability. And, FWIW, I remember reading at some point that Ritchie and/or Thompson felt some sort of vindication when they discovered how easy it was to write a C compiler for other machines.
"C as a portable assembler" is something of a straw man. I don't think anybody with even a passing familiarity of the actual history believes that Ritchie and Thompson had such specific and directed goals.
Another way to spin the history is to argue that you had two engineers who had programmed on a wide variety of architectures, and who were familiar with a wide variety of languages, create a new language that was simple to compile and made pragmatic assumptions about architectural dependencies. For sure they weren't trying to create a universal assembler. Rather, they were driven by pragmatic needs.
Allowing yourself to be directed by actual, manifest requirements without foreclosing future opportunities is arguably one of the best approaches to engineering.
Did C succeed despite it's conceptual shortcomings, or _because_ of them? I think your essay presumes the former without giving enough consideration to the latter.
Or drop down to microcode, were things like eval and the garbage collector tended to live, along with graphics primitives and the usual things at that level. The first widely produced Lisp Machine could be outfitted with a very large bank of this vertical microcode if you were willing to pay for the static RAM to populate it. There was also a Lisp to microcode compiler of some level of utility.
The first paragraph leads with that key factor: "Even back then, there were better languages/OS's that cheap hardware just hadn't caught up to. That cheap hardware's limitations, and them alone, drove the design decisions of BCPL, B, and then C."
So anyone who could come up with a high(er) level language that would run on smaller machines was a winner. It meant the difference between a life of misery hacking assembler or a life of milk and honey coding in a high level language. There was no "Oh, let's be stupid and omit <safety feature du jour> from our language". It was more like "Wow, I got a compiler to run on that PDP-11/20 and it only had to be split into 5 passes to fit into core".
There were many many simple languages back then that occupied this niche. Only C has survived into the modern era (thanks to open source compilers and Unix and Microsoft's adoption of C for WindowsNT). If things had turned out differently we would be complaining about the lack of safety in code stil being written in Bliss or IMP or PL/S.