Java的另一个对手:Mirah

开发 后端
Mirah 满足了我的愿望,执行JRuby,对于非Java开发者,更平易近人。让我们面对现实吧,Java并不是特别难学,但有很多细节需要时间来习惯。它不是一个复杂的语言,但它可以吓跑门外汉。Mirah,我想使语言满足我的标准,让我和其他人替换一直想替换的Java。

当你使用Ruby语法,添加静态类型,并在JVM上运行时,发生了什么?Charles Nutter,JRuby的设计师为我们做了展示:

我们很快将有Java 7,支持API的动态调用和改进。我们有很多编程语言可供选择- 一些静态类型,一些是动态类型,...- 这提供了他们自己的独特优势。

我们甚至发现Java本身的一些“小变化“,比如文字列表和字符串开关。我们有任何受管理的Runtime的最大、最强的生态系统,数以百万计的开发者。

但是,缺少了什么东西。没有语言看起来能够取代Java本身。或者说,没有可以充当Java替身。

从Java中学习

让我们看一看标准,我相信我们必须满足替换Java的标准。下面是我的观点,他们都基于大量的使Java获得成功的指导原则。

同等代码下,性能等同于Java

如果我们使用新语言开始写核心库,以及系统级别的代码,它必须像Java做的那样执行准确。我们当然可以尝试更好的表现,但是“等同Java”绝对是最低限度。

没有语言强加的Runtime库

如果使用当前的替代语言的最大的障碍是它们强加于你它们的“锁链”-Runtime库。没有5,10,甚至20M的Jar文件,你写不出"Hello, world" 。复杂的部署,小配置的应用更复杂。甚至更糟糕的,有些语言带有很大的初始化消耗,在加载他们的Runtime的类文件,和/或初始化Runtime状态时。

不要比Java复杂

Java的成功很大程度归功于它的简单。任何语言试图替代它,都要考虑这一点,当然这并不意味着不能比Java强大。

优雅

考虑到所有的积极特征,Java也并不是一个特别美丽的语言。有大量的“仪式“,最简单的程序。类型必须在每个地方声明。少于80个字符根本写不出“Hello,world”,而其他语言可在用20个以下的字符做到。

JVM库的完美整合

取代Java的任何语言必须满足Java的使用案例。这意味着能够定义真正的类,真正的静态方法,真正的数组。从我们的语言到Java,需要被直接调用,使用相同的字节码,并且相比Java编写的同样的调用要更有效率。我们现在使用Java的地方,我们需要使用自己的语言,如果我们不能-我们永远需要堆栈某个地方存在Java。

拓展

现在的语言竞争,要看谁能最简单的设计DSL,谁有最简单的扩展点。扩展Java基本上受限于你可以做什么,用注释和注释处理器。而忘记了有一个灵活的语法 - Java看起来像Java。我们假设的语言需要易于扩展,它需要可以很容易地实验新功能。

是否有可能满足所有这些要求?我相信是的,那就是叫做Mirah的语言。

Mirah 编程语言

Mirah 满足了我的愿望,执行JRuby,对于非Java开发者,更平易近人。让我们面对现实吧,Java并不是特别难学,但有很多细节需要时间来习惯。它不是一个复杂的语言,但它可以吓跑门外汉。Mirah,我想使语言满足我的标准,让我和其他人替换一直想替换的Java。

用代码来解释Mirah更容易理解,看看下面的代码吧!

安装 Mirah

下载最新的zip文件,Mirah Github 下载页面

你可以在里面找到mirah-complete.jar,一些bin脚本for "mirah" 、"mirahc,",一组案例、说明、协议等。

准备开始

Mirah 有清晰、简单的语法。一些非常美丽,你也会发现它非常接近Ruby。

 

  1. puts "Hello, world!" 

我们第一个Mriah程序,利用Mirah命令运行。

 

  1. ~/projects/mirah_play → mirah -e 'puts "Hello, world!"' 
  2. Hello, world! 

 

