关于: "philosophy":

Prompt=RFP

很多人刚接触 AI 时,总觉得 prompt 是一种魔法:只要说对了话,机器就会做出惊人的事情。现实却更平凡——也是更有趣的。Prompt 并不是咒语,它是一份规范。而任何规范,都有写得好与写得差的区别。写得好,会改变整个游戏规则。一个行之有效的方法,是把 prompt 当作 RFP(Request for Proposal,征求建议书) 来写。

一开始,这听起来似乎有些过于正式:prompt 不过是几句话,为什么要写得像征求建议书?答案很简单:任何复杂系统都只有在输入结构化的情况下,才会表现得可预测。写得模糊的 prompt,就像给承包商下了一个含糊的任务:事情总会做,但你得到的结果可能不尽如人意,还浪费时间。将 prompt 写成 RFP,可以让你更可控、更可重复,也更容易评估效果。

核心思想是把 prompt 模块化,分成五个部分,每个部分回答一个明确的问题。第一部分是 身份与目的(Identity & Purpose)。谁在使用这个 prompt?想达到什么目标?很多人觉得没必要告诉 AI 这些,毕竟它不需要知道你的职位或心情,对吧?但事实证明,背景信息很重要。一个适合数据分析师的 prompt,用在小说创作上可能就会出问题。身份和目的就像告诉承包商:“你在建桥,不是在做鸟屋。”它给 AI 的思路提供了约束。

第二部分是 背景 / 上下文(Context / Background)。这里提供 AI 需要知道的已有信息。可以把它理解为“你已经知道什么”。没有背景,AI 可能会重新发明轮子,或者给出与先前假设相矛盾的答案。背景可以是之前的对话内容、专业知识、数据集,或者任何能让任务落地的信息。原则很简单:系统不喜欢模糊,人类也不喜欢。想象一个城市规划的承包商,如果你没交代地形、人口、地势,那结果几乎必然是乱象丛生。

第三部分是 操作步骤(Steps / Instructions),这是 RFP 的核心。这里要明确告诉 AI 具体做什么、怎么做、顺序如何。是让它总结?翻译?比较?列清单?关键是具体但不死板。这在软件设计里也类似:明确输入、处理和输出。指令模糊,结果模糊;指令详细、模块化,结果可靠可用、可测试、可扩展。操作步骤还可以包括方法、风格、推理约束,例如“用五岁孩子能懂的方式解释”或“以简洁为主”。这就像 API 合约:明确双方预期。

第四部分是 输出格式 / 限制(Output Format / Constraints)。这部分的作用更像软件的接口。如果不指定输出格式,答案可能正确,但无法直接使用。你可能需要列表、JSON、表格、文章;可能要求数字保留小数点两位;可能要求每条清单都有引用。这些约束减少后处理工作,降低出错概率,也便于评估。在我经验里,这是很多程序员最容易忽视的部分。没有输出规范,就像建了座漂亮桥却架在河边——完美,但没用。

第五部分是 评估与价值(Evaluation / Value)。这个 prompt 为什么存在?怎么判断它成功了?RFP 总有评价标准:成本、时间、性能。Prompt RFP 同样应该说明什么算有价值,如何验证结果。是正确就行,还是需要创意?完整性重要还是可读性重要?提前定义评估标准,会影响前面部分的写法:上下文、步骤、约束都可以针对可量化目标优化。更重要的是,它让迭代变得容易:你不必让 AI 无止境地“再来一次”,只需调整 RFP 中哪一模块有问题。

将 prompt 写成 RFP,还有一个深层次的好处:它迫使人类理清自己的思路。很多时候,我们问 AI 问题,是因为自己还没想明白。通过 Identity / Context / Steps / Output / Evaluation 这样的模块化结构,我们不仅在指导 AI,也在整理自己的想法。这类似 Paul Graham 写代码的经验:写代码本身就是思考的工具。高质量的 RFP prompt,对人类的帮助甚至比对机器的更大。

这种方法也容易扩展。如果你同时使用多个 AI agent,或者构建人机协作流程,RFP 模块化让你可以复用部分内容,比如调整上下文或输出格式而不改全部指令。软件工程里叫函数库,我们这里也是同理。你不仅解决一个问题,还建立了可扩展的框架。

举个例子:你想让 AI 写一份新品咖啡机的产品简介。随便写的 prompt 可能是“写一份咖啡机产品简介”,得到的结果大多泛泛。但如果按 RFP 写:

  • 身份与目的:你是消费电子创业公司的产品经理,需要一份设计与营销团队可用的产品简介。

  • 背景 / 上下文:公司已有两款咖啡机,包括市场反响、目标人群、技术规格。

  • 操作步骤:总结产品目标、主要功能、设计重点、预期零售价。

  • 输出格式 / 限制:文档结构为概览、功能、设计说明、市场定位,每个功能用项目符号,内容不超过 100 字。

  • 评估与价值:文档完整、逻辑清晰,符合公司定位,审阅者无需额外解释。

