Yes. Nobody would have used Ada absent the DoD Mandate.
Generally true. My solution was to use a mix of Fortran and assembly-coded fortran-callable subroutines and functions.
I have also used fortran in realtime systems, including to code interrupt routines. This was before fortran developed call stacks, which led to some very interesting bugs when shared routines were fought over.
Not really. I suppose the best example is priority inversion, which I first encountered when I became a embedded realtime programmer in 1974
- it was part of the lore, an entry in the long list of blunders to be avoided, but had neither a name nor a literature. My boss told me about it in 1974 while I was learning the ropes.
The developers of Ada did not even know of that lore, never having built and fielded a non-trivial embedded realtime system, and so fell into this and other traps.
When the Ada gurus figured out why they were getting these devastating random big delays, the named the cause and wrote many learned articles.
A key example is Rendezvous. As mentioned before, I built a middleware in Ada83 (plus some assembly) to replace Rendezvous, for a factor of ten reduction in message-passing latency, and the elimination of forced synchronism.
The basic interface had four APIs: Get empty message (a block of memory from a linked list), send message, receive message, release message for reuse. Message transfer is asynchronous - neither sender nor receiver wait for the other, unless they want to.
The problem with message facilities having only send-message and receive-message APIs is that the operating system and/or the application level code (like the middleware) is forced to copy the message contents time after time. DEC was very proud that the message interfaces in VMS only copied the message text seven times going and another seven times coming, for a total of fourteen times.
Given the amount of data to be sent and received in a radar, and the speed of the computers of the day, copying the message text is simply untenable, by at least two and probably three or four orders of magnitude. Only a shared-memory pass-pointer architectures can work.
Which brings me to the second key example, shared memory. Ada83 simply had no concept of shared memory and especially of multiprocessor systems with global memory, despite wide use in embedded realtime systems of the day.
To build the shared-memory pass-pointer architecture, it was necessary to implement shared memory between different processes on different processors. Ada83 simply could not do this, not even after clever pruning of the language, because the code optimizer did not know and could not be told that there were other entities that could change memory.
The solution was to realize that according to the Ada LRM, the optimizer was required to treat subroutine calls as atomic. So the shared-memory stuff was done in Ada-callable assembly, where Ada could not see, allowing us to keep Ada in ignorance of things she could not understand.
The part about "because the code optimizer did not know and could not be told that there were other entities that could change memory" also crippled hardware control by reading and writing memory-mapped control registers. Again, assembly-coded Ada-callable subroutines to the rescue.
One obvious question is why we didn't use C, versus assembly, to implement the shared-memory functions, given that we had DEC C. The problem was political: The Ada zealots were afraid of C (their main competitor), but not of assembly. The added effort of coding in assembly was still less than the added effort of fighting the zealots off if we used C. Although it would have been interesting to see how the zealots dealt with a 100:1 to 1000:1 performance problem.
The DoD had a deleterious role here. Their insistence that the entire language be implemented from the start, without being able to start small and grow, forced both compiler and validation suite to be huge, and prevented any serious efforts to optimize the generated code. Said another way, the world's supply of Ada compiler gurus was absorbed with getting obscure parts of Ada and the suite to work. It was many years before compilers good enough to be plausible emerged. It would have been far better to start with the core 10%, and to allow changes to the LRM as experience accumulated.
Data point: Back in the day, I compared the size in bytes of the DEC C compiler and the DEC Ada83 compiler, both of which were well respected. The Ada83 compiler was ten times the size of the C compiler. Complexity is not linear in size, it's more like quadratic.
I've been hearing various forms of this claim about the then latest compilers for the last 45 years, and it has never been true, for a very simple reason: No compiler understands intent, or will tell the programmer that if they only redesigned their entire program around a specific special instruction, a 100:1 speedup would be possible.
My favorite special (SEL 32/55 and I believe IBM 360) instruction is Execute Remote Indexed, which was used to implement a 3-dimensional lookup table of actions to take when a specific button on a specific control panel of a specific box was operated. The actions were single assembly instructions that could be anything from changing a date value to calling a subroutine. There were at least 20,000 selectable actions.
Coming back to optimizing compilers, the real case for them is economic: While any good assembly programmer can beat the compiler, it is not usually worthwhile to do so, because computers have gotten fast enough and cheap enough that shaving 10% off simply isn't worth it.
By 1983, the FORTH folk had gotten over it, but in 1972 or so, when it first came out, they would say very little about how it worked, and they wanted $10,000 for access. In those days, a Volvo sedan was about $3,000.
I asked for a list of ten happy users to talk to, and started calling. Only the users that had cracked the kernel were able to program in FORTH, so, I got an octal dump of the PDP-11 FORTH kernel from one happy user, and reverse engineered the kernel. Then I knew why they were so close-mouthed - it was far too small and too simple to justify such a price. So, I wrote Fifth.
Joe Gwinn