这里我们使用-e flag执行一行脚本,也可以放入文件中。

 

  1. ~/projects/mirah_play → echo 'puts "Hello, world!"' > hello.mirah  
  2.  
  3. ~/projects/mirah_play → mirah hello.mirah   
  4. Hello, world! 

 

当然我提到Mirah也是一个编译器。在上面的例子,它在执行前快速编译已有脚本。没有runtime库意味着没有解释,所以所有东西在执行前作为JVM字符码结束。我们使用mirah命令生成类文件:

 

  1. ~/projects/mirah_play → mirahc hello.mirah   
  2.  
  3. ~/projects/mirah_play → ls -l Hello.class   
  4. -rw-r--h;r--  1 headius  staff  505 Mar 19 18:49 Hello.class 
  5.  
  6. ~/projects/mirah_play → java Hello  
  7. Hello, world! 

 

这个例子可能最重要。不仅是Mirah为一段代码产生了类文件,而且类文件完全独立。最终的java命令不需要jar文件或类路径。你决定什么依赖来引入到你的程序。

让我们浏览一下Mirah的基本语法。

基础语法

Mirah是静态类型,像Java或Scala一样,但你仅是观察也许不知道。这是因为Mirah采用了一种叫做“local type inference(本地类型推断)“的技术。简单来说,通常可以从Mirah的上下文推断对象,变量和方法调用的类型。像Scala和C#中,您仍然必须声明方法参数; Mirah只是在本地范围内推断出类型。