差别显而易见。一个是粗略草稿,一个是可直接使用的产物。更妙的是,RFP 的模块化意味着你只需要调整上下文或输出格式,就能适应新的任务,无需重写整个 prompt。

更广泛地说,prompt 并非无序的文字游戏,它们是人类语言写成的软件规范。认真、模块化、结构化书写 prompt,你就不再依赖运气,而是掌控了流程。写 RFP 风格的 prompt,是对自己和 AI 都有益的习惯:思考清楚、沟通清楚、获得有价值的输出。

总结一下,RFP prompt 的五个模块带来的价值:

  1. 身份与目的:明确使用者和目标,让 AI 理解任务定位;

  2. 上下文 / 背景:提供信息基础,让回答有据可依;

  3. 操作步骤:定义流程,让输出可预测、可测试;

  4. 输出格式 / 限制:规范接口,让结果可用、可复用;

  5. 评估与价值:确定成功标准,让迭代有效、价值明确。

正如软件设计强调模块化、契约与清晰逻辑,RFP 风格的 prompt 同样让 AI 不再是黑箱,而是可以推理、可以规划、可以协作的伙伴。写这样的 prompt,你不仅获得更好的结果,更会在写作的过程中理清自己的思路,让人机协作真正高效。


n5321 | 2026年1月30日 14:37

The Nature of Software

松井行弘曾经说过,软件本质上就是“数据和指令”。这句话听起来简单,但如果你真正深入思考,你会发现其中隐藏着对整个软件世界的基本洞察。软件不是魔法,也不是一个黑箱,而是数据和操作数据的规则的组合。程序员的工作,本质上就是在设计这些规则,并确保数据沿着预期的路径流动。

在任何一个程序里,数据和指令之间都存在一种紧密的互动关系。数据本身没有意义,除非有指令去操作它;指令没有价值,除非它能作用于某种数据。举个简单的例子,一个排序算法就是一组指令,它的意义在于它能够将数据按照某种顺序重新组织。当我们看到软件崩溃、bug 或者不可预期行为时,其实发生的问题往往是数据和指令之间的错位——数据没有按预期被操作,或者指令被应用在了错误的数据上。

理解了软件的基本构成之后,下一步就是考虑如何组织这些数据和指令,使得系统更可维护、更可扩展、更可靠。这就是设计模式(Design Patterns)出现的地方。设计模式给我们提供了一种“组件化”的思路。每个模式都是一个经过验证的结构或交互方式,它定义了系统中各个组件的角色以及它们之间的通信方式。

在组件化的设计中,每个组件都承担特定的职责。比如在 MVC 模式中,Model 管理数据和业务逻辑,View 负责显示界面,Controller 处理用户输入。各个组件之间通过清晰的接口进行交互,从而降低耦合,提高系统的可理解性。组件之间的交互往往决定了整个系统的行为:如果交互混乱,即便每个组件单独设计得再完美,整个系统依然难以维护。换句话说,软件的复杂性往往不是来自单个组件的复杂,而是来自组件之间关系的复杂。

在分析这些组件和它们的互动时,我想起了 Peter Drucker 对管理学的洞察。Drucker 曾经说,管理的核心元素是决策(decision)、行动(action)和行为(behavior)。如果把软件系统比作一个组织,那么每个组件就是组织中的一个部门,每个决策就是指令,每个行动就是对数据的操作,而行为则是系统整体的运行方式。软件设计与管理分析之间的类比并非偶然:无论是组织还是程序,复杂系统都依赖于如何协调内部元素的决策与行为。

理解了组件、决策与行为的关系之后,我们就自然走向了 UML(统一建模语言)的方法论。UML 是一种描述系统结构和行为的语言,它将软件世界拆分为两类图:状态图(State)和行为图(Behavior)。状态图关注对象在生命周期中的不同状态以及状态之间的转换,它回答“一个对象在什么情况下会做出什么变化”。行为图关注系统在某个特定时刻的活动和交互,它回答“系统是如何完成特定任务的”。通过这种方式,UML 提供了一种形式化的视角,让我们可以在代码实现之前,先理清软件的结构和动态行为。

如果回到松井行弘的观点,我们可以看到 UML 图实际上是在把“数据和指令”抽象化,形成可视化模型。状态图对应数据的状态变化,行为图对应指令执行的流程。当我们在设计模式中定义组件和接口时,这些 UML 图就能帮助我们预测组件交互的后果。结合 Drucker 的分析方法,我们甚至可以将系统建模成一个“决策—行为—结果”的闭环。每一次用户操作(决策)触发组件间的交互(行为),最终影响数据状态(结果),形成软件运行的完整逻辑。

