IT技术博客大学习 共学习 共进步

程序语言之争与Java社区文化

游啊游,淡定、淡定 (微薄@zhh-2009) 2013-03-11 13:21:03 浏览 3,041 次

   早几年有Ruby粉抨击设计模式,如今王垠又来,还有各种框架之争、平台之争,不计其数,

   争吵到最后又归结到程序语言问题,最后程序语言问题又归结为两个: 1.语言A能做的语言B能做吗? 2.如果都能做哪个做起来更方便?

   对于问题1,我不想用看似高深的计算理论、图灵机来证明,大家都爱听类似王垠的大白话。

   好,我们都知道Java、Groovy、Scala写的程序都能运行在JVM平台上,

   Java是静态语言、Groovy是动态语言、Scala即是静态语言又是函数式语言,

   所以各种语言类型都包含了,

   三种语言之所以能运行在JVM之上,是因为在运行之前转换成了一种中间语言,即符合classfile规范的字节码(叫它L吧),

   所以: Java = L; Groovy = L; Scala = L 推出 Java = Groovy = Scala,即问题1一定为真。

   对于问题2目前没有人知道答案,王垠也没给出严格证明。

   但是我们还是可以从技术和非技术两方面聊聊这问题

1.技术层面

动态与静态

   以Groovy、Ruby、Python为代表的动态语言无须类型声明,

   而以C/C++/Java为代表的静态语言则需要类型声明,

   也就是说静态语言做同样一件事至少要比动态语言多一步,

   比如,算a+b的和,对于静态语言来说你必须先说明a、b是int还是long还是其他类型,

   但是事物总是有两面性,有好的一面通常也有坏的一面,

   比如,如果a是10,而b是一条狗,a和b能相加吗? 静态语言能够在编译期提前检测出可能的错误,

   而动态语言需要到运行时才发现。

visitor模式与模式匹配

   王垠现在的研究方向是“程序设计语言”,说到visitor模式与函数式语言的模式匹配也可以从两方面来思考。

   visitor模式在编译器实现和SQL Parser中有大量运用,

   下面的代码就是摘取自Javac的部分源代码:

public abstract class Visitor {
	public void visitTopLevel(JCCompilationUnit that) {
		visitTree(that);
	}
	public void visitImport(JCImport that) {
		visitTree(that);
	}
	public void visitTree(JCTree that) {
		assert false;
	}
}

public abstract class JCTree {
	public abstract void accept(Visitor v);
}

public class JCCompilationUnit extends JCTree {
	public void accept(Visitor v) { 
		v.visitTopLevel(this); 
	}
}

public static class JCImport extends JCTree {
	public void accept(Visitor v) {
		v.visitImport(this); 
	}
}

   而这个“一门天生就能损害人眼视力的语言->Erlang"是我在2008年原本发在JavaEye上的文章(当年年轻不懂事),

   目前在JavaEye上找不到了,这个是别人转发的其中很小的一部分。

   文章中有大量使用Erlang模式匹配的代码,

   模式匹配的分枝数大致与Visitor类的visit方法个数相等,

   当分枝数很少时(比如不到5个),显然模式匹配的方式更省事,而Java版的visitor模式要定义很多类,

   但是,当分枝数很多时(编译器的Parser得到的AST的节点数通常不少于20个),

   对比Erlang的代码,你能分清两者哪个更好吗?这完全取决人的好恶问题。

   我们还能举出大量的例子,但是总有一些情况能证明一方好另一方坏,

   所以,当好处与坏处综合一起考量时,谁能证明谁更好?

2.非技术层面

语言特性多点好还是少点好?

   语言特性少对于语言设计者和编译器实现者都少了很多工作量,保持语言简单,IDE的开发者也轻松,

   对于初学者也容易入门。但是,有时也正因为缺少一些特性,所以开发者抱怨一门语言需要写很多代码,

   比如最常提到的就是Java没有闭包,而JavaScript、Ruby中的闭包用得很爽。

   还有Java总是动不动就要敲一堆骨架代码(setter、getter等等),

   可是借助于IDE这些都是可以自动生成的。

把语言层的东西抽离到库和框架?还是反过来?

   这个问题更值得讨论,

   C#是Anders Hejlsberg的玩具,Anders Hejlsberg喜欢在C#中加各种特性,

   比如LINQ就是一个很好的例子,而Java并不这么做,交给框架去做吧,比如Hibernate、iBatis。

   更有趣的是Hibernate还有.NET的版本NHibernate,NHibernate在.NET社区也很流行,

   为什么在C#中有了LINQ还要NHibernate呢?如果LINQ真的足够好还需要其他框架吗?

   如果其他框架能流行反过来证明在语言中集成过多特性并不是一个好的方式。

最后,我们再来谈谈Java的文化

   世界人口很多,如今各种层次的码农加起来也很多,

   如何让他们都有活干,如何发挥各种码农的特长,如何让各层次的码农和谐相处?

   我认为Java在所有语言中是表现最好的,

   正因为Java设计得简单死板,也没加太多特性,给IDE开发者带来了方便,

   也给上层框架开发者有更多发挥的空间,用IDE、库、框架来弥补语言的不足,

   因为框架的繁荣进一步形成了良好的社区,应用开发者使用框架来开发业务系统,

   Java的规范又使得业务团队能更好协作。

   所以从语言设计者到IDE开发者、框架开发者,最后到应用开发者每个人都在发挥自己的优势,

   每个层次的开发者都能找准自己的位置。

   俗话说“君弱臣强、君强臣弱”,君可以弱,但只要不是昏君,有足够的强臣,这并不伤国体,

   Java语言和Java社区就是君弱臣强,

   而C#语言和微软社区就是君强臣弱,

   但是你会发现微软社区也开始流行框架了,

   君强容易演变成专制,而社区成员变成了盲从,缺乏创造力。

建议继续学习

  1. 每个程序员都应该学习使用Python或Ruby (阅读 17,741)
  2. 敲击最多的键和编程语言语法 (阅读 7,302)
  3. 为什么Lisp语言如此先进?(译文) (阅读 6,402)
  4. 编程语言的选择很重要 (阅读 5,122)
  5. 编程语言的可读性 (阅读 4,962)
  6. PHP很烂?我的看法 (阅读 4,501)
  7. php语言漫谈 (阅读 4,182)
  8. 几种计算机语言的评价(修订版) (阅读 4,141)
  9. 分清“语言/规范”以及“平台/实现”,以及跨平台.NET开发 (阅读 4,143)
  10. 为什么我喜欢Lisp语言 (阅读 3,921)