Scopes and Modes: A System Approach to Building Software

We want to develop software that meets complex requirements but works seamlessly for the user. We have down the user’s task at hand into manageable pieces and then reconstruct them into a cohesive, efficient, and robust whole.

But here's the intriguing part: for all user tasks exist two distinct modes of thinking, each crucial to the success of the endeavor. It's like having two hats to wear, one for diving into the nitty-gritty and sweating the details, and another for exploring possibilities and unleashing your innovation.

Let’s get started with breaking down the user’s task into manageable pieces.

Scopes: Levels of Abstraction

When coding, writing or doing any other “craft”, we work on different levels. A writer can focus on words, sentences, paragraphs, sections, or the entire essay. A programmer can zoom in on statements, functions/modules, classes, or the entire program. We are looking at a certain scope of the system. It is a point of view, we are placing ourselves in.

When we develop software that caters to programmers or writers, we have to consider the scope they are working in.

In system design, the levels of abstraction can be categorized as follows:

  1. System Level: At the system level, we take a step back and look at the big picture. Imagine you are an explorer discovering a new land. You want to understand the lay of the land, its major features, and how it interacts with the surrounding environment. You observe the overall landscape, rivers, mountains, and the relationships between them. Similarly, at the system level, we focus on the overall system and its interactions with external entities. We identify the system's objectives, requirements, and high-level architecture, just like a landscape overview.

  2. Subsystem Level: Now, let's zoom in and explore a specific region within the land. Think of a city within the newly discovered land. Within the city, you encounter different neighborhoods or districts, each with its own distinct characteristics and functions. These neighborhoods are interconnected, with well-defined paths or roads connecting them. Similarly, at the subsystem level, we decompose the system into smaller subsystems or modules. Each subsystem is responsible for specific functions or services, like the neighborhoods in the city. They have defined interfaces that allow them to communicate and work together, just like the roads connecting the neighborhoods.

  3. Component Level: Within each neighborhood of the city, you find individual buildings or structures that serve specific purposes. Each building represents a component of the system. For example, there might be a school building, a hospital, or a residential complex. Components are like the building blocks of the system. They encapsulate specific functionality and can be implemented as software modules, hardware devices, or a combination. Components are designed to be reusable, maintainable, and replaceable, just like different buildings in a city.

  4. Module Level: Now let's enter one of the buildings within a neighborhood. Inside the building, you find different rooms or areas dedicated to specific activities. Each room represents a module within a component. For instance, within a school building, you might have classrooms, laboratories, and administrative offices. Modules represent cohesive units of functionality. They are designed to encapsulate a specific set of related tasks or operations, just like the rooms within a building.

  5. Unit Level: Finally, let's step into one of the classrooms in the school building. Here, you observe the students engaging in different activities, following specific instructions from their teachers. The students represent units and the teachers' instructions represent the relationships and interactions that guide the system's behavior. At the unit level, we delve into the detailed implementation of the system. This level deals with the nitty-gritty details of executing the system's functions.

When we develop software, we have to think about what level of abstraction the user is working on. If it’s multiple, we have to enable them all.

Modes: The Two Types of Work

Most types of work can be split into two phases:

  1. Implement

  2. Evaluate

Writing consists of composition and editing, programming of coding and debugging, design of sketching and refining, and photography of capturing and editing,…

We are iterating back and forth between implementation and evaluation.

These two modes, implementation and evaluation, are inseparable. They represent the yin and yang, the creative and analytical forces that propel the user towards an output he can be proud of.

These two types of work often required two very distinct frames of mind. When we are implementing, we concentrate on the smallest detail. We craft new sentences, new lines of code. We sweat the details, meticulously crafting solutions that address every specific requirement.

When we are evaluating, we are taking a step back. How does the newly created thing fit into the larger scheme of things? How do the new lines of code connect to my program, how does the new sentence fit into the paragraph or essay? This mode demands creativity, an open mind, and the willingness to push boundaries. Like an explorer venturing into uncharted territory, we step back and look at the bigger picture.

Software programs should reflect this duality.

Let the user pick whether he wants to implement or evaluate. In the best case, you can recognize, what mode he is going for. Then give him the appropriate tools for the task at hand.

How to Put it Together in Software

The easiest way to think about it is as a flowchart. We are moving from the system level to the unit level. In each step, we are iterating between implementing and evaluating.

At each level of scope, we can implement or evaluate.

When we think about the task at hand as a system, we can break it down into its scopes and then its fundamental operations.

Let’s Break it Down for a Writing

Imagine we are coding a new writing software. An editor powered by AI.

Let’s break it down from the user’s perspective:

  1. At the system level, we start with the entire essay as our scope. We implement by generating an outline with headings and sub-headings, capturing the overall structure of our thoughts. We evaluate by considering whether to re-order sections, delete redundant parts, insert new ideas, or make changes to improve the flow and coherence of the essay.

  2. Moving to the subsystem level, we focus on each section of the essay, which contains several ideas or arguments. Here, we implement by generating ideas and points to address within each sub-heading, capturing the essence of our thoughts. We evaluate by assessing the logical progression of ideas, considering whether to re-order, delete, insert, or modify them for better clarity and coherence.

  3. As we zoom in further to the component level, we reach the paragraph level. Here, we implement by writing sentences that support and develop the ideas presented within each section. We refine our writing by evaluating whether sentences need re-ordering, deletion, insertion, or modification to enhance their impact and effectiveness in conveying our message.

  4. Continuing to the module level, we focus on crafting individual sentences that convey specific points or arguments. Here, our implementation involves selecting the right words and structuring sentences to articulate our thoughts clearly. We evaluate each sentence, considering whether it aligns with our intended meaning, requires rephrasing, or needs adjustments to improve its coherence and effectiveness in conveying the desired message.You can see an example of that in our last essay, where we explored how we can show clear feedback with a git-like interface.

  5. Finally, at the unit level, we immerse ourselves in the fundamental operation of writing: selecting the precise words and expressions to convey our ideas. We implement by choosing words that accurately capture our intended meaning and communicate effectively to the reader. We evaluate by carefully considering each word, deleting unnecessary ones, making changes to improve clarity, and ensuring the overall impact of our writing.

If we are developing writing software, we should enable all these operations. And we should make it easy for the user to switch between the different modes. The user can navigate the different levels of abstraction from the system level to the unit level.

Sources

Reply

or to participate.