更有意思的是,这种思路不仅适用于大型系统,也适用于小型程序。即便是一个简单的记账应用,它内部也有数据(账目)、指令(增删改查操作)、组件(界面、数据库访问层、逻辑处理层),以及行为和状态(余额变化、报表生成)。理解软件的本质,让我们可以在任何规模上进行更高效的设计。

在实践中,很多程序员往往倾向于直接写代码而不做抽象建模,这就像一个组织没有明确的决策流程,只凭临时行动运营一样。初期可能运作正常,但随着规模扩大,混乱必然出现。而 UML 和设计模式提供了一种思考工具,让我们在编码之前就能设计好组件、交互和行为逻辑,降低后期维护成本。

从另一个角度看,软件的本质决定了它既是科学又是艺术。科学在于它遵循逻辑:数据和指令必须精确对应,每个状态变化必须可预测;艺术在于它的组织和表现方式:组件如何组合、接口如何设计、交互如何流畅,都影响最终系统的可用性和美感。正如 Paul Graham 常说的,好的软件就像写作,代码不仅要能执行,还要易于理解,甚至带有某种“优雅感”。

所以,当我们理解软件从“数据和指令”,到“组件和交互”,再到“状态和行为”的全貌时,就会意识到:软件并不仅仅是代码的堆砌,它是一个动态的系统,一个有行为的世界。每一个设计决策、每一个模式选择、每一个状态转换,都像是一个组织中管理者的决策——最终决定了系统的表现和可持续性。

总结来说,软件的本质可以概括为三个层次:

  1. 基础层:数据和指令,这是软件的原子元素;

  2. 组织层:组件和交互,这决定了系统的结构和模块间的协作;

  3. 行为层:状态和行为,反映系统动态演化和用户感知的功能。

理解这三层,并能够在设计中自觉应用 UML 和设计模式,不仅能让我们写出功能完整的程序,更能让我们写出优雅、可维护、可扩展的软件系统。正如管理学分析复杂组织的方法可以提高企业效率一样,软件设计的这些工具和方法可以让我们掌握软件的复杂性,创造出真正有价值的产品。


n5321 | 2026年1月30日 12:32

mermaid code

cd mermaid-live-editor

pnpm dev --open


n5321 | 2025年12月10日 09:18

UML 图的所有类别


UML 分为 结构图 + 行为图 两大类。


🧱 一、结构图(Structure Diagrams)——描述系统静态结构

这些图用来表示类、模块、系统组件之间的关系。

1. 类图(Class Diagram)

  • 最常用

  • 展示类、属性、方法、继承、关联、聚合、组合等

2. 对象图(Object Diagram)

  • 是类图的“实例化快照”

  • 展示对象之间当时的关系

3. 组件图(Component Diagram)

  • 描述系统如何分成不同组件(DLL、模块、包等)

4. 部署图(Deployment Diagram)

  • 展示系统在服务器、硬件上的部署情况

  • 如:Web server、DB server、负载均衡

5. 包图(Package Diagram)

  • 显示模块/包之间的依赖关系

6. 复合结构图(Composite Structure Diagram)

  • 表示内部结构,如类内部部件、端口、连接器

7. 剖面图(Profile Diagram)

  • 定义 UML 扩展(刻板构造、标签、元信息)


⚙️ 二、行为图(Behavior Diagrams)——描述系统行为与流程

这些图表示系统的动态动作、逻辑控制、状态转移等。

1. 用例图(Use Case Diagram)

  • 展示用户(Actor)如何与系统交互

  • 需求阶段常用

2. 活动图(Activity Diagram)

  • 类似流程图

  • 用来描述业务流程、算法内部逻辑

3. 状态机图(State Machine Diagram)

  • 描述对象/系统的状态变化

  • 常用于嵌入式、电机控制、协议机

4. 序列图(Sequence Diagram)

  • 展示对象之间按时间先后的消息交互

  • 最常用的行为图之一

5. 通信图(Communication Diagram)

  • 展示对象间的消息传递(更强调关系网络)

6. 交互概览图(Interaction Overview Diagram)

  • 活动图 + 序列图的结合

  • 用于大型流程展示

7. 时序图(Timing Diagram)

  • 用时间轴展示状态变化

  • 在硬件/协议中常用


📝 UML 全目录总结(备查用)

结构图(7)

  1. Class Diagram 类图

  2. Object Diagram 对象图

  3. Component Diagram 组件图

  4. Deployment Diagram 部署图

  5. Package Diagram 包图

  6. Composite Structure Diagram 复合结构图

  7. Profile Diagram 剖面图

行为图(7)

  1. Use Case Diagram 用例图

  2. Activity Diagram 活动图

  3. State Machine Diagram 状态机图

  4. Sequence Diagram 序列图

  5. Communication Diagram 通信图

  6. Interaction Overview Diagram 交互概览图

  7. Timing Diagram 时序图


n5321 | 2025年12月10日 09:16

Programming as Theory Building

