"Pascal and its Successors" - Niklaus Wirth

Finding this long essay (presently down, see archive here) a good read. Here’s an extended excerpt:

Today, it is hard to imagine the circumstances prevailing in the 1960s. We must recall that the computing community was strictly split into two professional camps. The scientists and engineers used Fortran for their programming large-scale, word-oriented, binary computers, wheres the business community used Cobol for their smaller, character-oriented, decimal machines. System programmers were labouring within computer companies using proprietary machine-code assemblers. There were attempts to unite the two worlds, such as the highly innovative Burroughs B-5000 computer, or IBM’s programming language PL/I. Both were ill-fated and devoured considerable budgets. Pascal was another such attempt, although less ambitious and without budget or industrial support. It applied the idea of recursively defined structures not only to executable statements, but also to data types. As elements, it adopted arrays (vectors, matrices) from Fortran and Algol, as well as records and files from Cobol. It allowed them to be freely combined and nested.

The other fact about the 1960s that is difficult to imagine today is the scarcity of computing resources. Computers with more than 8K of memory words and less than 10us for the execution of an instruction were called super-computers. No wonder it was mandatory for the compiler of a new language to generate at least equally dense and efficient code as its Fortran competitor. Every instruction counted, and, for example, generating sophisticated subroutine calls catering to hardly ever used recursion was considered an academic pastime. Index checking at run-time was judged to be a superfluous luxury. In this context, it was hard if not hopeless to compete against highly optimized Fortran compilers.

Perhaps see also
(Some writings on) some crucial writings in computing

1 Like

That helps explain C…

I didn’t understand until recently that an operating system was written in Pascal called the P-system, and that I had used it many years ago, in the form of Apple Pascal on the Apple IIe. I remembered it was odd, because I had to format a disk just to save my projects, since it used its own disk format.

Researching the other implementations, I found out that Texas Instruments had created one for the TI-99/4A in the form of a P-system card that was installed in the Peripheral Expansion Box, along with a set of disks that contained the p-code for the file system, the Pascal compiler, and an editor. An implementation had also been created for the IBM PC (by IBM, perhaps?).

Given that p-code was really a form of bytecode, it was possible to write other languages in it, and indeed, that was done.

Seems pretty neat, when I think about it, but the idea didn’t take off.

This idea of making Pascal portable through the development of p-code came pretty early. Wirth thought of it, because he wanted people to be able to share software written in Pascal across different systems. If it compiled to native code, that would make it very difficult, he thought. So, compile it to p-code, instead, and you could just share the p-code across systems, and it would run.

At first, he came out with what he called his p-kit in the early 1970s, which was essentially a compiler and VM. He eventually compiled the Pascal compiler to p-code, making it a self-hosted language.

UCSD came up with the idea of the P-system, an operating system written in p-code, aka. UCSD Pascal, in the mid-1970s. Interesting learning that this same idea was hanging around, shortly after the development of Smalltalk, which had a pretty similar idea about it. Though, Smalltalk was arguably more successful on the merits, given that you can run its original text and graphics on modern systems very portably.

A key limitation of the p-code system that Wirth created was that its portability was not extendable to things like sound and graphics, or network capability, etc. Only console-based, text-oriented I/O was portable. This really limited the appeal of using the P-system (which had the same limitation). You could generate p-code for those features, but they were tied to the system where you used them. They were not cross-platform.

I thought it was interesting to learn that the scheme of compilation and execution Java has used was created more than 20 years before it came on the scene.

1 Like

Even by the mid-2000s, the AS3 compiler for Flash Player 9 (yet another byte code engine) had an optimization option for omitting run-time checks of boundaries – and this did speed up things noticeably. Run-time checks are expensive,…

Run time checks don’t catch eveything. Running out memory or heap or bad pointers are they checked? Parameter passing really does need to checked how ever,
C lets you code what you need. I like old the wild west of C programing,before all this code
optimization and standards. You knew what the code did. No type checking let you
handle weird things in code.
The real problem is you had no memory with 8,12,16 bit computers, so checking of code and comments of often where omited, BASIC was bad for this.
Ben.

I struggled to find this, but it’s apposite:

