在我看来,仅由于自然语言的非正式性质,您不可能用完全没有歧义的英语来编写软件规范,因此,真正明确的规范必须包括以正式指定的语言编写的代码。
这是已知结果还是我缺少什么?
在我看来,仅由于自然语言的非正式性质,您不可能用完全没有歧义的英语来编写软件规范,因此,真正明确的规范必须包括以正式指定的语言编写的代码。
这是已知结果还是我缺少什么?
Answers:
难道这不是律师总是为了避免歧义而做的吗?
结果是他们以最不自然的方式写作,尝试阅读论文比以往任何时候都更加困难,尽管如此,始终存在矛盾和歧义。
没错,您不能编写完全没有歧义的软件规范,但是您也无法通过实现正式的指定语言来做到这一点。
这也是我们记录代码的原因,因为有时很难为我们所读。
用其他代码记录代码毫无意义。
不可能?让我们先问一下它是否令人满意。如果我们同意这是不可能的,并且仍然有很多有用的软件,那么明确规范的目标似乎是学术性的。
我想说,对于规范和软件,都不可能证明任何事情都是完美无缺的。
我认为这取决于问题的大小。如果问题足够小,本质上是数学上的问题,也许还有我遗漏的其他一些标准,我会说写一个可行的规范是可能的。
问题越大,受众越广,难度就越大。
但是航空电子设备和其他复杂问题表明,有可能用英语写出“足够好”的规范来解决大问题。
好吧..问题的一个完全明确的说明是实际的代码本身:)
这是一个已知的问题,对于特殊的任务关键型系统,必须以正式的(编程)语言编写明确的规范,然后将其转换为可证明符合规范要求的代码。这是一个非常狭窄的领域,有99.999%的开发人员从来不需要执行这样的任务,但是我曾经与一个为交通控制/铁路系统做过这个工作的人进行过交谈。
我是W3C的追随者,我倾向于根据他们的规范来撰写文章。我的经验告诉我,在没有书面示例代码的情况下阅读任何规范,简直令人头疼。
我完全同意,我认为主要原因是开发人员倾向于更好地阅读和理解代码。试想一下,如果您得到的数学论文没有任何公式。
To calculate the result, simply add variable x to variable y,
and then divide that by the b factor.
要么:
result = (x + y) / b
哪一个较短?哪一个更易读?哪个带来更多理解?
规格也是如此。很多时候,当您到达技术部分时,编写一行代码可以澄清一段冗长的解释。
假设有一种正式的语言可以编写明确的规范。然后,我建议应该对英语的子集进行双射映射。因此,如果您坚持使用此子集,那么应该有可能编写明确的规范。
但是,任何具有足够表达能力以进行有趣工作的形式语言都将没有不一致之处(哥德尔不完整性)。
在这种情况下,歧义实际上是一种优势。
要解释为什么,让我们假设一下,如果它是可以使用英语语言在一个完全明确的方式,这样可以通过编程来解决任何问题,可以完全和明确地表达。如果我们使用英语的这种变体,并且我们的描述的确确实完整地描述了要编写的程序,那么从逻辑上讲,必须有可能执行自动翻译成目标编程语言-换句话说,我们构想的英语实际上实际上是一种编程语言。
阅读设计文档(尤其是功能设计)的人们实际上并不希望如此详细—阅读程序的源代码,无论是C ++,Java还是明确的英语,都超出了一般非程序员的头脑。这就是自然语言出现的地方:它们使规范的编写者可以在细节范围内任意滑动,将不相关的实现细节移到子文本中,或者完全不指定它们。即使您没有提供准确的定义,自然语言也充满了相对清晰地传达含义的设备(这是使自动翻译如此困难的一部分)。
因此,目标通常不是一个完整,正确和明确的规范;目的是编写一个规范,向人类清楚地说明您将要构建的内容。
每当您确实需要正确而明确的东西,并且无论如何事情变得技术化时,伪代码通常比自然语言或严格的形式语言更有价值-它仍然可以忽略无关的细节(通过调用未指定的函数/过程),但是结构是明确的。
(我的一些观点已经被其他答案所暗示,但是我觉得我提供了一种足够不同的观点,使之值得回答而不是发表评论。)
在解决规范是否可以真正且完全明确的问题之前,我们必须至少在您所要求的水平上解决规范是否应该明确的问题。
让我从程序经理的角度来解决这个问题,该经理正在处理中小型项目,或者是作为较大项目一部分的功能。通常会为此类项目编写两种不同类型的规范:功能(或PM)规范和设计(或开发)规范:
通常,这些实现级别的详细信息不是在正式文档中捕获的,而是本身在代码本身(包括注释)中记录的。这种含糊不清的程度允许优秀的开发人员使用自己的技能,并进行注重细节的技术决策,这是优秀的单个开发人员的特点。因此,我会毫不犹豫地说,规范中的歧义实际上是一件好事:它允许开发人员完成其工作,并将其提升到不仅仅是“代码猴子”的地位。
但这并不是说整个文档中应该有歧义。从高层次上讲,与客户的接口应该没有歧义。如果功能具有面向公众的API,则应严格定义它。如果系统要求传递日期以完成工作,那么该日期应该在当地时区还是UTC?需要什么格式?是否需要精确到毫秒,还是分钟就可以了?
回到是否可以使用自然语言来创建明确的规范的问题,这的确不能很好地捕捉这种清晰的水平。我已经看到它在某些有限的情况下完成,但是这些可能是我们无法普遍适用的独特例外。大多数情况下,借助技术术语,图表甚至伪代码可以解决歧义。一旦您开始寻求此类工具的帮助,自然语言将不再是唯一的描述符。因为这些工具甚至可以使在功能上完全明确的规范变得更加清晰,所以我敢说,甚至不应该尝试这种工作。
话虽这么说,因为自然语言通常会被这些工具补充以使其在功能上变得明确,所以我的专业意见是,没有,仅自然语言不足以在所有情况下创建明确的规范。
我相信正确答案是否定的。有必要区分以下问题:
第一个问题和第二个问题之间的差异涉及所涉及的详细程度,所需的解释量以及出于编写软件或软件规范的目的而对以自然语言构建句子所施加的规则。
第二个问题的答案是肯定的。给定自然语言的适当约束子集,并使用公认的句子构造和含义规则,可以用语法英语句子编写代码。例如,以下语言明确允许编写分配语句:
Variables: x,y,z,...
Constants: 1,2,3,...
Rules: (1) if x is a variable and n a constant, then
"The variable x contains the number n" is a sentence.
(2) if x is a variable and n a constant, then
"Assign the number n to the variable x" is a sentence.
也就是说,我们可以通过描述每个过程来将用正式编程语言编写的代码系统地转换为自然语言。另一方面,软件规范通常需要解释。因此,是否可以明确地给出软件规范取决于规范中涉及的详细程度。但是,给定规范所覆盖的选定域,并选择对该域的特定操作,就可以执行类似的翻译过程。例如:
Over the domain D supporting operations f,g,h over elements a,b,c in relations
P,R,Q with properties φ,ψ,θ, design a program that does X,Y,Z.
其中陈述X
,Y
,Z
只包含在规范的前言中提到的那些项目,都写在适当正式和商定的自然语言的子集。然后,歧义将涉及如何实施规范-但这是可以预期的。