Peter Naur 1985

Peter Naur’s classic 1985 essay “Programming as Theory Building” argues that a program is not its source code. A program is a shared mental construct (he uses the word theory) that lives in the minds of the people who work on it. If you lose the people, you lose the program. The code is merely a written representation of the program, and it’s lossy, so you can’t reconstruct a program from its code.

Introduction

The present discussion is a contribution to the understanding of what programming is. It suggests that programming properly should be regarded as an activity by which the programmers form or achieve a certain kind of insight, a theory, of the matters at hand. This suggestion is in contrast to what appears to be a more common notion, that programming should be regarded as a production of a program and certain other texts.

Some of the background of the views presented here is to be found in certain observations of what actually happens to programs and the teams of programmers dealing with them, particularly in situations arising from unexpected and perhaps erroneous program executions or reactions, and on the occasion of modifications of programs. The difficulty of accommodating such observations in a production view of programming suggests that this view is misleading. The theory building view is presented as an alternative.

A more general background of the presentation is a conviction that it is important to have an appropriate understanding of what programming is. If our understanding is inappropriate we will misunderstand the difficulties that arise in the activity and our attempts to overcome them will give rise to conflicts and frustrations.

In the present discussion some of the crucial background experience will first be outlined. This is followed by an explanation of a theory of what programming is, denoted the Theory Building View. The subsequent sections enter into some of the consequences of the Theory Building View.

Programming and the Programmers’ Knowledge

I shall use the word programming to denote the whole activity of design and implementation of programmed solutions. What I am concerned with is the activity of matching some significant part and aspect of an activity in the real world to the formal symbol manipulation that can be done by a program running on a computer. With such a notion it follows directly that the programming activity I am talking about must include the development in time corresponding to the changes taking place in the real world activity being matched by the program execution, in other words program modifications.

One way of stating the main point I want to make is that programming in this sense primarily must be the programmers’ building up knowledge of a certain kind, knowledge taken to be basically the programmers’ immediate possession, any documentation being an auxiliary, secondary product.

As a background of the further elaboration of this view given in the following sections, the remainder of the present section will describe some real experience of dealing with large programs that has seemed to me more and more significant as I have pondered over the problems. In either case the experience is my own or has been communicated to me by persons having first hand contact with the activity in question.

Case 1 concerns a compiler. It has been developed by a group A for a Language L and worked very well on computer X. Now another group B has the task to write a compiler for a language L + M, a modest extension of L, for computer Y . Group B decides that the compiler for L developed by group A will be a good starting point for their design, and get a contract with group A that they will get support in the form of full documentation, including annotated program texts and much additional written design discussion, and also personal advice. The arrangement was effective and group B managed to develop the compiler they wanted. In the present context the significant issue is the importance of the personal advice from group A in the matters that concerned how to implement the extensions M to the language. During the design phase group B made suggestions for the manner in which the extensions should be accommodated and submitted them to group A for review. In several major cases it turned out that the solutions suggested by group B were found by group A to make no use of the facilities that were not only inherent in the structure of the existing compiler but were discussed at length in its documentation, and to be based instead on additions to that structure in the form of patches that effectively destroyed its power and simplicity. The members of group A were able to spot these cases instantly and could propose simple and effective solutions, framed entirely within the existing structure. This is an example of how the full program text and additional documentation is insufficient in conveying to even the highly motivated group B the deeper insight into the design, that theory which is immediately present to the members of group A.

In the years following these events the compiler developed by group B was taken over by other programmers of the same organization, without guidance from group A. Information obtained by a member of group A about the compiler resulting from the further modification of it after about 10 years made it clear that at that later stage the original powerful structure was still visible, but made entirely ineffective by amorphous additions of many different kinds. Thus, again, the program text and its documentation has proved insufficient as a carrier of some of the most important design ideas.

Case 2 concerns the installation and fault diagnosis of a large real–time system for monitoring industrial production activities. The system is marketed by its producer, each delivery of the system being adapted individually to its specific environment of sensors and display devices. The size of the program delivered in each installation is of the order of 200,000 lines. The relevant experience from the way this kind of system is handled concerns the role and manner of work of the group of installation and fault finding programmers. The facts are, first that these programmers have been closely concerned with the system as a full time occupation over a period of several years, from the time the system was under design. Second, when diagnosing a fault these programmers rely almost exclusively on their ready knowledge of the system and the annotated program text, and are unable to conceive of any kind of additional documentation that would be useful to them. Third, other programmers’ groups who are responsible for the operation of particular installations of the system, and thus receive documentation of the system and full guidance on its use from the producer’s staff, regularly encounter difficulties that upon consultation with the producer’s installation and fault finding programmer are traced to inadequate understanding of the existing documentation, but which can be cleared up easily by the installation and fault finding programmers.

