在您看来,哪种语言可以让普通程序员输出具有最少数量的难以发现的错误的功能?当然,这是一个非常广泛的问题,我对非常广泛和普遍的答案和智慧感兴趣。

就我个人而言,我发现我花很少的时间在 Java 和 C# 程序中寻找奇怪的错误,而 C++ 代码有其独特的一组重复出现的错误,而 Python/类似代码有其自己的一组常见且愚蠢的错误,编译器会检测到这些错误其他语言。

另外,我发现在这方面很难考虑函数式语言,因为我从未见过用完全函数式代码编写的大型复杂程序。请您输入。

编辑: 对难以发现的错误的完全任意的澄清:重现需要超过 15 分钟,或者查找原因并修复需要超过 1 小时。

如果这是重复的,请原谅我,但我没有找到有关此特定主题的任何内容。

有帮助吗?

解决方案

语言的类型系统越强大,在编译时间本身会捕获的错误将越多。

下图从其类型系统的功率,简单性和安全性方面比较了一些知名的编程语言。 [[ 资源 ]

alt text

*考虑使用不安全构造的能力。

C#由于“不安全”的关键字和关联的指针机械而被塞入不安全的行中。但是,如果您想将这些视为一种内联的外国功能机制,可以随意撞到c#Skyward。

由于不安全*的功能系列,我将Haskell '98标记为纯粹,但GHC Haskell并非纯净。如果您禁用不安全*,请相应地跳转GHC HASKELL。

其他提示

我认为Haskell可以帮助您避免一些常见的错误来源:

  • 它纯粹是功能性的:功能不能具有(无意)的副作用,这使多核编程更容易,更容易容易出错
  • 它是强烈键入的:您不能意外地混合布尔,char,int和float值
  • 它是静态输入的:许多编译时捕获了许多编程错误
  • null 不是价值类型定义的一部分:您避免 十亿美元的错误
  • 有很多现成的高阶功能,您可以重复使用,而不是编写自己的(可能是错误的实现)
  • 它有一个垃圾收集器:几乎消除了内存错误(由于其懒惰的评估策略,“空间泄漏”除外)

传统上,最难找到错误是多线程应用程序中的种族条件

  • 几乎不可能繁殖
  • 可以很微妙

因此,您需要尽可能多地为您管理类似性的语言。这些还不是主流。 Java做了一些,但是让您遇到困难。

据我了解,您需要一种功能性语言,因为“不副作用”首先是使两个要点消失的事情。我已经看到,在透明地使Haskell成为有效的多线程语言方面的工作正在进行中,我相信Fortress是从头开始设计的,以成为一种有效的并行语言。


编辑:在Java中 Executors 处理更多的硬零件。您需要使各个任务符合 Callable 界面。

ADA的设计是使尽可能多地以编译时间而不是运行时间捕获。这意味着,要在ADA中获得一个程序比同等学历的汇编通常需要大约10倍的时间,但是当它编译时,您可能会更有信心,当程序的漏洞不会表现出来跑。

首先是一个定义:据我了解,一个难以找到的错误是可以复制但很难找到原因的错误。

可能最重要的方面是我所说的 狭窄, ,即一个错误可以逃脱多远,错误可能会影响错误的范围。在诸如C,错误的语言中,例如负阵列索引或非专业指针,可能会影响整个程序中各地的所有内容,因此在最坏的情况下,您必须检查 到处都是 找到问题的根源。

在这方面,良好的语言支持访问修饰符并以使其难以绕过它们的方式或不可能绕开它们的方式。好的语言鼓励您限制变量的范围,而不是使具有全局变量的容易变得太容易了(例如,“所有未明确声明的一切都是具有默认类型和值的全局变量”)。

第二个重要方面是 并发. 。种族条件通常很难繁殖,因此很难找到。优秀的语言提供易于使用的同步机制,并且在必要时,其标准液体是安全的。

这已经完成了我的清单;诸如强键入的其他事情有助于在编译时捕捉错误,但是以后可能不难找到这些错误。

考虑到所有这些,我会说Java和C#以及JVM和.NET世界中的许多其他语言都适合避免难以找到的错误。

由于Excel是最广泛使用的DSL,因此我会选择Excel。 (当然不包括VBA)

它适合法案:

  • 它总是很容易复制(这是电子表格 - 它不起作用)
  • 找到该错误非常容易,因为它完全是“功能性的” - 从错误的单元格开始,然后追溯所有依赖性。

这是一个困难的问题,因为大多数错误不是语言本身的错 - 而是开发人员在使用语言方面犯错误的错。

我相信语言特征有几个方面会影响错误的可能性:

  • 互动性 - 带有REPL的动态语言鼓励与运行程序和较小的代码 /测试周期进行互动 /实验。如果您认为迭代是发现清洁简单解决方案并检测/消除错误的好方法,那么这将倾向于使用交互式语言。

  • 表现力 - 如果代码较短,并且具有较小的样板 /附带复杂性,则更容易看到错误 /逻辑错误。

  • 类型安全 - 编译时间越多,编译器将捕获的错误越多,因此一般类型的安全性是一件好事。但是这些通常不是 很难找到 错误 - 即使在完全动态的语言中,数据结构中的错误类型通常会导致非常明显的运行时错误,而TDD几乎总是会捡起这些错误。

  • 不变性 - 许多硬错误是由于可变状态的复杂相互作用所致。强调不变性的语言(Haskell,Clojure,Erlang)具有巨大的优势。

  • 功能编程 - 编写代码的功能方法往往比具有复杂效果 /交互序列的对象代码更“可证明是正确的”。我的经验是,FP有助于避免棘手的错误 - 我相信某处有一些我目前找不到的学术研究可以支持这一点。

  • 并发支持 - 并发问题特别难以检测和调试,这就是为什么如此重要的原因。任何需要手动锁定的东西最终都注定要失败(这几乎包括 每一个 面向对象的并发方法)。我在这方面知道的最好的语言是Clojure-它具有独特的方法来管理并发性,该方法将软件交易记忆与不可变的数据结构相结合,以获取新颖,可靠和合成的并发框架。看 http://www.infoq.com/presentations/value-indentity-state-hickey 有关更多见解

语言的强大功能越少,它给您拍摄脚的选择就越少。

与C ++(如C ++)相比,Java和C#等高级语言将产生更少的错误。

话虽如此,我相信Java比C#更安全。 Java人为地受到限制,因此没有高级知识的普通程序员可以掌握它并制作稳定的程序。

您认为哪种语言使普通程序员可以输出最少难以找到的错误的功能?

在我看来,德尔福。该语言基于 Pascal,对于普通程序员来说足够简单直观 (甚至是没有经验的编码员) 易于上手,其丰富的工具和库支持使大多数错误很容易找到。

  • 强类型和严格的编译器可以捕获许多常见错误。
  • 直观的语法不会导致常见错误。(《世界上最后的虫子》 if (alert = RED) {LaunchNukes;}, ,例如不会编译。)
  • 精心设计的对象模型,消除了许多常见的 C++ OOP 错误。
  • 语言内置的边界检查和范围检查, 大大减少出现安全问题的可能性。
  • 可能是人类已知的最快的编译器,它可以提高您的工作效率,并且使您在等待构建时更不易失去思路。
  • 调试器 Visual Studio 的调试器希望像它长大后一样。
  • 内存管理器中直接内置了泄漏跟踪功能,使查找和修复内存泄漏变得轻而易举。
  • 一个大型、成熟的标准库,提供预构建和预测试的方法来完成常见任务,而无需构建您自己的、可能有错误的实现。
  • 附带有用的工具,例如强大的日志系统和分析器,可以更轻松地跟踪问题。
  • 对标准库中未包含的常见问题提供强大的社区支持,包括 强大的第三方并发库.

要考虑的一件事是转折时间。

在过去的五年左右的时间里,我主要在Java(JSF,接缝等)开发了Web应用程序。最近,我得到了一份新工作,我们正在使用Perl(与Catalyst和Moose一起使用)。

我在珀尔(Perl)的生产力要比在爪哇(Java)发挥作用。

不需要编译和(热)部署是原因之一。我还发现编写用例更容易,因为可以更迭代的方式完成。至少对于我参与的项目,Java中的框架似乎是不必要的复杂的。

我猜我的perl代码中的错误数量或多或少与我的Java代码中的错误数量相同,甚至可能更高。但是,我发现ET更容易,更快地查找和修复这些错误。

也许对每种编程语言的静态和动态代码分析的可用工具数量可能给出一个想法。语言的工具越多,语言在用户中很可能很受欢迎,要么在难以找到错误时很受欢迎。但是我无法让Google指出有关该主题的任何研究。还应注意的是,某些语言(例如C)可以用来围绕基础硬件错误进行工作,并随着年龄的增长而围绕硬件的磨损来工作。

而不是谈论语言如何谈论语言功能

  • Java迫使您考虑例外(投掷...),您必须公开或处理这些异常。这是否真的阻止了我忘记错误或我使用的更多例外,这些异常不需要此操作?
  • “合同设计”(http://en.wikipedia.org/wiki/design_by_contract)迫使我考虑前和后条件。我已经阅读了C#-4.0的可能。
许可以下: CC-BY-SA归因
scroll top