scieee AI-readable full text Open interactive document viewer

Three Foundational Ideas That Shaped Software Engineering

Dutta, Abhishek

Abstract

Alfred North Whitehead once remarked, "Civilization advances by extending the number of important operations which we can perform without thinking about them." This talk explores three foundational research papers in software engineering – each more than half a century old – that have shaped how we design, reason about, and collaborate on large-scale software systems. These works have enabled programmers to operate at higher levels of abstraction, leading to scalable and intelligible software development. The first paper, by D. L. Parnas (1972), introduced the principle of "information hiding" for decomposing a large scale software project into modules which have an interface that reveal as little as possible about its inner workings. This approach allows for independent evolution of components, improving both maintainability and clarity. Inspired by this idea, B. Liskov and S. Zilles (1974) later formalized the concept of Abstract Data Types (ADTs), enabling programmers to reason about data structures through well-defined operations rather than through a long sequence of low level machine instructions to fetch, update and store smaller units of a data structure. Together, these ideas laid the groundwork for building complex software systems using composable and comprehensible modules. The second group of papers liberated programmers from the need to consume "spaghetti" code generated by the need to sprinkle "go to" statements in a program code to realise desirable control flow. Böhm and Jacopini (1966) mathematically proved that any computable function can be implemented using just three control structures: sequence, selection (e.g. if … else), and repetition (e.g. for loop). This formal result supported E. W. Dijkstra’s (1968) influential call to abolish "go to statement" from "everything except … plain machine code". Although high-level constructs like loops and conditionals are still compiled to low-level jumps (e.g., JMP), these papers empowered developers to operate at a higher level of abstraction where control flow of a computer program was more intelligible. The third set of papers were intended to address the challenge of modelling and understanding naturally occurring complex processes. "How complex or simple a structure is depends critically upon the way in which we describe it." wrote H. A. Simon (1962) to make a case for finding the "right representation" to describe complex systems. Simon’s key insight was to view a complex system as a hierarchical structure composed of subsystems (or modules) which interact more internally than externally. Subsystems at higher levels were derived from subsystems operating at lower levels of the hierarchy. To model real-world processes, Dahl and Nygaard (1967) pioneered object-oriented modeling by representing processes as a set of interacting objects – each encapsulating state and behavior—and organizing them hierarchically through inheritance. These insights emphasized modularity, hierarchy, and abstraction as essential tools for managing complexity and continue to underpin modern programming paradigms. [ References ] Herbert, Simon. "The architecture of complexity." Proceedings of the American Philosophical Society 106, no. 6 (1962): 467-482.Simon, Herbert A. “The Architecture of Complexity: Hierarchic Systems”. In The Sciences of the Artificial, 183–216, MIT Press, 2019.Parnas, David L. “On the Criteria to Be Used in Decomposing Systems into Modules”. In Software fundamentals: collected papers by David L. Parnas, Addison-Wesley, 2001.Parnas, David L. "On the criteria to be used in decomposing systems into modules." Communications of the ACM 15.12 (1972): 1053-1058.Dijkstra, Edsger W. "Letters to the editor: go to statement considered harmful." Communications of the ACM 11, no. 3 (1968): 147-148.Böhm, Corrado, and Giuseppe Jacopini. "Flow diagrams, turing machines and languages with only two formation rules." Communications of the ACM 9, no. 5 (1966): 366-371.Liskov, Barbara, and Stephen Zilles. "Programming with abstract data types." ACM Sigplan Notices 9, no. 4 (1974): 50-59.Dahl, O.-J., & Nygaard, K. “Class and subclass declarations.”, Norwegian Computing Center, presented at IFIP Working Conference on Simulation Languages, Oslo, May 1967 . (1967).

Full text