Regarding being worthwhile to pay for the protection, I would quote Hoare, regarding his experience with Algol compilers in production presented at the Turing Awards speech.
“Many years later we asked our customers whether they wished us to provide an option to switch off these checks in the interests of efficiency on production runs. Unanimously, they urged us not to–they already knew how frequently subscript errors occur on production runs where failure to detect them could be disastrous. I note with fear and horror that even in 1980, language designers and users have not learned this lesson. In any respectable branch of engineering, failure to observe such elementary precautions would have long been against the law.”

Oddly, in this talk Hoare says something slightly different:

08:00 Adding checks to arrays added space and time to the program; on Tony’s first machine it ran at less than 2k operations per second (500 micro seconds per operation, and two such tests for each array bounds).
08:40 No undetected array errors, and customers didn’t know they could trade off safety for speed.

2 Likes

I am thinking more, NULL pointers was not the mistake, ALGOL was. The same
goes for PASCAL, all teaching, not production languages. JAVA is closed source.
Now if there was a standard for pesdo-code used text books, that would be useful
to know.
Ben,
PS: can we ever get a spell checker for the editor?

I think, it’s important to note that Algol wasn’t just a computer language, it was a general notation form for algorithms that happened to have a “machine representation”. Which is pretty amazing, if you think of it. (Null pointers introduced some of a schism into this.)

Having said that, I’m not aware that Algol was used much outside of computing.

PS: Meaning, Algol isn’t that much about what an ideal programming language may look like, but more like, what if we had a formal description language that would lend itself as well to the problem space as to a computer implementation, so that we could transfer any model or algorithm described this way directly onto a computer and run it. (Yes, we may have to transcribe some Greek letters and other symbols, but that’s essentially it.) It’s more about how computers could integrate into the scientific space.

I came from the mainframe corner with Fortran, Cobol and PL/I and was completely shocked how anyone could seriously consider such a wild macro assembler as a programming language.

1 Like

Not sure what BASICs you’ve used but traditional BASICs have always done array bounds checking and keep track of things like GOSUB, etc. stack sizes, “heap” allocation via DIM and so on.

Of-course peek & poke have a lot to answer for…

-Gordon

Algol. To much math theory for my liking. Never liked logic in general, The door is
open, the door is closed. Real world, the door is open but a Gorrila is standing in it.
How do I handle the set of numbers, that are prime and are the middle 200 of the first
1000 primes.

With BASIC I was thinking more like INPUT A$; if A$=‘Y’ gosub 100
What about ‘YES’ or ‘N’ as input.

Soon I will have meta compiler… more evil languages to write.

Ben.

To provide an example: say, a neuroscientist publishes a paper on the visual cortex of a cat, describing how the signals travel through the “system”, with all the relevant interconnections and bandwidths. As she publishes these descriptions using Algol, we can directly transfer this to a computer and run a simulation to validate it and maybe conduct some further experiments with this model. This is a huge vision, eliminating many intermediary steps and processes, as well as some systemic problems with computers in scientific research. However, as Algol tackles this in a highly systematic manner (which is somewhat to be expected, provided its scope), it involves some rather abstract (i.e., mathematical) approaches.
Conversely, it is not as much about how we want to deal directly with a computer. If it performed well in this category, as well, that would be (merely) an additional win.

(Regarding the spell checker: There should be one in your browser, check the context menu of the textarea. But I keep forgetting about this, as well. :slight_smile: )

This assumes ALGOL discribes the problem. It does not as brain uses chemistry and
physical placement to work. Electrical impulses are just one aspect of nerve cells.
real,int,boolean … no nerve cell data type.
What you do is write BRAIN-GOL for your problem. Use the tools to fit the problem.
Ben.
PS: At one time you could get a APL I/O device, so you could use ALGOL.
ALT abcd4 to get a ⏨ seems arather weird way to enter data.

1 Like

I’ve to admit that I’ve kind of an aesthetic fascination going on with Algol, right from the beginning, as it was the very first programming I ever learned (but never used). This may be well responsible for me having caught on programming, at all.
On the age-old question, “is it art or engineering”, Algol is clearly on the artsy side of thing, which is sympathetic to me personally, but is probably an absolute no-go nowadays.