The conclusion seems inescapable that at least with certain kinds of large programs, the continued adaption, modification, and correction of errors in them, is essentially dependent on a certain kind of knowledge possessed by a group of programmers who are closely and continuously connected with them.

Ryle’s Notion of Theory

If it is granted that programming must involve, as the essential part, a building up of the programmers’ knowledge, the next issue is to characterize that knowledge more closely. What will be considered here is the suggestion that the programmers’ knowledge properly should be regarded as a theory, in the sense of Ryle. Very briefly, a person who has or possesses a theory in this sense knows how to do certain things and in addition can support the actual doing with explanations, justifications, and answers to queries, about the activity of concern. It may be noted that Ryle’s notion of theory appears as an example of what K. Popper calls unembodied World 3 objects and thus has a defensible philosophical standing. In the present section we shall describe Ryle’s notion of theory in more detail.

Ryle develops his notion of theory as part of his analysis of the nature of intellectual activity, particularly the manner in which intellectual activity differs from, and goes beyond, activity that is merely intelligent. In intelligent behaviour the person displays, not any particular knowledge of facts, but the ability to do certain things, such as to make and appreciate jokes, to talk grammatically, or to fish. More particularly, the intelligent performance is characterized in part by the person’s doing them well, according to certain criteria, but further displays the person’s ability to apply the criteria so as to detect and correct lapses, to learn from the examples of others, and so forth. It may be noted that this notion of intelligence does not rely on any notion that the intelligent behaviour depends on the person’s following or adhering to rules, prescriptions, or methods. On the contrary, the very act of adhering to rules can be done more or less intelligently; if the exercise of intelligence depended on following rules there would have to be rules about how to follow rules, and about how to follow the rules about following rules, etc. in an infinite regress, which is absurd.

What characterizes intellectual activity, over and beyond activity that is merely intelligent, is the person’s building and having a theory, where theory is understood as the knowledge a person must have in order not only to do certain things intelligently but also to explain them, to answer queries about them, to argue about them, and so forth. A person who has a theory is prepared to enter into such activities; while building the theory the person is trying to get it.

The notion of theory in the sense used here applies not only to the elaborate constructions of specialized fields of enquiry, but equally to activities that any person who has received education will participate in on certain occasions. Even quite unambitious activities of everyday life may give rise to people’s theorizing, for example in planning how to place furniture or how to get to some place by means of certain means of transportation.

The notion of theory employed here is explicitly not confined to what may be called the most general or abstract part of the insight. For example, to have Newton’s theory of mechanics as understood here it is not enough to understand the central laws, such as that force equals mass times acceleration. In addition, as described in more detail by Kuhn, the person having the theory must have an understanding of the manner in which the central laws apply to certain aspects of reality, so as to be able to recognize and apply the theory to other similar aspects. A person having Newton’s theory of mechanics must thus understand how it applies to the motions of pendulums and the planets, and must be able to recognize similar phenomena in the world, so as to be able to employ the mathematically expressed rules of the theory properly.

The dependence of a theory on a grasp of certain kinds of similarity between situations and events of the real world gives the reason why the knowledge held by someone who has the theory could not, in principle, be expressed in terms of rules. In fact, the similarities in question are not, and cannot be, expressed in terms of criteria, no more than the similarities of many other kinds of objects, such as human faces, tunes, or tastes of wine, can be thus expressed.

The Theory To Be Built by the Programmer

In terms of Ryle’s notion of theory, what has to be built by the programmer is a theory of how certain affairs of the world will be handled by, or supported by, a computer program. On the Theory Building View of programming the theory built by the programmers has primacy over such other products as program texts, user documentation, and additional documentation such as specifications.

In arguing for the Theory Building View, the basic issue is to show how the knowledge possessed by the programmer by virtue of his or her having the theory necessarily, and in an essential manner, transcends that which is recorded in the documented products. The answers to this issue is that the programmer’s knowledge transcends that given in documentation in at least three essential areas:

1) The programmer having the theory of the program can explain how the solution relates to the affairs of the world that it helps to handle. Such an explanation will have to be concerned with the manner in which the affairs of the world, both in their overall characteristics and their details, are, in some sense, mapped into the program text and into any additional documentation. Thus the programmer must be able to explain, for each part of the program text and for each of its overall structural characteristics, what aspect or activity of the world is matched by it. Conversely, for any aspect or activity of the world the programmer is able to state its manner of mapping into the program text. By far the largest part of the world aspects and activities will of course lie outside the scope of the program text, being irrelevant in the context. However, the decision that a part of the world is relevant can only be made by someone who understands the whole world. This understanding must be contributed by the programmer.

2) The programmer having the theory of the program can explain why each part of the program is what it is, in other words is able to support the actual program text with a justification of some sort. The final basis of the justification is and must always remain the programmer’s direct, intuitive knowledge or estimate. This holds even where the justification makes use of reasoning, perhaps with application of design rules, quantitative estimates, comparisons with alternatives, and such like, the point being that the choice of the principles and rules, and the decision that they are relevant to the situation at hand, again must in the final analysis remain a matter of the programmer’s direct knowledge.