Three Foundational Ideas That Shaped Software Engineering Talk at the 3rd Annual Conference of the US Research Software Engineer Association, Philadelphia (USA), Oct 7, 2025. [email protected] Dr. Abhishek Dutta Principal Research Software Engineer University of Oxford Foundational Idea 1 replace: push rbp mov rbp, rsp mov al, dl mov cl, sil mov qword ptr [rbp - 8], rdi mov byte ptr [rbp - 9], cl mov byte ptr [rbp - 10], al mov dword ptr [rbp - 16], 0 .LBB0_1: mov eax, dword ptr [rbp - 16] mov ecx, eax mov rdx, qword ptr [rbp - 8] movsx eax, byte ptr [rdx + rcx] cmp eax, 0 je .LBB0_6 mov eax, dword ptr [rbp - 16] mov ecx, eax mov rdx, qword ptr [rbp - 8] movsx eax, byte ptr [rdx + rcx] movsx esi, byte ptr [rbp - 9] cmp eax, esi jne .LBB0_4 mov al, byte ptr [rbp - 10] mov ecx, dword ptr [rbp - 16] mov edx, ecx mov rsi, qword ptr [rbp - 8] mov byte ptr [rsi + rdx], al .LBB0_4: jmp .LBB0_5 .LBB0_5: mov eax, dword ptr [rbp - 16] add eax, 1 mov dword ptr [rbp - 16], eax jmp .LBB0_1 .LBB0_6: pop rbp ret An example program (i.e. sequence of machine instructions) to replace all occurrences of a character in a string with a new character Assembly code generated using https://godbolt.org/ replace: push rbp mov rbp, rsp mov al, dl mov cl, sil mov qword ptr [rbp - 8], rdi mov byte ptr [rbp - 9], cl mov byte ptr [rbp - 10], al mov dword ptr [rbp - 16], 0 .LBB0_1: mov eax, dword ptr [rbp - 16] mov ecx, eax mov rdx, qword ptr [rbp - 8] movsx eax, byte ptr [rdx + rcx] cmp eax, 0 je .LBB0_6 mov eax, dword ptr [rbp - 16] mov ecx, eax mov rdx, qword ptr [rbp - 8] movsx eax, byte ptr [rdx + rcx] movsx esi, byte ptr [rbp - 9] cmp eax, esi jne .LBB0_4 mov al, byte ptr [rbp - 10] mov ecx, dword ptr [rbp - 16] mov edx, ecx mov rsi, qword ptr [rbp - 8] mov byte ptr [rsi + rdx], al .LBB0_4: jmp .LBB0_5 .LBB0_5: mov eax, dword ptr [rbp - 16] add eax, 1 mov dword ptr [rbp - 16], eax jmp .LBB0_1 .LBB0_6: pop rbp ret An example program (i.e. sequence of machine instructions) to replace all occurrences of a character in a string with a new character replace: push rbp mov rbp, rsp mov al, dl mov cl, sil mov qword ptr [rbp - 8], rdi mov byte ptr [rbp - 9], cl mov byte ptr [rbp - 10], al mov dword ptr [rbp - 16], 0 .LBB0_1: mov eax, dword ptr [rbp - 16] mov ecx, eax mov rdx, qword ptr [rbp - 8] movsx eax, byte ptr [rdx + rcx] cmp eax, 0 je .LBB0_6 mov eax, dword ptr [rbp - 16] mov ecx, eax mov rdx, qword ptr [rbp - 8] movsx eax, byte ptr [rdx + rcx] movsx esi, byte ptr [rbp - 9] cmp eax, esi jne .LBB0_4 mov al, byte ptr [rbp - 10] mov ecx, dword ptr [rbp - 16] mov edx, ecx mov rsi, qword ptr [rbp - 8] mov byte ptr [rsi + rdx], al .LBB0_4: jmp .LBB0_5 .LBB0_5: mov eax, dword ptr [rbp - 16] add eax, 1 mov dword ptr [rbp - 16], eax jmp .LBB0_1 .LBB0_6: pop rbp ret replace: push rbp mov rbp, rsp mov al, dl mov cl, sil mov qword ptr [rbp - 8], rdi mov byte ptr [rbp - 9], cl mov byte ptr [rbp - 10], al mov dword ptr [rbp - 16], 0 .LBB0_1: mov eax, dword ptr [rbp - 16] mov ecx, eax mov rdx, qword ptr [rbp - 8] movsx eax, byte ptr [rdx + rcx] cmp eax, 0 je .LBB0_6 mov eax, dword ptr [rbp - 16] mov ecx, eax mov rdx, qword ptr [rbp - 8] movsx eax, byte ptr [rdx + rcx] movsx esi, byte ptr [rbp - 9] cmp eax, esi jne .LBB0_4 mov al, byte ptr [rbp - 10] mov ecx, dword ptr [rbp - 16] mov edx, ecx mov rsi, qword ptr [rbp - 8] mov byte ptr [rsi + rdx], al .LBB0_4: jmp .LBB0_5 .LBB0_5: mov eax, dword ptr [rbp - 16] add eax, 1 mov dword ptr [rbp - 16], eax jmp .LBB0_1 .LBB0_6: pop rbp ret Loop Branching Böhm and Jacopini (1966) mathematically proved that any computable function can be implemented using just three control structures: ●Sequence of instructions ●Selection (e.g. if … else) ●Repetition (e.g. for loop) Information Hiding ●Decompose a large scale system into modules which have an interface that reveal as little as possible about its inner workings Module Parnas, David L. "On the criteria to be used in decomposing systems into modules." Communications of the ACM 15.12 (1972): 1053-1058. Interface External users can benefit from the services offered by this module without needing to understand its internal operational details. A large scale system can be developed and understood in terms of these modules. Information Hiding ●Inspired by the idea of information hiding, B. Liskov and S. Zilles (1974) formalised the concept of Abstract Data Types (ADT) –Enables programmers to reason about data structures through welldefined operations rather than through a long sequence of low level machine instructions to fetch, update and store smaller units of a data structure Liskov, Barbara, and Stephen Zilles. "Programming with abstract data types." ACM Sigplan Notices 9, no. 4 (1974): 50-59. Stack Push() Pop() Information Hiding ●Inspired by the idea of information hiding, B. Liskov and S. Zilles (1974) formalised the concept of Abstract Data Types (ADT) –Enables programmers to reason about data structures through welldefined operations rather than through a long sequence of low level machine instructions to fetch, update and store smaller units of a data structure Liskov, Barbara, and Stephen Zilles. "Programming with abstract data types." ACM Sigplan Notices 9, no. 4 (1974): 50-59. Stack Push() Pop() Stack Push() Pop() Interface Together, these ideas laid the groundwork for building complex software systems using composable and comprehensible modules. Structured Programming (1966) Information Hiding (1972) Foundational Idea 3 How complex or simple a structure is depends critically upon the way in which we describe it. – H. A. Simon (1962) Systems are not inherently simple or complex. The way we describe a system makes it simple or complex. How complex or simple a structure is depends critically upon the way in which we describe it. – H. A. Simon (1962) What is the “right representation” to describe complex systems? How complex or simple a structure is depends critically upon the way in which we describe it. – H. A. Simon (1962) What is the “right representation” to describe complex systems? Turing Award (1975) Nobel Prize in Economics (1978) Hierarchical Representation ●H. A. Simon’s key insight was to view a complex system as a hierarchical structure composed of subsystems (or modules) which interact more internally than externally. Module A Module B Herbert, Simon. "The architecture of complexity." Proceedings of the American Philosophical Society 106, no. 6 (1962): 467-482. Hierarchical Representation ●H. A. Simon’s key insight was to view a complex system as a hierarchical structure composed of subsystems (or modules) which interact more internally than externally. ●Subsystems at higher levels were derived from subsystems operating at lower levels of the hierarchy Riesenhuber, Maximilian, and Tomaso Poggio. "Hierarchical models of object recognition in cortex." Nature Neuroscience 1999 Simonyan, Karen, and Andrew Zisserman. "Very deep convolutional networks for large-scale image recognition." 2014 When you write code, it is highly likely that you are using these concepts without thinking about them. These ideas were not available 75 years ago when computer programming was evolving. What is the next thing that is currently not obvious to us but will become so for future generations? What is the next thing that is currently not obvious to us but will become so for future generations? ●In the past, both writing and reading computer code was challenging. ●Now with code LLM, writing code is becoming less challenging but understanding and debugging existing code is still laborious. ●It is highly likely that we will find novel ways to represent large corpus of code in a form that will be easier to understand, debug and extend. Thank you