There are some obvious problems with Algol. E.g., just take switches in Algol, which allow you to mix in state logic into any other type of logic at about any level. So you end up with something that may look like an array and an index as an argument to an array related procedure, but in actuality, this totally changes the behavior of the program and what the code actually is about. Some Algol constructs are both very high level and very low level (compare again switches) or may occur both at a high level and at a low level (e.g., if-else clauses in value expressions). This leads to highly abstract programs, which may be hard to follow, if they go full in on Algol features. It’s like Perl, just from an opposing angle. However, as opposed to Perl, which comes quite naturally (while writing that is), there isn’t an ideal level at which to “think Algol”. So, yes, it’s an awkward tool. But a brilliant one, especially given the lack of precedence.

For fun, have a look at that beauty of a switch declaration combined with in-line if-else, one of the examples provided in the Revised Report:

switch S:=S1,S2,Q[m], if v>-5 then S3 else S4

For those not familiar with the concept, a switch in Algol is a data structure consisting of labels and/or other switches to be used with goto and an index/subscript. So what will be the meaning and consequences of the following statement (again from the Revised Report), where we pass switch “S” as an argument to a procedure, where it is locally known as “Town”?

goto Town [if y<0 then N else N+1]

Again, this is not an extreme abuse of the concept, this is exemplary text book behavior, provided in the very definition of the language. I do admit, this is somewhat alarming.
Also, yes, we do want run-time checks in Algol, compare this example.

I remember trying out UCSD Pascal, I think on a Commodore PET, at one place I worked. We thought it was interesting, but not suitable for writing production code for our customers (at that time we used a mix of BASIC, compiled BASIC, and Assembler for that). I’ve not been able to find out much about UCSD Pascal on the PET, so perhaps I’m misremembering.

I tried Modular-2 on the Amiga, and again found it interesting, but not really suitable for writing fast action game programs (I had a Lattice C compiler I used for that).

Later, at another company, some of the programmers were using Borland Turbo Pascal, but by then I was using various C compilers on PCs, so I never really got into Turbo Pascal.

I didn’t know about Oberon and its various flavours until I read the article. Seems interesting, but it never really caught on, and I don’t have the time to invest in learning a programming language that no longer has many users.

I don’t think that’s a fault of the language. Happens everywhere. Sloppy/Lazy programmers, sadly.

Have you looked at ML?

-Gordon

Note that you could buy machines that used p-code as their native machine code (implemented in microcode).

And Wirth did a machine that had m-code as its native machine language (also microcoded) for running Modula-2.

2 Likes

I got FPGA card here with Oberon here, another Wirth product, with his version of a windows type operating system with a RISC cpu.
Too busy playing with my own cpu design at the moment, for that.
As for ML it uses too many hard to pronounce words for me. :slight_smile:
Small here, as I have 48kb user space and 32kb os space. DOS era programing
640k or less.

1 Like

I got to use SML when I was in college, in one of my upper-division courses. I took to it well. It was the first time I felt like I understood functional programming.

The thing about it that was a revelation to me was how it used patterns as function signatures. I wrote a binary search in it, and I could just write out all the cases as patterns, with function code that would handle each case, citing new patterns, which represented what to do next, and these patterns would match the function signatures. It was easy to follow the code. Very nice.

2 Likes

I did something similar in … Erlang? I forget which FP language. But when it gels it’s a thing of beauty. Unfortunately I think I have one of those brains that was ruined by BASIC, so imperative and OO solutions come to mind before any other paradigm.

It’s worth pointing out that today’s “big” processors with branch predictors don’t suffer much from index checking. It does pollute the branch prediction cache and code cache, so it has a small measurable impact. For Google-scale services where a 1% overhead may mean tens of millions USD in yearly costs, it sure would make a difference. But on the desktop, and on the mobile? Not very much.

On older pipelined processors without sophisticated branch predictors, there often was a jump convention - say forward jumps not taken, backwards jumps taken. As long as out-of-bounds jumps were forward on such a system, they would not flush the pipeline. This was of some importance on machines with deep pipelines. To mind comes the disaster known as NetBurst (Pentium IV). On that one, a pipeline flush was a lot of wasted work!

1 Like