3) The programmer having the theory of the program is able to respond constructively to any demand for a modification of the program so as to support the affairs of the world in a new manner. Designing how a modification is best incorporated into an established program depends on the perception of the similarity of the new demand with the operational facilities already built into the program. The kind of similarity that has to be perceived is one between aspects of the world. It only makes sense to the agent who has knowledge of the world, that is to the programmer, and cannot be reduced to any limited set of criteria or rules, for reasons similar to the ones given above why the justification of the program cannot be thus reduced.

While the discussion of the present section presents some basic arguments for adopting the Theory Building View of programming, an assessment of the view should take into account to what extent it may contribute to a coherent understanding of programming and its problems. Such matters will be discussed in the following sections.

Problems and Costs of Program Modifications

A prominent reason for proposing the Theory Building View of programming is the desire to establish an insight into programming suitable for supporting a sound understanding of program modifications. This question will therefore be the first one to be taken up for analysis.

One thing seems to be agreed by everyone, that software will be modified. It is invariably the case that a program, once in operation, will be felt to be only part of the answer to the problems at hand. Also the very use of the program itself will inspire ideas for further useful services that the program ought to provide. Hence the need for ways to handle modifications.

The question of program modifications is closely tied to that of programming costs. In the face of a need for a changed manner of operation of the program, one hopes to achieve a saving of costs by making modifications of an existing program text, rather than by writing an entirely new program.

The expectation that program modifications at low cost ought to be possible is one that calls for closer analysis. First it should be noted that such an expectation cannot be supported by analogy with modifications of other complicated man–made constructions. Where modifications are occasionally put into action, for example in the case of buildings, they are well known to be expensive and in fact complete demolition of the existing building followed by new construction is often found to be preferable economically. Second, the expectation of the possibility of low cost program modifications conceivably finds support in the fact that a program is a text held in a medium allowing for easy editing. For this support to be valid it must clearly be assumed that the dominating cost is one of text manipulation. This would agree with a notion of programming as text production. On the Theory Building View this whole argument is false. This view gives no support to an expectation that program modifications at low cost are generally possible.

A further closely related issue is that of program flexibility. In including flexibility in a program we build into the program certain operational facilities that are not immediately demanded, but which are likely to turn out to be useful. Thus a flexible program is able to handle certain classes of changes of external circumstances without being modified.

It is often stated that programs should be designed to include a lot of flexibility, so as to be readily adaptable to changing circumstances. Such advice may be reasonable as far as flexibility that can be easily achieved is concerned. However, flexibility can in general only be achieved at a substantial cost. Each item of it has to be designed, including what circumstances it has to cover and by what kind of parameters it should be controlled. Then it has to be implemented, tested, and described. This cost is incurred in achieving a program feature whose usefulness depends entirely on future events. It must be obvious that built–in program flexibility is no answer to the general demand for adapting programs to the changing circumstances of the world.

In a program modification an existing programmed solution has to be changed so as to cater for a change in the real world activity it has to match. What is needed in a modification, first of all, is a confrontation of the existing solution with the demands called for by the desired modification. In this confrontation the degree and kind of similarity between the capabilities of the existing solution and the new demands has to be determined. This need for a determination of similarity brings out the merit of the Theory Building View. Indeed, precisely in a determination of similarity the shortcoming of any view of programming that ignores the central requirement for the direct participation of persons who possess the appropriate insight becomes evident. The point is that the kind of similarity that has to be recognized is accessible to the human beings who possess the theory of the program, although entirely outside the reach of what can be determined by rules, since even the criteria on which to judge it cannot be formulated. From the insight into the similarity between the new requirements and those already satisfied by the program, the programmer is able to design the change of the program text needed to implement the modification.

In a certain sense there can be no question of a theory modification, only of a program modification. Indeed, a person having the theory must already be prepared to respond to the kinds of questions and demands that may give rise to program modifications. This observation leads to the important conclusion that the problems of program modification arise from acting on the assumption that programming consists of program text production, instead of recognizing programming as an activity of theory building.

On the basis of the Theory Building View the decay of a program text as a result of modifications made by programmers without a proper grasp of the underlying theory becomes understandable. As a matter of fact, if viewed merely as a change of the program text and of the external behaviour of the execution, a given desired modification may usually be realized in many different ways, all correct. At the same time, if viewed in relation to the theory of the program these ways may look very different, some of them perhaps conforming to that theory or extending it in a natural way, while others may be wholly inconsistent with that theory, perhaps having the character of unintegrated patches on the main part of the program. This difference of character of various changes is one that can only make sense to the programmer who possesses the theory of the program. At the same time the character of changes made in a program text is vital to the longer term viability of the program. For a program to retain its quality it is mandatory that each modification is firmly grounded in the theory of it. Indeed, the very notion of qualities such as simplicity and good structure can only be understood in terms of the theory of the program, since they characterize the actual program text in relation to such program texts that might have been written to achieve the same execution behaviour, but which exist only as possibilities in the programmer’s understanding.

