My Path in Research. The 70s
Motto. I invite you to look at this journey not just as a recollection of facts and achievements, but as a call to your personal effort to continue conceptualization, innovation, and the promotion of freedom of thought in computer science, so that every idea can cross time and technology, giving each generation the means to create its own future.
Chronological (narrative) reading, complementary to the Research section organized by domains.
Introduction
Sometimes I wonder when my journey in research actually began. There isn't a precise moment, a day that signified a conscious and definitive choice. It was rather a silent calling, a slow flow, driven by an inner need: the need to understand the world, to structure it, to make it more coherent and freer in approach. The computer forces you to do this: you must understand reality well to present it as faithfully as possible to the computer; otherwise, everything is falsified.
I took the admission exam for the Faculty of Energetics at the Polytechnic of Bucharest following a pragmatic choice made by my father. The field was promising, and the competition for admission seemed more accessible than at Electronics. To me, any field in the Polytechnic was indifferent: my dreams were elsewhere, far from the technical area. My father had obtained for me a promise of a scholarship from a Bucharest enterprise, which could make a difference in case of equal averages. I had no problems with admission; I entered Energetics with a high average.
After graduating from the first year, in 1962, thanks to pro-rector Cornel Penescu, the Automation section was established, and for populating the 2nd and 3rd years of the section, the best students from three faculties were selected: Electronics, Electrical Engineering, and Energetics. I was among those chosen for the 2nd year, thus staying at Energetics but following the Automation specialization. Gradually, this field began to attract me, and I congratulated myself on this lucky turn of fate.
In my final years of study, I followed two computer courses, both analog and digital. The subjects were interesting, but the professors — who were just then learning themselves what to teach — failed to excite us. Based on personal liking, I chose as my supervisor for the diploma thesis Ivan Sipoș, a young assistant involved in artisanal computer design. The theme received — designing a digital desktop calculator — was not at all trivial in 1965. I started with the design of combinational and logic circuits, in an era when transistors were just appearing, and integrated circuits were still far off.
In the Romania of the '60s, in a modest, limited, and often rigid technological landscape, I discovered the secret charm of computers. It wasn't just about their fascinating power to execute commands, but about the possibility — still vague but seductive — of creating structures, as if alive, inside them: in fact, worlds of their own, ordered by more rigorous rules than those of immediate reality.
My diploma project was well received, and I obtained a grade of 10 at the diploma exam. I was assigned to the Factory of Automation Elements (FEA), a new enterprise, equipped with Japanese technology, established with consultancy and assistance from the Japanese company HOKUSHIN. Very modern, it constituted, in terms of conception and organization, a model for other subsequent factories in the branch. All the engineers of the factory were specialized in Japan. I, however, arriving in the factory when the scholarship games were already made, did not partake in that specialization, so I was given for study the technology of two Romanian electronic automation systems, UNILOG and UNIDIN, designed by IPA (Institute for Design in Automation) and produced for two years at the Bucharest factory Electromagnetica, with tradition in telephony. To take over the production of the two products at FEA, I was seconded for a year at Electromagnetica.
Returned after a year of secondment, alongside other colleagues at FEA, fresh graduates of the Polytechnic but not trained in Japan, we felt like intruders among the Japanese products that shone in comparison with the poor Romanian products. I began to seek a way out. I still maintained the connection with Ivan Sipoș, my diploma project supervisor, who at one point told me that he had spoken with Professor Penescu, now the dean of the Faculty of Automation and head of the Specialty Department, to open an assistant position for me.
In the meantime, many changes had taken place at the Polytechnic: thanks to the efforts made by Prof. Penescu, the Automation Section of the Faculty of Energetics was transformed in 1967 into the Faculty of Automation, of which Penescu, besides department head, was also the founding dean. Later, due to the process of increasing the importance that the government gave to the computer industry in Romania, which also led to the production of Felix computers under French IRIS license, the Faculty of Automation was transformed in 1969 into the Faculty of Automation and Computers, with the new Department of Computers.
Ivan's good word mattered; Penescu also knew me, I had been his student with high grades, so I took the competition, won it, and was to start activity in the second semester of the 1969–1970 academic year.
It was, however, the period of the establishment of the Department of Computers in the Faculty of Automation under the leadership of Associate Professor Mircea Petrescu. It was to be formed from specialty teaching staff from Electronics and Automation brought from other departments of the Polytechnic. Sipoș moved with enthusiasm to this new department and, given my background related to computers, convinced me too to take the same step.
That's how I entered the universe where I was to spend my entire career. The Romanian proverb "the year does not bring what the hour brings" summarizes well the fact that events and changes can occur rapidly and unpredictably in life, overturning forever everything that was predictable until then, carrying our lives to unexpected lands. How many such occasions each of us has had in life…
Arrived in the Department of Computers, I began my career as a teaching staff member at the Polytechnic of Bucharest in 1970, with the simple but profound desire to build with the computer structures that could reproduce human behavior, to replace humans in their various activities. In the first two years, my future seemed linked to computer design, in one of the teams coordinated by the two professors Petrescu, Mircea and Adrian.
In parallel with my job, since my internship at FEA, I was attending full-time courses at the Faculty of Mathematics of the University of Bucharest, specializing in Computing Machines. In the final years, the emphasis of our training as mathematicians fell on computer programming, and thus I discovered the software domain, which was to fascinate me truly.
As soon as, within the Polytechnic's Computer Department, the issue of starting software projects arose, I joined with enthusiasm, abandoning without regret the initial direction of hardware design.
Attempts to master as well as possible the complexity of software and to infuse reasoning into inanimate systems were for me not just professional stages. They were forms of the same quest: the quest for a deeper freedom, the quest for an order hidden in chaos, the quest for an intelligence to serve life, not replace it.
This journey, over five decades long, has borne many names: portability, software engineering, artificial intelligence, medical informatics, digital ecosystems, or digital twins. But beyond labels and temporary technologies, it was always the same journey: the journey toward a world in which thought, life, and technology can coexist in harmony.
I write these lines now, looking back over this journey, not as a cold balance sheet, but as a living story that does not end with me: a story about what I sought, what I understood, and especially about what I became in the course of my quest.
Unleashing the Software (1970–1980)
Looking back, I realize that my first big battle in computer science was a battle for the liberation of software from hardware shackles.
In the '70s, the world of computers was divided into isolated fortresses: each computer system was a closed kingdom, each program was the prisoner of the architecture that had given birth to it. It wasn't just about technical differences, but about existential limitations: code written for one machine was useless for another, and each progress seemed to build a new wall instead of opening a bridge.
High-level programming languages (COBOL, FORTRAN, LISP, ALGOL-60, etc.) were introduced in the '50s and '60s not only with the purpose of bringing the interaction with the computer closer to dialogue between people but also to create a common denominator between different machines. It was a big step forward in the direction of software's liberation from hardware dominance.
The advantage of these languages over assembly languages, specific to each computer, was obvious: writing algorithms in a form close to mathematical expressions gave them immediate success. With these languages, one stepped out of the narrow circle of a platform, offering the possibility of executing a program on several different platforms, provided there was a compiler for that language on those platforms and at the cost of recompilation. We were, however, still far from the ideal of a program with its own life, independent of the physical platform.
But let's see how things stood with the new computer technology in those years at the Polytechnic Institute of Bucharest.
Computer programming was talked about timidly in the Polytechnic since the late '60s, at the Digital Computers courses. I myself had such a course in the 4th year, but programming was only discussed by reflex: digital electronic circuits and, eventually, the computer's assembly language were central themes. The theme of my diploma project was the design of a desktop calculator, but there was no question of the possibility of programming it.
Due to the visionary character of Prof. Grigore Moisil from the Faculty of Mathematics of the University of Bucharest, who foresaw the brilliant future of computers in society, in 1968, the Computing Center of the University of Bucharest (CCUB) on Ștefan Furtună Street, led by the professor, obtained from IBM laboratories in Vienna an IBM 360/30 computer, of the third generation, despite the embargo imposed on socialist countries regarding new technologies. Thanks to Moisil, this computer became accessible to the public — in fact, to those interested in programming it.
CCUB had become a focus of computer culture, and many of the future computer specialists were trained there. For six months, IBM organized courses of a few weeks to train the Center's staff in programming and using the computer with FORTRAN, COBOL, and ASSEMBLER languages, as well as with the DOS operating system. IBM also brought application software packages and documentations. Besides CCUB staff, many other interested persons from Bucharest and the country participated in these courses, so the experience — and the attraction — of using third-generation computers spread rapidly. At the Polytechnic, without its own computer, eventual programming themes were solved with the IBM 360 computer at CCUB.
Professor Moisil then encouraged the organization of courses for various users, which he called "free courses." In 1969, Moisil established the Department of Informatics at the Faculty of Mathematics, and at the Polytechnic, the Department of Computers was established. The actual establishment of the Department of Computers within the Faculty of Automation took place in the autumn of 1969, under the leadership of Professor Mircea Petrescu, with a team of 11 teaching staff members. I was the 12th employee in the department, six months after its establishment.
A Passion for Formal Systems
At the Faculty of Mathematics of the University of Bucharest, Professor Dragoș Vaida centered his Programming Languages course in the fourth year on the ALGOL60 language, which he was passionate about. In one of the lectures, he invited a colleague from Professor Moisil's group of researchers at the Computing Center, recently returned from a residency at the University of Grenoble, where he had specialized in formal languages. In the few lectures he presented to us about Chomsky grammars, this guest managed to captivate us to such an extent that we fell in love with these mathematical models of natural language, introduced by Chomsky fifteen years before.
Fascinated by formal systems, in 1972, I began attending the evening courses on Automata Theory held by Professor Grigore Moisil at the Faculty of Law of the University of Bucharest. After the course, I would walk the professor slowly down 6 Martie Boulevard talking about many subjects, up to his house behind the Armenian Church. There, on the corner of Armeneasca Street, was a small park with a bench where we sometimes stopped. We would sit on the bench and the professor would take out of his large, soft, worn leather briefcase a jar of yogurt and eat it with a small spoon. "Viorica scolds me if I return with the yogurt home," the professor would excuse himself, smiling.
The professor urged me to write the first article, based on my mathematics diploma thesis supervised by Dragoș Vaida: "Semantics of programming languages with the Vienna Method." In this denotational semantics attributed to the IBM Laboratory in Vienna, the abstract machine associated with the language had as data some objects (mathematical) with a tree structure. My article gave these objects a formal definition. I gave the article to Professor Moisil who promised me he would transmit it to a collaborator of his specialized in formal languages. After a week, the professor brings me the article with the collaborator's comments, which demolished it due to a circular definition used for trees in which the object to be defined appears in its very definition. Mathematically, such a definition was indeed wrong, but in the depths of my soul, I knew that my definition was correct in the context of computation theory provided that the object to be defined is instantiated and I add the base cases, i.e., the cases of initial instances that satisfy the definition without being defined in terms of the definition itself. The shock of that rejection was too strong. Discouraged, instead of correcting the article as I would have done a few years later, I abandoned the idea of publishing it.
The UNDP-UNESCO Program
During the period 1969–1973, my department benefited from a UNDP-UNESCO program intended to increase the specialization of teaching staff in the field of computing. I have described this beneficial program for all of us in another chapter; however, what is worth remembering here is the essential support offered by the Technical University of Darmstadt within this program. The German partners provided us with two IBM computers — an IBM 1130 and an IBM 1401 — almost new, but already considered outdated at their home. We also received an HP 2116 B minicomputer, with "toggle switch" programming and with a paper tape reader, considered a competitive computer at that time. With these computers, a research team from our department achieved, alongside specialists from Great Britain and France, the interconnection of two computers — a premiere in Romania.
In parallel, my colleague Petre Dimo, who had participated in the courses organized by IBM at CCUB, where he learned FORTRAN among others, published in 1970 a book about FORTRAN IV programming — the first book of its kind to appear in Romania, which had a great success among specialists. In 1972, the recently established Computing Center of the Polytechnic received a FELIX C-256 computer, made in Romania after a French IRIS-50 license. It worked with punched cards, had a magnetic disk and two magnetic tape units. With this computer and with Dimo's work as bibliographic support, we began teaching the FORTRAN language at the Polytechnic. Dimo and I were the ones who initiated the Computer Programming course in the 1st year in 1973, first at the Faculty of Automation, for the two parallel years, and then, with the support of other members of the department, at the other faculties within the Institute.
The number of programs sent daily to the Computing Center increased rapidly. Most had syntax errors, which involved a laborious cycle: execution of the program written on punched cards, testing, correcting, punching new cards, and resuming the cycle. To reduce this effort and save cards, several members of the department under Dimo's leadership decided to support the Center's activity by developing a conversational system SISIF, FORTRAN-oriented, with multiple access — a verification and correction environment for code, designed to function before card punching. We decided to experiment on this occasion with two of the latest technological novelties in computer science: time-sharing technique and computer interconnection. It was chosen that the application accessed by multiple users would be a re-entrant FORTRAN syntax analyzer, executable on the HP2116B computer. The students' consoles were to be linked to the same HP2116B whose operating system offered multi-tasking. The correct programs were to be sent to the IBM1301 computer for execution.
SISIF
Within this system, I dealt, along with Florica Moldoveanu, with writing the FORTRAN syntax analyzer. This analyzer allowed students to interactively verify the syntactic correctness of programs, entering the code from the console. The analyzer should have received the students' programs line by line. At the end of each line sent by a user, the analyzer should have evaluated the syntax of the line in the context of the previous lines of the same user. In case of errors, these had to be notified to the respective user who could correct the line and resend it to the analyzer.
Once validated, the program could be punched on cards and processed without resuming the arduous cycles of correction. The analyzer was written in FORTRAN on the HP 2116 B computer. Unfortunately, the lack of a formal description of the FORTRAN language's syntax prevented me from using design methods based on formal languages, although my knowledge in the field was fresh — I had just graduated from the Computing Machines section of the Faculty of Mathematics of the University of Bucharest. This experience was for me the first concrete confrontation with the idea of software autonomy — not only from hardware but also from the rigid cycles of classical development.
The realization of the SISIF system led to theoretical contributions in the synchronization of parallel computing processes, in verifying their correctness, in evaluating the performance of parallel process synchronization mechanisms, and in elaborating models for deadlock prevention strategies. These contributions were presented at the SAII communication sessions organized by the faculty.
Starting the PhD
In 1973, I started my PhD under the supervision of Mircea Petrescu. He established, without asking me, the title of my PhD thesis: "Implementation of a language for an interactive data processing system". The inspiration came from the research of Professor Louis Bolliet from the University of Grenoble, our expert within the UNDP program. The two had first met in Bucharest, and then Mircea Petrescu met him again during a residency in Grenoble, where he was impressed by his innovative approach to human-computer interaction. According to the PhD supervisor's intention and given my mathematics studies, my research direction had been traced: formal language theory, a field compatible with my mathematical background.
ALGOL60 and the Challenge of Implementing a Conversational Compiler
ALGOL60 was a revolutionary language, imagined and designed by a group of 13 renowned specialists, computer scientists from the United States and Europe. Although it was a major innovation, its use in commercial applications was hampered by the absence of standard input/output facilities in its description and by the lack of interest in the language on the part of major computer vendors, who felt no need to complicate things with a complex language when simpler ones existed, for example FORTRAN or COBOL, sufficient for their immediate needs. It can be said that ALGOL60 was a language that appeared "before its time" being not only a radical improvement over its predecessors but also a constraint for almost all its successors, raising the bar for next generations of programming languages and becoming the standard in the publication of algorithms.
Among its innovations, ALGOL60 introduced the concept of a block, a sequence of instructions in a program delimited by the keywords begin and end. Such a block defined a scope, i.e., an area in the program in which a binding of some program entities (variables, functions, etc.) to some ad-hoc introduced names (identifiers) is valid. The block was an essential progress for the appearance of structured programming only 7 years later. Also, ALGOL 60 was one of the first languages that allowed function definitions, which in addition could be nested within each other and could be invoked recursively.
But perhaps its most important contribution was the use of the Backus-Naur Form (BNF) metalanguage for defining the syntax of a language. BNF is a formalism through which the syntax of a programming language can be described as a context-free formal grammar from the Chomsky hierarchy. After ALGOL60, BNF became a standard in the description of programming languages.
Due to ALGOL60's complexity, there were no complete implementations of the language, and existing variants were partial and non-conversational. Besides a new implementation of the ALGOL60 language, Louis Bolliet was probably interested in time-sharing and interactive access to the compiler — the possibility for multiple users to simultaneously send instructions to the computer and receive error messages in real time to correct their programs, eventually re-proposing them then to the compiler.
Such a way of working could be obtained only with the destructuring of the compiler, forcing it to work incrementally, i.e., processing instructions (increments) as they were entered. The essential component of such a compiler was the syntactic analyzer, which had to manage multiple users simultaneously and offer them precise error messages, allowing users to edit their programs online. Under these conditions, the compiler had to store the context for each session of a user, i.e., gather enough information from the part of the program compiled until then, to be able to notice errors related to context dependencies specific to the ALGOL language grammar. These context dependencies were expressed in natural language in the language definition.
Such a project was, however, too ambitious to be carried out by a single person, and this was obvious to me from the beginning. Officially, I had five years at my disposal to advance as much as possible, but academic reality proved to be much more complicated: new courses to prepare, research contracts with industry, articles and books to write.
Program Portability – From Exercises to Articles
On the background of the experiences with SISIF, the first coherent thread of my research was built, almost without me realizing it at first: program portability. In a technological context dominated by machines incompatible with each other and by languages closely tied to hardware, portability was, in fact, a form of resistance: an attempt to grant software a "free citizen" status, capable of migrating from one architecture to another without being rewritten from scratch. Around this idea, a small "school" was crystallized within the department — colleagues and students with whom I transformed practical problems into publishable results.
BCPL
Briefly, about BCPL
BCPL (Basic Combined Programming Language) was a procedural, imperative, and structured programming language. The language was imagined and first implemented by Martin Richards, from the University of Cambridge, in 1967. Originally intended for writing compilers for other languages, it was a true software gem of the time. It had an illustrious descent: from it was derived in 1969 the B language (Ken Thompson and Dennis Ritchie), from which the C language was later born. Richards, concerned with the fate of his language, used many concepts of theoretical computer science and programming that appeared in the '60s to facilitate the implementation of the language on the most diverse platforms.
BCPL was conceived so that its compilers would be small and easy to port. Richards implemented the compiler even in BCPL, which made it self-hosting — a necessary condition for real portability. It is known, however, that a compiler is inherently dependent on the target machine (the one for which it is written), because a part of it — the one dealing with code generation — must be rewritten for each different machine, starting from a common software baggage for any platform (program stored on punched or magnetic tapes).
The "weirdness" of the BCPL compiler, in Richards' conception, consists in an explicit intermediate form, which the compiler generates as an interface between the independent part and the machine-dependent part, so that then, from this intermediate form, the effective machine code is generated. This intermediate form is written in a language called OCODE and was seen as the assembly language of a simple abstract machine, BCPL-oriented. The abstract machine had a linear memory for saving variables, consisting of cells of equal sizes, addressable by integers, so that consecutive integers refer to adjacent cells. This approach became a common practice later (for example, in Pascal, Java).
BCPL introduced several characteristics of many modern languages, including the use of braces for delimiting code blocks. The language is unusual also by the fact that it has a single data type: a word — a fixed number of bits — chosen usually to align with the machine-word of the architecture of the platform on which the implementation is done and with an adequate capacity to represent any valid storage address.
Our Implementation of BCPL
In 1974, Mariana Necula, my department colleague, brought from England, on a punched tape, the source of the BCPL language compiler, written in an intermediate level language called INTCODE, which generated INTCODE code. This version had been recently perfected by Martin Richards, the language's author, to simplify the procedure of "porting" the BCPL compiler on various platforms.
The original compiler for BCPL had been written by Richards in the BCPL language itself, in the idea of making it as portable as possible. But the truly popular solution proposed by Richards for the portable implementation of BCPL was the choice of the bootstrapping method. By "bootstrapping" we usually refer to the process by which a simple system initializes and/or activates a complex system. To be more precise, there are two types of bootstrapping:
Whole bootstrap involves writing a compiler in a high-level language, compiling it with an already existing compiler, then using the new version to recompile itself — self-hosting.
Half-bootstrap refers, as in the case of BCPL, to the fact that a fixed, minimal part of the system (for example, an interpreter for an intermediate code) is written directly on the target machine; then this is used to run or generate the rest of the system.
In the case of BCPL, bootstrapping involved:
a BCPL compiler written in BCPL (so self-hosting),
which generated intermediate code: OCODE (machine-independent),
and for "porting" on a new machine, only a translator OCODE → native code was needed or, the simpler version, an OCODE interpreter, written directly for that machine.
In our version for the bootstrapping of the BCPL compiler implementation, Martin Richards introduced an INTCODE abstract machine, whose machine code has an intermediate level assembly language, also called INTCODE: a compact and extremely simple language, thought to be independent of any real machine. INTCODE was thus an even simpler intermediate layer, for rapid interpretation on new machines, precisely for the purpose of a quick bootstrap.
In the version received by us, to transfer the BCPL compiler to a new machine, Richards provided to write first a small INTCODE interpreter for the target machine. The INTCODE assembler and interpreter were together approximately 4 to 6 times smaller than a typical BCPL code generator, from OCODE to assembly language. Implementing an INTCODE assembler and interpreter could be done in 2–3 days. The purpose of INTCODE was to allow the developer to obtain a temporary interpretive implementation on the target machine in a minimum time. With the INTCODE interpreter, the BCPL compiler became executable on a new machine: with this small software device, one could read the punched tape containing the BCPL compiler written in INTCODE and execute the compiler on the new machine for any BCPL program, even before the existence of a backend for native code generation (INTCODE → machine code).
In other words, INTCODE created a temporary interpretive implementation of the BCPL compiler on the target machine. Subsequently, using even the BCPL version of the BCPL compiler (self-hosting), the first native code generator could be written and one could gradually give up the interpreted layer.
This ease of implementation was paid for with the slowdown of BCPL programs' execution. Even if through INTCODE a factor of approximately 10:1 was lost in execution speed, the INTCODE interpreter was nonetheless a useful tool for the initial implementation of BCPL on the target machine, allowing then the first effective code generator to be written directly in BCPL, using the BCPL version of the BCPL compiler.
Consequently, to be able to use the BCPL language in programming courses, we had to implement on the FELIX computer an INTCODE interpreter capable of executing the original code. This phase, apparently modest, was in fact a decisive moment: a code written in an abstract, portable language, could "sprout and give fruit" in a completely different environment through the simple implementation of an interpreter adapted to the environment. After successfully running the interpretation, we obtained a functional BCPL translator, which allowed us to develop and run programs in BCPL, free from the constraints of proprietary assembly languages.
Working with the BCPL language, the elegant and robust precursor of C, I began to sketch a new dream: a program in a language that would survive hardware change, travel between systems and keep its identity in any context. Two decades later, James Gosling would imagine the Java language for Sun Microsystems, using the same principles of portability — although no source explicitly mentions Richards' influence, the conceptual analogy seems obvious to me. The academic knowledge of the two worked as an arc extended in time, having as pillars the same foundation of the future software engineering.
From this experience was also born the first series of articles dedicated to portability, written together with my colleagues:
I. Athanasiu, M. Necula, L. D. Serbanati, Program Portability. Automatics, Metrology, Computers, Vol. 20B, pp. 201–206, Technical Publishing House, Bucharest, 1975 (in Romanian).
In this first article about portability, I tried, along with Athanasiu and Necula, to put order in a field that, in practice, was treated only empirically. We started from simple but pressing questions:
what does it mean exactly for a program to be "portable"?
towards what exactly must it be independent: hardware, operating system, language, execution environment?
what are the real costs of portability?
The article represented an attempt to build a common vocabulary: we discussed types of portability (horizontal – between similar machines, vertical – between different generations of machines), typical barriers (specific instructions, call conventions, internal representations), as well as strategies for mitigating these barriers. The ideas came directly from our experiences with the compilers and tools existing in the laboratory, but in the article they were abstracted into a conceptual framework that could be reused.
Looking back, it was less a "spectacular" article and more one of positioning: it defined, in a language as systematic as possible, the problem I had proposed to attack in the following years.
L. D. Serbanati, M. Cosma, C. Popescu, M. Necula, BCPL – a Language for Program Writing. Automatics, Metrology, Computers, Vol. 24A-B, pp. 345–360, Technical Publishing House, Bucharest, 1976 (in Romanian).
L. D. Serbanati, Methods and techniques for ensuring program portability. Automatics, Metrology, Computers, Vol. 25, pp. 69–82, Technical Publishing House, Bucharest, 1977 (in Romanian).
I. Athanasiu, M. Necula, L. D. Serbanati, M. Cosma, C. Popescu, Comparative Study of some BCPL Compilers. Automatics, Metrology, Computers, Vol. 27, Technical Publishing House, Bucharest, 1978 (in Romanian).
Conclusion to the BCPL Experience
Looking as a whole, our BCPL laboratory had become, without necessarily aiming for it, a small "portability workshop". The punched tape, the INTCODE interpreter on FELIX, the BCPL compilers compared with each other – all these were both technical exercises and pretexts for building a conceptual framework about what it means, in practice, a portable program.
Macroprocessors for Ensuring Portability
STAGE-2
In the same period, I came into contact with another important piece of the "portability puzzle": STAGE-2, the universal macroprocessor developed by W. Waite. If BCPL and INTCODE represented the "abstract machine" and intermediate code component, STAGE-2 brought to the fore macroprocessing as a tool for building compilers and translators.
I received from Waite a generic version of STAGE-2 on magnetic tape and quite dense documentation. The central idea was fascinating: a universal macroprocessor that could be used for extending languages, text reformatting, code generation, and automation of complex transformations, all in a way independent of a specific language or software system. STAGE-2 was not thought of as an annex to an assembler or a compiler, but as a stand-alone program, capable of processing any text stream and producing another, based on a set of rewriting rules. The main characteristic of STAGE-2 is the half-bootstrap procedure for portable implementation. This research was part of a broader study on program portability.
In simple terms, a macroprocessor is a program that copies an input text stream and generates an output text stream, performing a systematic set of replacements and transformations along the way. Macro processors are often embedded in other programs, such as assemblers and compilers. Sometimes they are stand-alone programs that can be used to process any type of text. Macroprocessors have been used, from the beginning, for:
• language extension, by defining new constructs expressed in terms of existing structures; • systematic replacement of text fragments in situations involving decisions; • text reformatting, generation of repetitive code or program skeletons.
STAGE-2 took these ideas to a remarkable level of generality. It processes one line of characters at a time, matching it with previously specified patterns, and is almost completely independent of the character set: it only needs digits 0–9 to be contiguous and in order. This independence from the character set transformed it into an ideal tool for building machine-independent software.
As in the case of BCPL, Waite provided an easy implementation, on any computer, of the macroprocessor, using a portable half-bootstrap procedure: a minimal version of STAGE-2, sufficient to interpret a simplified description of the macroprocessor, was used to generate the full version, optimized for the concrete platform. As in the case of BCPL, Waite's procedure provided writing a minimal interpreter, which could execute a simplified version of STAGE-2, sufficient to produce the full version.
We started from the generic version received from Waite and, together with a few very good students, we performed on FELIX this half-bootstrap procedure: a simplified STAGE-2 "kernel", used to generate full STAGE-2.
This experience was important for two reasons:
- technically, it demonstrated that portability is not a passive property, but an active construction, which requires vision, adaptability and rigor;
- methodologically, it showed how a single tool — a universal macroprocessor — can become infrastructure for many other tools: compilers, translators, code generators.
Article regarding the experience gained from portability research with the STAGE-2 macroprocessor:
Specialized Macroprocessor for Software Development – L. D. Șerbănați, R. D. Bercaru, D. F. Mânduțianu, Automatics, Metrology, Computers, Vol. 27, pp. 103–115, Technical Publishing House, Bucharest, 1978 (in Romanian).
Starting from the experience with STAGE-2, I proposed here a specialized macroprocessor for software development. The idea was to build, on top of a general macroprocessor, a set of dedicated facilities: templates for typical compiler structures, descriptions of symbol tables, parameterizable code generators. The goal was to obtain an infrastructure that would make the development of portable tools easier and more systematic.
If STAGE-2 represented, in Waite's vision, a universal macroprocessor, this article marks a derivation towards a specialized tool for software development. The experience with STAGE-2, with bootstrap techniques and with the idea of building machine-independent software led me to the question: can we have a macroprocessor explicitly adapted to the needs of the development process, not just a general text processing tool?
In the paper I described the design and implementation of a specialized macroprocessor that:
- accepted descriptions oriented on typical program structures (code fragments, module templates, call conventions);
- integrated, as much as possible, the experience accumulated in the laboratory — for example, usual patterns of portable code generation;
- could be used as infrastructure for other tools, from code generators to development environment configuration tools.
The portable implementations of the BCPL language compiler and the STAGE-2 macroprocessor were developed together with the students. Around BCPL, INTCODE and STAGE-2 I gradually formed a small team dedicated to language and program portability, which included colleagues like Maria Ana Necula, Irina Athanasiu, and students like M. Cosma, C. Popescu, R. D. Bercaru, D. F. Mânduțianu and others. The work in the laboratory — writing the INTCODE interpreter, the bootstrap of the BCPL compiler, the implementation of STAGE-2 on FELIX — gradually transformed into articles that tried to structure our experience into a theoretical language accessible to the community. They were not simple technical exercises, but manifestations of a profound idea: that a program, like a human idea, should be able to survive and evolve beyond the circumstances of its birth.
STAGE-2 Vision
STAGE-2 was, for me, a bridge between the portability experience related to compilers and future concerns for modeling the design process: the idea of having a tool that "transforms texts" systematically, based on explicit rules, anticipated, in a way, the need to treat design as a succession of controlled transformations on intermediate forms.
Janus
An additional experience with portability was offered to me by another macroprocessor proposed by Waite, the last in chronological order: the implementation of Janus — a symbolic language used to encapsulate the information that is normally transmitted from the analysis phase of a compiler to the code generators. Unlike STAGE-2 which uses an abstract machine to implement a single source language on a variety of target architectures, Janus approaches the original UNCOL idea by defining the essential elements of an intermediate language independent of any source language or target architecture. Instead of offering a single abstract machine, Janus describes the common base structure (stack machine with index register) of an entire family of abstract machines, which differ through their instruction sets to adapt to the specific constructions of the source languages.
Janus was, therefore, designed for software "transport": a program encoded in a high-level language can be translated by Janus on one computer, and the result can be translated into assembly code on another (the STAGE-2 macroprocessor was to be used for the second translation). I proposed this theme to Dan Mânduțianu as a subject for his diploma thesis. Dan successfully completed the implementation, but, unfortunately, our studies stopped here, due to other projects appearing on the horizon.
These experiences shaped me not only as a computer scientist but also as a thinker: they taught me not to look at present limits as definitive frontiers, but as invitations to creation. The liberation of software from the shackles of hardware and operating systems was, in essence, but an expression of the liberation of thought — a first step on a long road, in which programming was no longer just a technique, but an art of liberation from restrictions.
Implementing the LPTR Language
In the following two years I set aside portability, but also the PhD thesis, to respond to other urgencies, such as the contract with ICI for the realization of the LPTR compiler for the new Romanian minicomputer Independent, a variant of the DEC PDP-11/34 minicomputer. LPTR (Limbaj Pentru Timp Real - Language For Real Time) constituted a slightly simplified version of the RTL/2 language (Real-Time Language), a language for real-time applications, which colleagues in ICI needed in the industrial process informatics laboratory.
Our contract with ICI lasted two years and provided for the realization of a compiler for a language compatible with RTL/2, which was to be included in the National Library of Programs (BNP), accessible to all interested agents in industry. At the end of the contractual period, the team from the Polytechnic, led by me, implemented LPTR, and the compiler was validated and deposited in BNP. Since then, I have had no more information about the fate of the compiler. Probably it was not adopted in industry — moreover, as happened with RTL/2, which, although standardized, died a natural death, as many unused software products.
For me, the LPTR contract meant forming and leading a team of colleagues and students for the design and implementation of the compiler. After small changes to the RTL/2 syntax, I brought the LPTR syntax to an LL(1) grammar, which allowed a descending syntactic analysis. The grammar was attributed, which allowed an elegant semantic analysis. Finally, code generation was done in MACRO, the assembly language of the target minicomputer INDEPENDENT. The entire compiler was written in the C language.
This experience brought me an important technical maturation and a new perspective on complex project management.
Conclusions on the Research Period 1970–1980
This period was fundamental in shaping my identity as a researcher and professor in the field of computer science. I lived in an interval of intense transition, when old rigid hardware paradigms began to be questioned by new software portability concepts and dynamic interaction with the computer.
My efforts were marked by a profound dedication to software autonomy, its liberation from hardware "shackles" and the development of methods and tools that made programming accessible and flexible, especially for young students at the beginning of their road. Experiences with systems like SISIF, languages like BCPL, and concepts like incremental compilation represented essential steps in this quest.
If at the beginning I dreamed of machines that would imitate man, in time I understood that the dignity of our profession stands not in imitation, but in the construction of contexts in which human intelligence can work more clearly, more rightly and more freely.
In the educational plan, I tried to transmit not just programming techniques, but a robust algorithmic thinking, forming "programmer minds" that understand the foundations, not just concrete languages. Even if the contradictions of the educational system and political compromises tempered this vision, I firmly believe that the proposed model remains relevant even today. Those years were an occasion of confrontation with methodological, technological and social limits, but also a source of valuable lessons about thought flexibility, collaboration and the importance of forming future generations.
Those years consolidated the conviction that the essence of computer science stands in creating a flexible and durable framework, which transforms programming from a simple technical act into an art of structural thinking and intelligent flexibility.
It was the decade in which I moved from hardware to ideas and communities — students, colleagues, laboratories — joining small efforts in a common architecture; and this architecture, whether I called it portability, attribute grammars or computer education, always had the same purpose: to transform technology from constraint into tool, from barrier into bridge, from noise into language. In that confused universe of tapes, cards and long nights of program running, patience was shaped, friendship was cemented and the conviction was born that software — like thought — becomes truly powerful only when it is understood, transportable, resumed and continued by others.
Looking back, the period 1970–1980 consecrates the beginning of a research road that was to evolve along with technological and social changes, but which was always anchored in that spirit of freedom, order and creativity that guided me since the beginning. This period is not less a succession of technical achievements as much as a journey through which ideas acquired form and durable meaning.





