【问题标题】:Why aren't more applications written in multiple languages?为什么没有更多的应用程序用多种语言编写?
【发布时间】:2009-11-21 01:03:41
【问题描述】:

即使在 20 年前,也可以调用用一种语言编写的代码来调用用另一种语言编写的代码;在学校里,我们从 Ada 代码中调用汇编图形例程来完成一项课堂作业。值得注意的例外是从脚本中运行编译代码或从编译代码中执行系统命令;但是我们很少用 C++ 编写一个库来在我们的 Java 应用程序中使用。当 Java 第一次出现并且速度仍然很慢时,可以选择用 Java 编写主应用程序并将瓶颈代码移动到一些 C/C++ dll 中以使用 JNI 调用。

那么,这么多年过去了,是什么让我们无法编写多语言应用程序?我想到的主要场景是,如果一种语言不是因为某些性能瓶颈(比如早期的 Java 时代)而被认为是一个不错的选择,所以它完全用 C 语言编写,而不是混合使用两种语言。

我从架构和语言设计的角度对此感兴趣。你有什么好的例子、成功案例或引言吗?

[编辑] 最好的例子之一是对 Java 的强烈反对,因为它早期的性能很慢。尽管 JIT 编译器已经解决了这个问题,但我的问题始终是关于用一种更容易编写、阅读和维护的语言编写软件。如果存在瓶颈,请在汇编或 C 中编写一个例程来解决瓶颈。这样你就应该两全其美,至少在理论上是这样。

【问题讨论】:

  • 这是一篇博文的咆哮。不是问题。
  • 您的意见是基于什么?你怎么知道人们在做什么?那里有数百万个应用程序。我认为只有在某些应用程序中这种东西无论如何都会有用,并且它有相关的成本(即,现在你需要雇用懂两种语言而不是一种语言的人)。
  • 人不是白痴。当今流行的语言是一体式的(或至少是一体式的)。世界上没有一个高效的人会决定用多种语言编写应用程序,除非他确信它会更快地得到他想要的(或想要的)。

标签: architecture programming-languages


【解决方案1】:

使用多种语言涉及:

  • 技能组合更加多样化,并不是每个人都能解决系统中任何地方的问题
  • 根据所涉及的语言,在跨语言调用方面通常会有些痛苦。 (您的 JNI 示例在这里很好 - 它是令人讨厌的 IME。P/Invoke 要简单得多。)
  • 通常更难调试
  • 更复杂的构建系统(例如,使用 Java 可以获得可移植性 - 但如果您还要构建和部署本机库,生活就会变得更加艰难......)

是的,有时它是值得的——但我不会这样做,除非我有充分的理由。

当然,

.NET 和 Java 都让这件事变得容易多了——在一个平台上使用不同的语言比在(比如说)托管代码和本机代码之间进行互操作要容易得多。

【讨论】:

  • 优秀的回复。众所周知,我将 DSL/生成的代码用于“大大小小的”任务,但从团队的角度来看,使用单一语言有很多优势。你要问的问题是“第二种语言在解决这个问题方面比第一种语言好得多吗?我们愿意在整个项目期间处理上述问题只是为了使用它。”
  • 如果您不只是使用简单的字符串,则会浪费大量时间/代码编组数据进出每个子系统。
【解决方案2】:

我看到的最大问题是因为它要求团队中的每个人都非常多样化(请参阅 Jon Skeet 的回答)。如果你有一个 10 人的团队,其中 3 人非常了解 C#,并且有一些 VB.NET,3 人非常了解 VB.NET,但 C# 很少,另外 4 人非常了解 C++,但只能在 C# 或 VB 上使用。 Net,你能想象他们会写什么样的程序是多语言的吗?结果可能没问题,但是如果你失去了几个团队成员怎么办,时间很重要,说是你的 C++ 人,现在谁来修复那个代码?当然不是那些不熟悉 C++ 的 .NET 人。这会导致很多问题。

我看到当今应用程序大多是单一语言的第二个原因是,当您达到大量代码行时,能够遵循相同的流程、模式并查看相同类型的代码是非常好的整个系统。你的大脑不必在语言之间切换来找出一些东西,因为你已经在“思考 C#”了。

我有一个朋友用 VB.Net 编写他的用户界面,他的后端代码总是存储在 C# 中的 DLL 中。没关系,VB.NET 和 C# 可以很好地协同工作,但是说他需要将它外包给某人来修复一段代码,其中 VB.NET 和 C# 代码中都有错误,好吧,他需要外包两名开发人员,一名精通 VB.NET,另一名精通 C#。这增加了两倍的成本,以及原本可以一次性完成的开销。