让我们看看在Java中定义一个简单的方法,并对比Mirah。首先,是Java:

 

  1. public static String hello(String name) {  
  2.   return "Hello, " + name + "!";  

 

Mirah如下:

 

  1. def hello(name:String)  
  2.   "Hello, #{name}!" 
  3. end 

 

这里我们声明了name变量,作为String。因为仅是一行代码是一String,我们知道返回类型一定是String。

如果我们将它放入一个文件,会得到与使用javac同样的结果。

 

  1. ~/projects/mirah_play → cat HelloJava.java   
  2. public class HelloJava {  
  3.     public static void main(String[] args) {  
  4.         System.out.println(hello("world"));  
  5.     }  
  6.  
  7.     public static String hello(String name) {  
  8.         return "Hello, " + name + "!";  
  9.     }  
  10. }  
  11.  
  12. ~/projects/mirah_play → cat hello_mirah.mirah   
  13. def hello(name:String)  
  14.   "Hello, #{name}!" 
  15. end  
  16.  
  17. puts hello("world")  
  18.  
  19. ~/projects/mirah_play → javac HelloJava.java   
  20.  
  21. ~/projects/mirah_play → mirahc hello_mirah.mirah   
  22.  
  23. ~/projects/mirah_play → javap HelloJava  
  24. Compiled from "HelloJava.java" 
  25. public class HelloJava extends java.lang.Object{  
  26.     public HelloJava();  
  27.     public static void main(java.lang.String[]);  
  28.     public static java.lang.String hello(java.lang.String);  
  29. }  
  30.  
  31.  
  32. ~/projects/mirah_play → javap HelloMirah  
  33. Compiled from "hello_mirah.mirah" 
  34. public class HelloMirah extends java.lang.Object{  
  35.     public static void main(java.lang.String[]);  
  36.     public static java.lang.String hello(java.lang.String);  
  37.     public HelloMirah();  

 

Mirah将脚本顶层作为它的“main”主体,定义的方法转变为同样类的静态方法。这允许你有非常轻型的脚本,很干净,并没有runtime依赖。

使用Java库

一个简单的Swing应用

 

  1. import javax.swing.JFrame  
  2. import javax.swing.JButton  
  3.  
  4. class SwingMirah  
  5.   def initialize(title:String, w:int, h:int)  
  6.     @title = title  
  7.     @width = w  
  8.     @height = h  
  9.   end  
  10.  
  11.   def run  
  12.     frame = JFrame.new @title 
  13.     frame.setSize @width@height 
  14.     button = JButton.new "Press me" 
  15.     frame.add button  
  16.  
  17.     button.addActionListener do |event|  
  18.       JButton(event.getSource).setText "Mirah rocks!" 
  19.     end  
  20.  
  21.     frame.setVisible true 
  22.   end  
  23. end  
  24.  
  25. sm = SwingMirah.new("Welcome!"300200)  
  26. sm.run 

 

性能

Mirah与Java的性能对比,使用fibonacci。确实说明两件事:方法调用的性能和整数运算性能- 这都是很难在动态语言进行优化。

 

  1. def fib(a:int):int 
  2.   if a < 2 
  3.     a  
  4.   else 
  5.     fib(a - 1) + fib(a - 2)  
  6.   end  
  7. end  
  8.  
  9. def bench(n:int)  
  10.   n.times do 
  11.     timeStart = System.currentTimeMillis  
  12.     puts "fib(40): #{fib(40)}\nTotal time: #{System.currentTimeMillis - timeStart}" 
  13.   end  
  14. end  
  15.  
  16. bench 3 

 

最终调用fib(40),打印结果,使用插补字符串,与Java对比如何呢?

 

  1. ~/projects/mirah_play → java FibJava  
  2. fib(40): 102334155 
  3. Total time: 883 
  4. fib(40): 102334155 
  5. Total time: 876 
  6. fib(40): 102334155 
  7. Total time: 875 
  8.  
  9. ~/projects/mirah_play → mirah fib.mirah  
  10. fib(40): 102334155 
  11. Total time: 882 
  12. fib(40): 102334155 
  13. Total time: 876 
  14. fib(40): 102334155 
  15. Total time: 878 

 

Mirah与Java的表现完全一致。

更多来自Java的功能

界面定义:

 

  1. import java.util.List  
  2.  
  3. interface Printer do 
  4.   def printAll(a:List)  
  5.     returns void 
  6.   end  
  7. end 

 

我们执行这个界面与Java类似,使用implements 关键字,然而在Mirah, implements在类的body中。

 

  1. class MyPrinter  
  2.   implements Printer  
  3.   def printAll(a)  
  4.     a.each {|element| puts element}  
  5.   end  
  6. end  
  7.  
  8. list = ['foo''bar''baz']  
  9. p = Printer(MyPrinter.new)  
  10. p.printAll(list) 

 

文字列表和地图使用[] 和{} 语法。

 

  1. list = [1,2,3,4]  
  2. list.each {|x| puts x} # prints "1\n2\n3\n4\n" 
  3. map = {'foo' => 'bar'}  
  4. puts map['foo'] # prints "bar" 

 

Mirah,仍然在开发中。但是已经有很多的用户在使用。在Java兼容性方面考虑很有意义。现在Mirah类似于Java 0.9。. 没有泛型或枚举,最小的注释支持,而且大多基本语言功能...但是你有一些封闭的支持,更多的文字量,局部类型推断,等等。我们正在 稳步推进Mirah到1.0版本 ,至少相当于Java 5。我们还将继续改善Mirah的宏观体制和元编程能力,同时认真的从其他的语言中吸取最酷的功能。

责任编辑:金贺 来源: 开源中国社区
相关推荐

2016-12-26 15:23:21

戴尔

2012-01-12 10:09:55

Elementary 思路

2011-11-10 09:46:41

云计算云管理

2018-12-05 09:00:46

DevOps持续交付持续集成

2021-06-16 12:03:49

WindowsLinux游戏

2021-05-29 07:13:26

微软Nobelium网络攻击

2024-01-15 00:35:23

JavaScript框架HTML

2011-11-15 10:16:04

Linux操作系统

2012-03-02 09:22:11

程序员

2017-05-26 18:06:47

2011-11-14 09:41:10

Linux Mint

2010-07-22 09:12:26

2009-04-23 09:42:39

FubuMVCASP.NET MVCMVC

2023-09-19 23:21:48

Python列表

2013-06-28 15:45:52

产品经理

2009-12-11 09:40:40

傲游Chrome OS

2017-07-03 10:55:08

2009-08-04 15:18:11

C# Actor

2009-08-14 00:55:21

C#程序编译

2021-04-15 14:56:21

云计算去中心化
点赞
收藏

51CTO技术栈公众号