What is a programming language, and how is it specified? The following set of macros will give the user a head-start on getting almost any C compiler (actually the pre-processor) to chow down on Pascal Programs. As nearly always, or so it seems, there is still a lot more work that needs to be done, even if the only purpose of this exercise (for now) is to prove a point. Indeed, before we can even think about what a programming language is; maybe we need to address the issue of "what is a computer program?"
// so far so good ....
But first, lets us consider how how some hypothetical Alice can now convert her Pascal programs from that class she took in high school to run on Bob's C compiler, which hopefully is lint compatible, on the one hand, and which might also have a C to Spaghetti BASIC runtime option on the other. Or can she? Probably not with Visual Studio Code, at least in its present incarnation; and this sort of thing sadly, will result in an even bigger nightmare with Microsoft's purported AI approach to managing or I hinted at earlier,, "mangling" up code libraries on Git. It is as if we should be entering a new era of code renaissance, but to paraphrase Ted Nelson, who once said, "no matter how clever the hardware boys are, the software boys will piss it away" ... well, I will leave that as an exercise to the reader to figure out.
Despite the fact that you can get about a million hits on any search engine if you search for information about "context-free-grammars", it appears that a simple macro language based on the C pre-processor might indeed be Turing complete, at least in principle, if we had some improvements to the overall concept defining what a context is, or whether contexts should in general be understood in a dynamic sense, that is to say, if that can be done in a well-defined way. The Pascal WITH statement might cause a simple macro-based translation scheme, fits, since the preprocessor would have to have a way of maintaining a restricted symbol table, so that it could match otherwise undeclared identifiers with the correct object forms. This is deeper than the problem with sets, but it is related to another issue and that is what is whenever we encounter a group of statements like SET S = [2,3,5]; S = S + [7,11,13] we try to transform the latter statement into something like ((SET)S) = ((SET)S)+SET(7,11,13); in effect enforcing a C style cast on every variable everywhere in the translation.
This has no effect on any subsequent C compilation, Footnote: consider int a,b,c; (int)a = (int)b + int(c); which should compile just fine in any dialect of C. yet it does give a lispy feel to the output, or maybe I should suggest Python? That is to say that if an intermediate representation of a program according to some translation scheme explicitly required that every occurrence of a parameter be tagged with type information; then that would give the meta language at least some of the properties of a reflective language, which in term implies that even though C/C++ does not explicitly support reflection, we can add reflection via a suitable set of library routines, which would be invoked as appropriate when converting algorithms which can be specified according to some meta-language.
Nothing is better than steak and eggs for breakfast; but stale cereal is better than nothing, right? Does it therefore follow that if A is better than B and B is better than C that A is also better than C? Maybe somewhere in the land of GNU, hidden among and abundance of NILs, NOTs, NULLs, and NEVERMORES, there is some hidden treasure, or some deadly pitfalls, besides and among those things aforementioned.
Now, If that is so, then is stale cereal better than steak and eggs? Not if any "better than operator" must always be contextually aware, so that in the context of does "rock beat scissors?" we can suggest that the "beats" operator is like the "better" than operator, on the one hand. Yet with "steak and eggs" the error is that the meaning of the word nothing has changed from one context to another within an apparent frame; whereas for those familiar with Galois fields, for example, the rock vs. scissors vs. paper example could be understood as a limiting case for yet another over-arching set type where local order is preserved, but circular dominance can also exist.
These types of problems can give rise to important legal challenges for example, such as the issue of liability for defective software. Is it better to over ride the pilot input if the pilot tries to push the yoke down, or pull up; contrary to the "opinion" of the software, even in the case of sensor failure? This has actually happened, at least twice. Now who is liable, and was it because someone didn't really read the code, or try to work out all of the corner cases and edge cases?
Now what if the Pascal WITH statement contains a bug, and that that bug is inherent in the definition of the language itself; at least in principle, because Backus-Naur forms and other efforts to formalize problems of the "my dear aunt sally" variety with context free grammars ... lack concepts, and thus they are vulnerable to frame substitution errors, on the one hand, which may or may not be masked by some types of polymorphism, so that the code appears to execute correctly, "most of the time", and yet the PFC_LIST keeps getting corrupted, the IRQ is not less than equal, and here we go again with another bad patch Tuesday, and now they want us to write.
Somewhere me-thinks that there is some sympletic manifold that can be used to make business decisions that got lost in the maze of twisty little passages, long after the big company with the small name couldn't discern one rabbit hole from another, somewhere in the hall of mirrors that is connected to the maze of moving pathways. There is code for this, of course, somewhere on Git; it just a matter of working out the compiler options and linker options.
Now of course, just as Pascal is a descendant of Algol-60, and Ada is a descendant of Pascal, but then along came C++ which combined feature of Smalltalk with C, and so on. So, is Phyton just de-parenthesized Lisp in disguise; or does it not matter, since with a suitable grammar processor one can input a C or Pascal program and translate statements like print((2+3)*(4+5)); into the equivalent print(mult(add(2,3),plus(4,5)); which really gives rise to the pre-translation:
2: ENTER: 3: ADD: 4: ENTER: 5: ADD: MULT: PRINT:
This is of course, both beautiful and ugly, so simple, and so elegant, all while being so classic, or maybe I could write a flow chart. Yet, nobody uses flow charts anymore, unless it is part of a sales pitch for some motivational seminar, or something like that. However, it is probably not a good idea to use the term “flow chart” and “motivational seminar” and the same sentence, even though I just did, since --- cringe: some business methods are still patentable, and oh how the drafts-people love flow charts! Even if flowcharting is one of the easier rabbits to pull from almost any software hat; with the right tools, or course.
Maybe I should have entitled this log "Go Ask Alice *(when she is ten feet tall), but that will be the subject matter for a later post. So for now, and in other news,, I have made some progress in converting the UCSD p-system from Pascal to C++, so that I can eventually convert it either into a native PASM compiler for the Parallax propeller, or else transmogrify it into a Pascal to Lisp converter, or a native language to pseud-code converter, which then tries to find the right lisp functions, etc..
Hence, even though I HATE Pascal, as I said earlier - the UCSD p-system had a VERY elegant segmentation model that was also very memory efficient. Otherwise, there are many complaints that GCC for the propeller P1) has been abandoned for years, and thus there is also a desperate need for a working large memory model that is more up to date and which can for example use SD cards, or the now readily available (and low cost) 16 Megabyte serial flash memory as a kind of "virtual memory" or else write drivers so that the UCSD p-system thinks that the flash chip is a "hard disk", and then we would get a kind of virtual memory model as gravy, since p-system had a very aggressive segmentation model, that as I also stated - could be made to work more like DLL's work in windows.
That means of course that if we could run WINE or a subset of WINE on the P2, then the P2 architecture would be competitive with the Raspberry Pi world, except that when you look at how the P2 chip works, with it's ability to do to isochronous interleaving of a plurality of tasks across an echelon of processor, with near nano-second scale granularity; there is no comparison.