Program Life, Death, and Revival

A main claim of the Theory Building View of programming is that an essential part of any program, the theory of it, is something that could not conceivably be expressed, but is inextricably bound to human beings. It follows that in describing the state of the program it is important to indicate the extent to which programmers having its theory remain in charge of it. As a way in which to emphasize this circumstance one might extend the notion of program building by notions of program life, death, and revival. The building of the program is the same as the building of the theory of it by and in the team of programmers. During the program life a programmer team possessing its theory remains in active control of the program, and in particular retains control over all modifications. The death of a program happens when the programmer team possessing its theory is dissolved. A dead program may continue to be used for execution in a computer and to produce useful results. The actual state of death becomes visible when demands for modifications of the program cannot be intelligently answered. Revival of a program is the rebuilding of its theory by a new programmer team.

The extended life of a program according to these notions depends on the taking over by new generations of programmers of the theory of the program. For a new programmer to come to possess an existing theory of a program it is insufficient that he or she has the opportunity to become familiar with the program text and other documentation. What is required is that the new programmer has the opportunity to work in close contact with the programmers who already possess the theory, so as to be able to become familiar with the place of the program in the wider context of the relevant real world situations and so as to acquire the knowledge of how the program works and how unusual program reactions and program modifications are handled within the program theory. This problem of education of new programmers in an existing theory of a program is quite similar to that of the educational problem of other activities where the knowledge of how to do certain things dominates over the knowledge that certain things are the case, such as writing and playing a music instrument. The most important educational activity is the student’s doing the relevant things under suitable supervision and guidance. In the case of programming the activity should include discussions of the relation between the program and the relevant aspects and activities of the real world, and of the limits set on the real world matters dealt with by the program.

A very important consequence of the Theory Building View is that program revival, that is reestablishing the theory of a program merely from the documentation, is strictly impossible. Lest this consequence may seem unreasonable it may be noted that the need for revival of an entirely dead program probably will rarely arise, since it is hardly conceivable that the revival would be assigned to new programmers without at least some knowledge of the theory had by the original team. Even so the Theory Building View suggests strongly that program revival should only be attempted in exceptional situations and with full awareness that it is at best costly, and may lead to a revived theory that differs from the one originally had by the program authors and so may contain discrepancies with the program text.

In preference to program revival, the Theory Building View suggests, the existing program text should be discarded and the new–formed programmer team should be given the opportunity to solve the given problem afresh. Such a procedure is more likely to produce a viable program than program revival, and at no higher, and possibly lower, cost. The point is that building a theory to fit and support an existing program text is a difficult, frustrating, and time consuming activity. The new programmer is likely to feel torn between loyalty to the existing program text, with whatever obscurities and weaknesses it may contain, and the new theory that he or she has to build up, and which, for better or worse, most likely will differ from the original theory behind the program text.

Similar problems are likely to arise even when a program is kept continuously alive by an evolving team of programmers, as a result of the differences of competence and background experience of the individual programmers, particularly as the team is being kept operational by inevitable replacements of the individual members.

Method and Theory Building

Recent years has seen much interest in programming methods. In the present section some comments will be made on the relation between the Theory Building View and the notions behind programming methods.

To begin with, what is a programming method? This is not always made clear, even by authors who recommend a particular method. Here a programming method will be taken to be a set of work rules for programmers, telling what kind of things the programmers should do, in what order, which notations or languages to use, and what kinds of documents to produce at various stages.

In comparing this notion of method with the Theory Building View of programming, the most important issue is that of actions or operations and their ordering. A method implies a claim that program development can and should proceed as a sequence of actions of certain kinds, each action leading to a particular kind of documented result. In building the theory there can be no particular sequence of actions, for the reason that a theory held by a person has no inherent division into parts and no inherent ordering. Rather, the person possessing a theory will be able to produce presentations of various sorts on the basis of it, in response to questions or demands.

As to the use of particular kinds of notation or formalization, again this can only be a secondary issue since the primary item, the theory, is not, and cannot be, expressed, and so no question of the form of its expression arises.

It follows that on the Theory Building View, for the primary activity of the programming there can be no right method.

This conclusion may seem to conflict with established opinion, in several ways, and might thus be taken to be an argument against the Theory Building View. Two such apparent contradictions shall be taken up here, the first relating to the importance of method in the pursuit of science, the second concerning the success of methods as actually used in software development.

