周末话题-编程语言之动

时间:2021-07-01 01:29:06
程序员也有自己的信仰,也常常像教徒们为了自己的信仰而战斗一样,在IT 界也从来不缺少这些弥漫着硝烟的战争,有的时候也争的面红耳赤,只是有幸这类争论发生在虚拟的网络上,如果在现实世界恐怕会出命案了。

最近这几年网络上到处散布着编程语言回归的“流言”,大有动态语言颠覆编程界之势,貌似C# 4.o也要凑一下这热闹,加入更多的动态性。从.netJava里纷纷加入对Ruby等动态语言的支持来看好像确实如此。那今天俺们就来聊聊这个编程语言之“动”。

 

自从0607Ruby on Rails的狂风刮过整个社区后,关于编程语言的动静之论从来没有停止过,这股狂风又借Web 2.0猝然升级。在很多人谈到动态编程语言的时候,溢美之辞滔滔不绝。什么优美啊,简单啊,优雅啊,个性啊都劈里啪啦的用上了。

不过,到底什么是动态编程语言,它的优劣何在,和传统静态语言有何不同,恐怕每个人心目中都有一杆秤。今天就让我们畅所欲言吧。

 

什么是动态编程语言

这是一个很难下的定义,我们只有从动态编程语言的特征上去找一些线索。

解释的

从脚本之王小蟒蛇Python,到红宝石Ruby无不表现出解释性这个特征,貌似还没看到过编译型的动态语言。

灵活性

动态语言都很灵活,不然也不能称之为动态了。灵活好像是动态语言的代名词,就因为这个灵活所以现在动态语言越来越受人们的青睐。有人说使用C#,Java这类静态编程语言去编写一个程序,一个普通程序员和一个骨灰级老鸟编写的程序会差不多,而使用动态编程语言去编写,10个人可能会编写出11种风格来。好像不管你怎么写都是正确的,这样就很能体现出一个程序员的“个性”来。

简单

由于它是解释的,还非常灵活,所以用它编写程序非常简单。当你有一个非常好的想法的时候,比如一个算法,如果你想迅速的验证一下,相比而言使用动态语言就好多了,如果用C#这类语言做的辅助工程比算法核心还要多。

函数式编程

