关于兼容性:为什么我们需要其他JVM语言

关于兼容性:为什么我们需要其他JVM语言

Why do we need other JVM languages

我在这里看到,除了Java之外,在JVM上还运行着许多语言。我对JVM中运行的其他语言的整个概念有些困惑。因此:

为JVM使用其他语言有什么优势?

为JVM编写语言/编译器需要什么(概括而言)?

如何在JVM中以某种语言(Java以外的语言)编写/编译/运行代码?

编辑:在接受的答案中回答了3个后续问题(最初是评论)。为了清晰起见,此处将其重印:

用JPython编写的应用程序如何与Java应用程序交互?

此外,该JPython应用程序可以使用任何JDK函数/对象吗?

如果它是Jaskell代码,那它是一种功能语言会不会使其与JDK不兼容吗?


分别解决您的三个问题:

What is the advantage in having other languages for the JVM?

这里有两个因素。 (1)为什么要为JVM使用Java以外的其他语言,以及(2)为什么要在JVM上运行另一种语言,而不是在其他运行时?

  • 其他语言可以满足其他需求。例如,Java没有对闭包的内置支持,此功能通常非常有用。
  • 在JVM上运行的语言与在JVM上运行的任何其他语言的字节码兼容,这意味着以一种语言编写的代码可以与以另一种语言编写的库进行交互。
  • What is required (in high level terms) to write a language/compiler for the JVM?

    JVM读取字节码(.class)文件以获得其需要执行的指令。因此,要在JVM上运行的任何语言都需要编译为遵循Sun规范的字节码。此过程类似于编译为本机代码,除了将代码编译为由JVM解释的指令,而不是编译为CPU可以理解的指令。

    How do you write/compile/run code in a language (other than Java) in the JVM?

    非常类似于您使用Java编写/编译/运行代码的方式。为了弄湿你,我建议看一下Scala,它可以在JVM上完美运行。

    回答您的后续问题:

    How would an app written in, say, JPython, interact with a Java app?

    这取决于实现方式选择的弥合语言鸿沟。在您的示例中,Jython项目具有执行此操作的简单方法(请参见此处):

    1
    2
    from java.net import URL
    u = URL('http://jython.org')

    Also, can that JPython application use any of the JDK functions/objects?

    是的,请参见上文。

    What if it was Jaskell code, would the fact that it is a functional language not make it incompatible with the JDK?

    不。例如,Scala(上面的链接)在实现功能特性的同时保持了与Java的兼容性。例如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    object Timer {
      def oncePerSecond(callback: () => unit) {
        while (true) { callback(); Thread sleep 1000 }
      }
      def timeFlies() {
        println("time flies like an arrow...")
      }
      def main(args: Array[String]) {
        oncePerSecond(timeFlies)
      }
    }

    出于同样的原因,您需要在JVM上使用其他语言,因为通常需要多种编程语言:不同的语言最好解决不同的问题...静态类型与动态类型,严格类型与惰性类型...声明式,命令式,面向对象...等。

    通常,为在JVM(或.Net CLR)上运行的另一种语言编写"编译器"本质上是将该语言编译为Java字节码(或在.Net,IL的情况下)的问题。到汇编/机器语言。

    也就是说,为JVM编写的许多其他语言都没有编译,而是解释了脚本语言...


    从头开始,请考虑您要设计一种新语言,并希望它在具有JIT和GC的托管运行时中运行。然后考虑您可以:

    (a)编写您自己的托管运行时(VM)并解决各种技术难题,这些问题无疑会导致许多错误,性能下降,线程不正确以及大量可移植性。

    (b)将您的语言编译为可以在Java VM上运行的字节码,该Java VM已经非常成熟,快速并且在许多平台上受支持(有时具有多种供应商选择)。

    鉴于JavaVM字节码与Java语言之间的联系并不紧密,以至于过分地限制了您可以实现的语言类型,因此它一直是要在VM中运行的语言的流行目标环境。


    Java是一种相当冗长的编程语言,在过去的5年中,随着所有新的流行语言/框架的出现,它已经非常过时。为了支持人们想要的一种语言中所有花哨的语法并保持向后兼容性,向运行时添加更多语言更加有意义。

    另一个好处是,它使您可以在经过验证的托管平台上运行一些用Ruby ala JRuby(又名Rails)或Grails(本质上是Railys上的Groovy)编写的Web框架,而不是使用几乎不像经过尝试和测试的Ruby托管环境那样。

    要编译其他语言,您只需将其转换为Java字节码。


    我会回答,"因为Java很烂",但是话又说回来,这也许太明显了……;-)


    针对不同任务量身定制了不同的语言。尽管某些问题领域非常适合Java语言,但有些领域用替代语言表达起来要容易得多。同样,对于习惯于Ruby,Python等的用户而言,生成Java字节码并利用JDK类和JIT编译器的功能也具有明显的优势。


    回答第二个问题:

    JVM只是一个抽象机器和执行模型。因此,使用编译器作为目标与编译器可能针对的任何其他机器和执行模型相同,无论是在硬件(x86,CELL等)中实现还是在软件(parrot,.NET)中实现。 JVM非常简单,因此对于编译器而言,它实际上是一个相当容易的目标。而且,实现往往会有相当不错的JIT编译器(以处理javac生成的糟糕代码),因此您无需担心很多优化即可获得良好的性能。

    有两个警告。首先,JVM直接体现了Java的模块和继承系统,因此尝试执行其他任何操作(多次继承,多次调度)可能很棘手,并且需要复杂的代码。其次,对JVM进行了优化,以处理javac生成的字节码。产生与此完全不同的字节码很可能会进入JIT编译器/ JVM的奇怪角落,这在最好的情况下可能效率低下(最坏的情况是,它们可能使JVM崩溃或至少给出虚假的VirtualMachineError异常)。


    为JVM使用其他语言的优势与通常为计算机使用其他语言的优势完全相同:虽然所有图灵完备的语言在技术上都可以完成相同的任务,但某些语言使某些任务比其他语言更容易,而其他语言使其他任务更加容易。由于JVM是我们已经具备的能力,因此我们已经能够在所有(几乎所有)计算机上运行,??并且事实上,许多计算机已经具有JVM的功能,因此我们可以获得"一次编写,可在任何地方运行"的好处,但是不需要使用Java的人。

    为JVM编写语言/编译器与为真实机器编写语言/编译器并没有什么不同。真正的区别在于,您必须编译为JVM的字节码,而不是机器的可执行代码,但这实际上在宏伟的设计方案中只是很小的差异。

    在JVM中为Java以外的语言编写代码与编写Java确实没有什么不同,当然,除了您将使用另一种语言之外。您将使用有人为其编写的编译器进行编译(再次,与C编译器基本没有太大不同,与Java编译器几乎没有任何不同),最终您将能够运行它就像您要编译Java代码一样,因为一旦将Java代码转换为字节码,JVM就无法分辨它来自哪种语言。


    JVM的功能由JVM的字节码(在.class文件中找到的内容)而不是源语言定义。因此,更改高级源代码语言不会对可用功能产生重大影响。

    对于为JVM编写编译器所需的工作,您真正需要做的就是生成正确的字节码/ .class文件。使用替代编译器的方式来编写/编译代码的方式取决于所讨论的编译器,但是一旦编译器输出.class文件,则运行它们与运行javac生成的.class文件没有什么不同。


    这些其他语言的优点是它们可以相对轻松地访问许多Java库。

    根据语言的不同,Java员工的优势也各不相同-每个人都有一个故事,向Java编码人员讲述他们的优势。有些人会强调如何使用它们将动态脚本添加到基于JVM的应用程序中,而另一些人只是在谈论他们的语言如何更易于使用,语法更好等等。

    编写其他任何语言的编译器都需要做同样的事情:解析为AST,然后将其转换为目标体系结构的指令(字节代码)并将其以正确的格式(.class文件)存储。

    从用户的angular来看,您只需编写代码并运行编译器二进制文件,然后便可以生成.class文件,您可以将其与Java编译器生成的文件混在一起。


    .NET语言比实际用途更多地用于显示。每种语言都如此残酷,以至于它们都是带有新面孔的C#。

    出于多种原因为Java VM提供替代语言:

    • JVM是多平台的。移植到JVM的任何语言都可以免费获得。
    • 那里有很多遗留代码。诸如ColdFusion之类的过时引擎在提供更好的性能的同时,还为客户提供了将其应用程序从传统解决方案缓慢过渡到现代解决方案的能力。
    • 某些形式的脚本更适合快速开发。例如,JavaFX在设计时考虑了快速的图形化开发。这样,它就可以与DarkBasic等引擎竞争。 (处理是该空间中的另一个参与者。)
    • 脚本环境可以提供控制。例如,应用程序可能希望向用户公开类似VBA的环境,而不公开基础Java API。使用像Rhino这样的引擎可以提供一个环境,该环境支持在受严格控制的沙箱中进行快速而肮脏的编码。
    • 解释过的脚本意味着无需重新编译任何内容。无需重新编译就可以转化为更加动态的环境。例如尽管OpenOffice将Java用作"脚本语言",但Java确实吸引了这种使用。用户必须经历各种动态脚本环境(如Javascript)中不必要的重新编译/重新加载回转。
    • 这使我想到了另一点。脚本引擎可以更轻松地停止和重新加载,而无需停止和重新加载整个JVM。由于可以随时重置环境,因此增加了脚本语言的实用性。

    Java已经在七个主要版本(从1.0到1.6)上积累了庞大的用户基础。保持向后兼容性以支持生产中运行的无数百万行Java代码的行数限制了它的发展能力。

    这是一个问题,因为Java需要发展为:

    • 与从Java的成功和失败中学到的新型编程语言竞争。
    • 结合了编程语言设计的新进展。
    • 允许用户充分利用硬件的优势-例如多核处理器。
    • 修复了一些引入了意料之外的问题(例如,检查过的异常,泛型)的尖端思想。

    向后兼容性的要求是保持竞争力的障碍。

    如果将Java与C#进行比较,则Java在成熟的,可立即投入生产的库和框架中具有优势,而在语言功能和市场占有率增长方面则具有劣势。这是通过比较两种相距一代的成功语言所期望的。

    任何一种新语言都具有与C#相比Java极高的优势和劣势。在语言功能方面最大化优势并在成熟的库和框架方面实现劣势最小化的一种方法是为现有虚拟机构建语言,并使该语言可与为该虚拟机编写的代码互操作。这就是Groovy和Clojure取得不大成功的原因。和Scala周围的激动。没有JVM,这些语言只能在非常专业的细分市场中占据一席之地,而有了JVM,它们就会在主流市场中占据重要地位。


    对于编译器编写器而言,生成JVM或CLR字节码要容易得多。与任何机器语言相比,它们是一种更干净,更高级的抽象。因此,尝试创建新语言比以往任何时候都更可行,因为您要做的只是针对这些VM体系结构中的一种,并且您将拥有适用于您的语言的一组工具和库。他们使语言设计人员可以将注意力集中在语言上,而不是所有必需的支持基础结构。


    由于JSR流程使Java越来越死:http://www.infoq.com/news/2009/01/java7-updated

    可惜的是,甚至没有因为成员无法就实现达成共识而添加诸如Closures之类的必不可少的和众所周知的附加内容。


    他们这样做是为了跟上.Net的步伐。 .Net允许C#,VB,J#(以前),F#,Python,Ruby(即将推出)和c。我可能想念一些。对于脚本编写人员来说,可能是其中最大的Python。


    原因是JVM平台具有很多优势。

    • 数量庞大的图书馆
    • 平台范围更广
      实作
    • 成熟的框架
    • 旧版代码
      已经是您基础架构的一部分

    Sun尝试通过其脚本规范支持的语言(例如Python,Ruby)应运而生,并且在很大程度上归功于它们的生产力提高。从理论上说,运行Jython可以提高生产力,并利用Python的功能解决更适合Python的问题,但仍可以在运行时级别上与现有代码库集成。 Python和Ruby的经典实现对C库具有相同的功能。

    此外,用动态语言表达某些内容通常比用Java表示容易。如果是这种情况,则可以采用其他方法。使用Java中的Python / Ruby库。

    这会带来性能上的损失,但是许多人都愿意接受它,以换取更简洁,更清晰的代码库。


    在某种程度上,它可能是对抗.NET CLR的"军备竞赛"。

    但是我认为将新语言引入JVM也是有??真正原因的,特别是当它们"并行"运行时,您可以使用正确的语言来完成正确的工作,像Groovy这样的脚本语言可能正是您需要页面演示,而常规的旧Java更适合您的业务逻辑。

    我要让更有资格的人谈论编写新语言/编译器的要求。

    至于如何编写代码,您可以像往常一样在记事本/ vi中编写代码! (或者,如果您想以简单的方式使用它,请使用支持该语言的开发工具。)编译将需要一种特殊的语言编译器,以便将其解释并编译为字节码。

    由于Java在技术上也生成字节码,因此您无需执行任何特殊操作即可运行它。


    推荐阅读