The first argument is that software development should be based on scientific manners, and so should employ procedures similar to scientific methods. The flaw of this argument is the assumption that there is such a thing as scientific method and that it is helpful to scientists. This question has been the subject of much debate in recent years, and the conclusion of such authors as Feyerabend, taking his illustrations from the history of physics, and Medawar, arguing as a biologist, is that the notion of scientific method as a set of guidelines for the practising scientist is mistaken.

This conclusion is not contradicted by such work as that of Polya on problem solving. This work takes its illustrations from the field of mathematics and leads to insight which is also highly relevant to programming. However, it cannot be claimed to present a method on which to proceed. Rather, it is a collection of suggestions aiming at stimulating the mental activity of the problem solver, by pointing out different modes of work that may be applied in any sequence.

The second argument that may seem to contradict the dismissal of method of the Theory Building View is that the use of particular methods has been successful, according to published reports. To this argument it may be answered that a methodically satisfactory study of the efficacy of programming methods so far never seems to have been made. Such a study would have to employ the well established technique of controlled experiments (cf. Brooks, 1980 or Moher and Schneider, 1982). The lack of such studies is explainable partly by the high cost that would undoubtedly be incurred in such investigations if the results were to be significant, partly by the problems of establishing in an operational fashion the concepts underlying what is called methods in the field of program development. Most published reports on such methods merely describe and recommend certain techniques and procedures, without establishing their usefulness or efficacy in any systematic way. An elaborate study of five different methods by C. Floyd and several co–workers concludes that the notion of methods as systems of rules that in an arbitrary context and mechanically will lead to good solutions is an illusion. What remains is the effect of methods in the education of programmers. This conclusion is entirely compatible with the Theory Building View of programming. Indeed, on this view the quality of the theory built by the programmer will depend to a large extent on the programmer’s familiarity with model solutions of typical problems, with techniques of description and verification, and with principles of structuring systems consisting of many parts in complicated interactions. Thus many of the items of concern of methods are relevant to theory building. Where the Theory Building View departs from that of the methodologists is on the question of which techniques to use and in what order. On the Theory Building View this must remain entirely a matter for the programmer to decide, taking into account the actual problem to be solved.

Programmers’ Status and the Theory Building View

The areas where the consequences of the Theory Building View contrast most strikingly with those of the more prevalent current views are those of the programmers’ personal contribution to the activity and of the programmers’ proper status.

The contrast between the Theory Building View and the more prevalent view of the programmers’ personal contribution is apparent in much of the common discussion of programming. As just one example, consider the study of modifiability of large software systems by Oskarsson. This study gives extensive information on a considerable number of modifications in one release of a large commercial system. The description covers the background, substance, and implementation, of each modification, with particular attention to the manner in which the program changes are confined to particular program modules. However, there is no suggestion whatsoever that the implementation of the modifications might depend on the background of the 500 programmers employed on the project, such as the length of time they have been working on it, and there is no indication of the manner in which the design decisions are distributed among the 500 programmers. Even so the significance of an underlying theory is admitted indirectly in statements such as that ‘decisions were implemented in the wrong block’ and in a reference to ‘a philosophy of AXE’. However, by the manner in which the study is conducted these admissions can only remain isolated indications.

More generally, much current discussion of programming seems to assume that programming is similar to industrial production, the programmer being regarded as a component of that production, a component that has to be controlled by rules of procedure and which can be replaced easily. Another related view is that human beings perform best if they act like machines, by following rules, with a consequent stress on formal modes of expression, which make it possible to formulate certain arguments in terms of rules of formal manipulation. Such views agree well with the notion, seemingly common among persons working with computers, that the human mind works like a computer. At the level of industrial management these views support treating programmers as workers of fairly low responsibility, and only brief education.

On the Theory Building View the primary result of the programming activity is the theory held by the programmers. Since this theory by its very nature is part of the mental possession of each programmer, it follows that the notion of the programmer as an easily replaceable component in the program production activity has to be abandoned. Instead the programmer must be regarded as a responsible developer and manager of the activity in which the computer is a part. In order to fill this position he or she must be given a permanent position, of a status similar to that of other professionals, such as engineers and lawyers, whose active contributions as employers of enterprises rest on their intellectual proficiency.

The raising of the status of programmers suggested by the Theory Building View will have to be supported by a corresponding reorientation of the programmer education. While skills such as the mastery of notations, data representations, and data processes, remain important, the primary emphasis would have to turn in the direction of furthering the understanding and talent for theory formation. To what extent this can be taught at all must remain an open question. The most hopeful approach would be to have the student work on concrete problems under guidance, in an active and constructive environment.

Conclusions

Accepting program modifications demanded by changing external circumstances to be an essential part of programming, it is argued that the primary aim of programming is to have the programmers build a theory of the way the matters at hand may be supported by the execution of a program. Such a view leads to a notion of program life that depends on the continued support of the program by programmers having its theory. Further, on this view the notion of a programming method, understood as a set of rules of procedure


n5321 | 2025年8月16日 12:33