大部分动态语言都能进行函数式编程(现在C#利用Lambda表达式也能进行函数式编程了)。函数式编程独有的风格,在实现一些功能的时候用命令式编程语言实现非常麻烦,有的时候甚至是很难实现。因为是用命令式语言你必须一下下的“教”计算机如何去做,而函数式语言你只要告诉计算机你想要什么就可以了。

运行时动态绑定

不管上面的说法到底是不是真的动态语言的特性,但是确实,它们在现代的动态语言里都或多或少的体现了。不过上面几条无能如何都比不了下面这条的重要,也许正是因为这条所以才给这类语言冠以动态吧。就不卖关子了,我就来Show两行ruby代码吧:

#假设在一个游戏里存在一个怪物

class  Monster
  
# 在第一级的时候怪物还只能跑
   def  run
    puts 
" run "
   end
end
但是过了第一级的时候,怪物可以飞了。那就应该给怪物添加飞的方法,如果使用传统的如 C# 等语言,我们也许会创建几个子类,或许我们还可以使用策略模式:将行走,飞等动作都封装成一些策略,然后等到升级后不断的配置。

不过你看看ruby是怎么做的:

# 这里并不是重新定义一个怪物,而是给怪物这个类追加定义
class  Monster
    
# 给怪物类添加了一个新方法fly
     def  fly
      puts 
" fly "
      end
end
现在怪物类又多了一个新的方法了。是不是怪物升级了?

哎呀,不好,怎么程序里所有的怪物都升级了?是呀,你刚才是对怪物类追加定义,所以程序里所有怪物实例都会升级,那有没有办法只对某些实例升级呢?当然可以:

# 实例化一个怪物对象
  monster  =  Monster.new

  
# 怪物等级高于1的时候给怪物添加fly动作(看看,这里是运行时判断了)
   if  monster.degree  >   1
    
# 仅仅给这个怪物实例添加fly方法
     def  monster.fly
      puts 
" fly "
    end
  end  
# 呵呵,我的怪物可以飞了
monster.fly
注意,这个给类或实例添加新方法是在运行的时候进行的,并不是说你把程序停下来,然后重新编译下。如果这还不能说明问题,那看看rails 好了。

也许Rails里面的ActiveRecord模式已经被大家所熟知。假如现在有一个users数据库表,那么就应该对应一个User类,看rails是如何定义这个类的:

class  User  <  ActiveRecord::Base
   end
这样就ok 了,也许有人会问,表里的字段对应的属性呢?它们来自数据库表呢,你将对应的表修改了,这个类的属性也会自动的修改,一切都是动态的,如果没有ruby rails 的这个特性也许就无法表现了吧。

通过上面这个例子,大家看到没,动态语言可以在运行的时候改变自己的结果,比如添加新的方法啊,去掉一些方法啊(这个在JavaScript里也许有人用过吧delete)。多么奇妙的事情。

当然,这个运行时动态绑定用多态也能实现,但多态并没有运行时的去改变一个类的结构:增加方法,去掉方法,多态只是使用方法表的偏移这个东西把方法的调用弄到别的地方去了。

还有人可能会说,我用反射,我用Emit也可以在运行的时候添加代码,但是那多麻烦啊,用动态语言一切都那么自然而然。

 

比较

貌似上面一直在给动态编程语言叫好,但是动态语言也有很多缺点。

由于解释执行,编程语言执行效率一般都无法和这些静态编程语言相提并论。这也使得编程语言在很多方面无法得到应用。也许是人们对编程语言有一些偏见,在一些企业级开发领域难以见到动态编程语言的踪迹。不过这些担心也许是多余的,大名鼎鼎的google很多核心业务就是Python来支援的,国内还有很多大型网站也建立在动态语言之上,比如豆瓣,还有Javaeye就是构建在RubyOnRails上的 (我比较了一下,好像Javaeye的访问量比博客园的更大,服务器好像差不多,博客园的服务器还要稍微好些)

灵活性和复杂性是一把双刃剑,为什么OO里面将面向接口编程放在如此重要的地位?就是接口一般能非常稳定,能给客户代码提供一个稳定的契约,如果像刚才那个ruby那样运行时动态绑定的编写代码,稳定的接口又从何而来?所以动态语言就像小家碧玉,适宜于那种作坊式轻型开发,特别适合于xp的开发过程,而C#,Java之流则更适合于重型的开发方法。当两种不同开发信仰的语言走到一起会发生什么?这个正在今天慢慢的演变,IronRuby,IronPython正在一步一步的走进大家的视野,让我们拭目以待吧。

后记

貌似现在社区正在静悄悄的刮着编程语言回归的风,现在是不是也想在闲暇之余考虑一下学习一门动态语言?

有人说,使用动态编程才能真正的享受编程的乐趣,那个时候你才真的把编程当作一门艺术了,因为你可以随心所欲的编写程序,而不需要看这个规范,那个约束。

各位看官,对动态编程语言有何见解,欢迎发表意见,聊以当作周末闲谈话题了。

 

----------------------------------------------------------------附加-----------------------------------------------------------------

我上面有些言论说的非常欠妥,所以这里致歉一下

 

这是怪怪兄的评论:

Javaeye的Alexa排名是20K开外,cnblogs是4K,你的流量数据哪儿来的?

而且从你说的话,可以得出两种可能性:

1. 你认为解释型、 动态类型检查的语言不比编译型、 静态类型检查的语言慢。

2. 按照Joel他们所说的10倍差距, 你在说博客园程序写得比Javaeye烂20倍。

否则就自相矛盾了啊....。

要说到性能关键的应用最终还是交给C这类东西, Python是最出色的粘结各个部件的胶水之一;这是广泛的共识, 就算到了Google里也不能例外, 因为这是当前现实所决定的。

任何问题都很难说是信仰和宗教的问题, 而是真理与客观的问题...

Ruby/Python本身所采取的形式并没什么不好, 可惜跟随这个风潮所提出的一些说法和倡导的一些理念, 可是离真正的“科学”二字越来越远; 而歪风邪气的传播,却是借助于咱们这些无辜的普通用户。 长久的来看, 对于工程和应用方面, 也是有害的。

总之, 赞成楼主打开话题的做法, 但是提醒一下, 严谨二字还是必不可少的。

------------------------------------------------------------------------------------------------------------------

 

说实话,数据我真的没有深究,只是主观臆断的。我只看了下JavaEye和cnblogs成立的时间就主观的臆断javaeye的访问量大于博客园的,但是通过alexa排名,博客园的排名远远超过javaeye的,我的这个数据凭据非常可笑,谢谢怪怪兄的善意批评。做学问严谨二字应该时常放在心头,这一点实在没有做到,所有的言辞必须有真实的数据作为支撑。