但是,我完全同意可能将 C++ 用于性能关键部分的应用程序。有时,对于性能关键的代码段来说,简单的 .NET 可能不是一个好的选择。这种混码是绝对没问题的。

从长远来看,代码混合并不是一件坏事。这可能很好,因为它将帮助您作为开发人员变得更加多样化,改变您的思维方式,并帮助您作为开发人员。但是您必须为更多的开销、可能的成本,甚至可能在此过程中的一些挫折做好准备。

也许对您来说一个好主意(如果您正在寻找这种类型的答案)将选择每种技术的语言。我个人在 VB.NET 中编写了我所有的网络应用程序(asp.net 等)。它编写速度快,易于阅读且易于维护。对于网络,这正是您想要的。然而,我所有的桌面应用程序都被推到了 C# 中,因为它在某些方面是一种更强大的语言,并且提供了一些 VB.NET 没有的东西。真的,这都是个人喜好,但你明白了。

【讨论】:

    【解决方案3】:

    人们一直在编写多语言应用程序。您提到了从脚本语言调用的编译代码。这种情况经常发生,例如来自 Python、Perl、Lua 或 R 的 C++。或者来自 Groovy 的 Java。不确定从 Java 调用 C++ 的频率,但我相信它也会发生。

    这就是swig 如此受欢迎的原因。

    【讨论】:

    • 您在这里谈论的是两种截然不同的语言,C++ 作为高性能语言,Perl、Lua 或 Python 或其他语言作为快速开发语言。但是,C++ 和 Java 是相似的语言,所以我看不到它们之间的协同作用。
    • JNI(Java Native Interface)用于接口C++和Java
    • 我或多或少知道如何连接 C++ 和 Java,我想知道为什么,除了使用已经编写的代码。 (就像在研究生院中,我如何使用 f2c 将 Fortran 代码编译成 C,这样我就可以将它与 Lisp 接口。毕竟,我的 Lisp 应用程序需要一个高质量的线性编程系统。)C++ 和 Python 不行类似的事情,但 C++ 和 Java 可以。
    【解决方案4】:

    UNIX 已经解决了这个问题。 UNIX 风格的小型实用程序可以串联起来形成一个解决方案,这是用多种语言编写应用程序的一种形式。而不是定义语言之间交互的接口和/或机制,例如JNI,命令行或shell环境已经成为事实上的标准。

    我想知道是否接触 UNIX 或缺乏 UNIX 是导致这个主题要么不值得努力要么变得异常复杂的原因。也就是说,具有 UNIX 经验的人不会为 JNI 烦恼,因为他们处理设计问题的方式不同,因此他们的应用程序在内部更加模块化和内聚;更有利于变成一串应用程序中的一个组件,而不是一个单一的庞然大物。

    【讨论】:

      【解决方案5】:

      根据您对这个问题的看法,有很多应用程序是用多种语言编写的,也可能没有。

      例如,考虑一个使用多个网络服务的混搭网络应用。每个 Web 服务都可以用不同的语言编写。所以从某种意义上说,这样的应用程序是用多种语言编写的

      或者,您可以查看一个“简单的、非混搭的网络应用程序,它可能会使用:

      • 用于持久性的 SQL
      • C#/Groovy/RoR/等。对于应用逻辑
      • 用于演示的 JavaScript/CSS/(X)HTML

      甚至可能有一个 OR/M 工具,或者在 C# 的情况下是 LINQ to SQL,用于访问数据存储。我们不要忘记嵌入在代码的各个级别的正则表达式。这些都是不同的语言。所以从这个意义上说,经常使用多种语言来构建应用程序

      但我不认为这是你的想法。 我认为您的预期范围是单个项目团队生成的代码“主体”。您想知道为什么一个项目不使用 Java 编写一个组件,Lisp 编写另一个组件,Erlang 编写第三个组件,然后将它们链接在一起作为统一的可交付成果。

      已经提出了一些答案,例如构建/部署更难,或者不是每个人都能够在系统的每个部分工作,因为缺乏特定语言的技能。我不喜欢这些类型的答案。我在主要用单一语言编写的项目中看到了令人讨厌的构建/部署脚本。根据我的经验,当几乎任何项目达到一定规模时,特别是如果它是由许多人编写的,那么每个人都很难精通系统的每个部分。此外,从一种语言跳到另一种语言(假设开发人员足够老练)并不像某些人想象的那么大。

      问题是我们不能像乐高积木一样将代码块拼凑在一起。我们愿意,并且在某些情况下,也许我们可以做一些事情。问题主要在于公共组件接口组件依赖规范的成熟度。再一次,我看到这些东西妨碍了“主要是一种语言”的项目。但是当你跨越语言界限时,情况就更加复杂了。

      无论如何,为正确的问题使用“正确”的语言非常有价值。如果你真的相信你拥有三个用 Java、Lisp 和 Erlang 表示最好的组件,那么用这些语言编写这些组件对你有利。 只要您期望将它们链接在一起并维护这些链接所需的工作不会大于您从使用多种语言编写所获得的价值

      因此,真正归结为降低组装组件的成本。这与仅仅说“构建变得更难”略有不同。有了定义良好的公共接口、适当的信息隐藏以及相对轻松的依赖项发现和解析,没有理由不能用多种语言编写单个项目的组件。

      【讨论】:

        【解决方案6】:

        “那么,这么多年过去了,是什么让我们无法编写多语言应用程序?”

        可能会认为从语言 B 的代码调用语言 A 的代码有太多的陷阱。字节对齐、字节顺序、参数顺序等。覆盖所有的陷阱以便您可以在晚上睡觉需要时间.

        .NET 试图解决这些问题,但我不确定效果如何。那是另一个讨论。

        【讨论】:

          【解决方案7】:

          我最近的 4 个工作是调用的应用程序:

          • Java 来自 C#,C# 来自 F#
          • Ruby 中的 Java
          • Tcl 中的 Python、Python 中的 C++ 和 Tcl 中的 C
          • Java 来自 Python,Java 来自 Scheme

          (这还不包括 SQL、JS、OQL 等)

          根据我的经验,这种转变恰恰相反:更多的语言。原因包括:

          • 标准虚拟机(如 JVM 和 CLR)允许语言无意间进行协作
          • C 上的对象系统(如 GLib)为本地编译的语言提供类似的功能
          • 计算机系统现在大而快,每个人都使用带有查询语言的数据库(现在甚至 SQLite 都被认为很小!)
          • 最流行的新平台网络,如果您想要响应式客户端交互,则要求您使用 JS,而您可能没有在服务器上使用 JS
          • Web 还提供了一种在同一系统中集成完全不同的程序的自然方式,例如,具有正确 CSS/JS/主题的 Python 程序和 Ruby 程序可以看起来相同并相互链接,这样用户甚至都不知道这是两个独立的程序

          顺便说一句,这些都是付费项目。在我的个人项目中,我总是最终使用一种语言。简单性超过了能够拉出一个包并将其快速集成到我的项目中的好处。

          【讨论】:

            【解决方案8】:

            我完全同意这个问题的前提。

            学习多种特定领域的语言比尝试学习将通用语言应用于不同的领域更容易。

            不要误以为使用一种通用语言会以任何方式缩小所需的技能和学习范围。只是现在你必须学习如何将一种语言扭曲成各种形状,并学习六种框架来配合它。

            我们编写了一个系统,将 10,000 行通用 Java 代码替换为 750 行用 2 个 DSL 编写并与 Java 粘合在一起的代码。我们用原系统的 1/10 时间编写,包括 DSL 学习时间。

            【讨论】:

              【解决方案9】:

              是什么让你认为这没有发生?

              我的 ASP.NET MVC 应用程序有一些 C#、一些 VB.NET 和一些 JavaScript。我可以很容易地投入一些 Python 和 F#,但还没有发现需要走那么远。

              【讨论】:

              • 我也有一个项目,它使用 VB.NET/Javscript 作为 Web 端,使用 C# 作为应用服务和库。
              • 我不是说它没有发生,我是在问为什么它没有发生更多
              • 定义“更多”。今天有多少百分比的应用程序是用一种语言编写的?二?三?十个?
              • @kevindtimm,这听起来像是一个出色答案的核心。请在发布的答案中详细说明。
              • 问题说“更多”。这意味着,尽管人们肯定在一个应用程序中使用多种语言(地狱......几乎每个网络应用程序都使用 Javascript,一些 GPL 像 Java 和 SQL),但它还有更多的空间可以做得更好影响。
              【解决方案10】:

              一种情况是库或其他固定代码以与应用程序不同的语言出现。很多这些东西是用 C 编写的,而现在很多应用程序都不是用 C 编写的。数字的东西通常是用 Fortran 编写的(在研究生院,我不得不将 Fortran 例程连接到 Common Lisp 应用程序)。

              当您已经编写了重要部分时,使用其他语言比重写和验证其他人的代码要容易得多。

              【讨论】:

                【解决方案11】:

                我在最近的项目中混合使用了 C 和 Lua(或 C++ 和 Lua)。我觉得让两种语言具有不同的优点和缺点来平衡是一种解放。 Lua 代码大部分被编译(烘焙)到同一个 exe 中,因此最终结果只是一个二进制文件。

                关于调试和理解所有内容的难度的评论是有效的。不过,它确实使源代码行数保持在较低水平。

                Apple 的 Objective-C 采用了几乎相同的“汞合金”方法,但逐行转换了思维方式。我觉得那个困难。 Lua 和 C(++) 允许我通过源文件切换思维方式。

                【讨论】:

                  【解决方案12】:

                  自从汇编器发明以来,开发人员一直担心性能问题,例如优化 C++ 中的虚拟方法调用或 Java 的字节码运行时编译。质疑任何不明显的事情是他们的天性。

                  【讨论】:

                    【解决方案13】:

                    在我看来,在解释器/编译器中包含多语言支持有两个主要原因:

                    • 允许开发人员在汇编中编写函数,在性能对应用至关重要的极少数情况下
                    • 为可能熟悉其他语言的开发人员简化新语言的介绍

                    第一个今天很少见,主要是由于使用了共享库(例如 dll)和增加了抽象(你的代码和下面的程序集之间的抽象层很厚),而第二个主要是营销的事情,而营销通常不是编写语言规范的人的主要兴趣(.Net 是现在想到的第一个例外)。

                    【讨论】:

                      【解决方案14】:

                      略有不同的方面:

                      在 1980 年代,很少有语言能够提供全方位的功能。业务应用程序可以用 COBOL 编写,但如果它需要复杂的数值例程,则可以用 FORTRAN 编写,并使用定制的汇编程序来管理从 COBOL 到 FORTRAN 的函数调用。现在有多种语言选择和相关库,可以用一种语言提供全部功能。

                      计算机容量(CPU、内存、磁盘、I/O 速度)的严重限制也导致需要为程序或系统的不同部分使用不同的语言。

                      【讨论】:

                      • 我认为你说的太晚了。 COBOL 应用程序自 1960 年代就已经存在,而 COBOL 是一种受限语言。在 1980 年代,我们在小型计算机上使用了 Basic 和 Pascal,以及 Fortran,C 也随之出现(它最初是在 1989 年标准化的)。即使在 1960 年代,FORTRAN 和 ALGOL 也可用于通用编程。
                      • 我同意之前的情况也可能如此。我提到了 80 年代,因为我知道从那时起我所描述的系统就是如此。我并不是要暗示这个问题是那个时期独有的,只是引用经验而不是寻找其他时期的其他例子。
                      【解决方案15】:

                      在我的家庭项目中,我从 C 调用 Fortran 过程,或从 C++ 调用 C 过程。

                      在我的工作代码中,我们将 Java 与一些 C 混合在一起。

                      它仍然会发生,但人们试图避免它,有充分的理由。

                      【讨论】:

                      • 您能详细说明这些原因吗?
                      • 名称修改,二进制不兼容,调试困难。例如,JNI 被誉为 PITA。
                      【解决方案16】:

                      即使是初学者,我也发现自己需要在 C 代码中使用少量汇编语言来加快速度。 (这是为了使用一个相当慢的处理器板来跟踪带有摄像头馈送的线路)

                      我建议如果有人用某种语言写一篇文章,那么他们可能最喜欢这种语言。使用他们可能不太熟悉的语言需要有非常令人信服的理由。

                      据我了解,许多游戏开发者会为关键的数学库使用汇编。

                      【讨论】:

                        【解决方案17】:

                        我不确定原因是什么,但我想这与我们在 90 年代末开始的“语言-du-jour”心态有很大关系。我即将开始一个我想用 C++ 编写的令人抓狂的项目,但我希望可以使用许多其他语言。我可能会为此使用 Swig 和 SpiderMonkey 的组合。

                        但其中很多确实归结为没有人创建一个没有 .DLL 的统一对象/重用接口。 COM 在 Windows 上很棒。 IDispatch 使任何使用 IDispatch 的东西都可以使用。用 C++ 编写我们的组件并在 ASP 中通过 VBScript 使用它们真是太棒了。但是从来没有像这样的便携设备出现过。当然,尝试是通过 CORBA 和六种其他半生不熟且通常不受欢迎的技术进行的——但它们都存在数据编组问题、调用问题、性能问题、字节序问题。没有人真正花时间试图解决它,现在行业正在向 SOAP 发展,以在性能不重要的地方取代它(并在它重要的地方坚持使用 CORBA)。

                        【讨论】:

                          【解决方案18】:

                          我认为很大一部分原因是因为没有令人信服的理由这样做。如果一种语言具有足够引人注目的功能(例如,面向对象),那么它可能足够引人注目以用于整个项目。 BITD,过去如果速度不够快,您会用汇编语言重写部分代码,或者编写适配器以便您可以从 C 调用 FORTRAN 统计数据包。如今,没有太大压力要做到这一点。许多性能问题在代码中是无法解决的(例如,网络延迟),并且大多数提供软件组件的公司都以几种“风格”(例如,Java jar 文件或 .NET 组件)来提供它们。正如其他人所提到的,许多开发人员之间也存在很大的惰性,这往往使他们不愿意学习一门新语言,尤其是在它不同的情况下。当然,如果一种语言没有不同,那么可能没有任何令人信服的理由来学习它。

                          【讨论】:

                            【解决方案19】:

                            我们经常使用多种语言写作。这取决于手头的任务。在最近的一个 web 应用程序中,我用 PHP 编写了 web 框架,用 JavaScript 编写了客户端脚本,用 Delphi 编写了后端引擎和 PHP 插件,用 MS-SQL 编写了数据库。

                            目前我在一个环境中工作,我们在 Delphi 中执行快速原型设计,然后发送到生产环境以使用 MS C# 进行编码。该公司还使用多种其他语言。

                            几年前,我参与了一个使用 8 种不同语言的项目。这是一个正确的混乱,但它仍然得到大规模的支持。

                            所以我真的不能同意 Kelly French 的提议,即我们没有使用多种语言。您只需要将您的应用程序扩展到数据库或 Web 服务中,您就会发现自己将其混合在一起。没有一种语言可以做到这一切。如果有的话,我会在星期天使用它并参加它的教堂。

                            【讨论】:

                              【解决方案20】:

                              使用多种语言会使重构变得更加困难和昂贵。因为当这些类是用不同的语言编写时,诸如将方法从一个类移动到另一个类的操作要困难得多。

                              【讨论】:

                                【解决方案21】:

                                我想说,使用多种语言编写的应用程序比您想象的要多得多。只是一个例子:

                                • 最近有多少互联网应用程序是用 C 语言编写的?几乎没有。
                                • 有多少 IP 堆栈是用 C 以外的其他语言编写的?几乎没有。

                                【讨论】:

                                  【解决方案22】:

                                  这主要是一个管理问题。答案更植根于经济而非技术。简单地说,它更贵。您可以想象所有困难,例如更难管理,包括调试、重构、开发人员更换等。

                                  【讨论】:

                                    【解决方案23】:

                                    对于许多类别的应用程序,根本不需要“经典”的多语言项目(涉及高级语言和低级语言),而且额外的复杂性成本很高:

                                    • 您的开发人员必须了解所涉及的所有语言
                                    • 您的构建系统必须支持它们
                                    • 便携性会受到影响
                                    • 错误会更加隐蔽

                                    OTOH,许多现代应用程序已经使用许多不同的语言,例如Java、JSP、XSLT 和 Javascript 可能都用在同一个项目中。

                                    【讨论】:

                                      【解决方案24】:

                                      我用 Python 编写,它从 C 中调用,使用 SQL 查询其数据库,使用 HTTP 执行其 I/O,提供使用 TEI 描述的文档,使用 XSLT 转换它们,使用 HTML 在客户端呈现其输出和 CSS,以特殊的模板语言格式化其非文档输出,并使用 javascript 为其用户界面添加功能。

                                      您可能已经注意到,这是一个相当通用的 Web 应用程序(TEI 除外)。你所说的这些技术现在非常普遍。动机并不总是优化代码中对速度敏感的部分,但这些技术肯定是存在的。

                                      【讨论】:

                                        猜你喜欢
                                        • 2010-10-01
                                        • 1970-01-01
                                        • 1970-01-01
                                        • 1970-01-01
                                        • 1970-01-01
                                        • 1970-01-01
                                        • 2011-11-22
                                        • 1970-01-01
                                        相关资源
                                        最近更新 更多