ruby特点,RUby什么意思

  ruby特点,RUby什么意思

  为什么Ruby是一个流行的LISP?

  为什么Ruby是一个流行的LISP?

  翻译于2007年8月13日04: 55: 38 已有7441人查看过它 4人对它发表过评论。

  几年前,我考虑过Ruby,决定忽略它。Ruby没有Python流行,也没有LISP强大。我为什么要把时间花在这上面?当然,我们可以反过来考虑这件事。如果Ruby比LISP流行,比Python强大怎么办?这足以让Ruby变得有趣吗?在回答这个问题之前,我们应该确定是什么让LISP如此强大。保罗格拉厄姆已经写了一些令人信服的文章来说明LISP的优点。出于讨论的目的,我将这些文章的内容总结为两点:*LISP是一种紧凑的函数式语言。*LISP有可编程的宏。正如您将在下面看到的,Ruby也是一种函数式语言,它比我想象的更好地模拟了宏。Ruby是一种比LISP更紧凑的函数式语言。简洁的语言可以让你简洁而明确地表达你的意思。一眼就能看出来。

  几年前,我考虑过Ruby,决定忽略它。Ruby没有Python流行,也没有LISP强大。我为什么要把时间花在这上面?

  当然,我们可以反过来考虑这件事。如果Ruby比LISP流行,比Python强大怎么办?这足以让Ruby变得有趣吗?

  在回答这个问题之前,我们应该确定是什么让LISP如此强大。保罗格拉厄姆已经写了一些令人信服的文章来说明LISP的优点。为了便于讨论,我将这些文章的内容归纳为两点:

  LISP是一种紧凑的函数式语言。

  LISP有可编程的宏。

  正如您将在下面看到的,Ruby也是一种函数式语言,它比我想象的更好地模拟了宏。

  Ruby是一种比LISP更紧凑的函数式语言。

  简洁的语言可以让你简洁而明确地表达你的意思。一眼就能看到更多的程序,再也没有bug藏身的地方了。达到一定程度后,让你的程序更紧凑的唯一方法就是使用更强大的抽象。

  lambda是一个特殊而强大的抽象概念。使用lambda,您可以立即创建一个新函数并将其传递给其他函数,甚至可以保存它以备后用。例如,如果您想将表格中的每个数字加倍,您可以写:

  (mapcar(lambda(n)(* n ^ 2))我的列表)

  Mapcar通过转换mylist中的每个元素来构建新的列表。在这个例子中,这个转换可以理解为“对于每个值n,乘以2。”在JavaScript中用function替换lambda可能更清楚:

  map(function (n) { return n * 2 },mylist)

  当然,这只是提示您可以使用lambda做些什么。喜欢这种编程风格的语言被称为函数式语言,因为它们使用函数。一旦你学会阅读一个用紧凑的函数式语言编写的程序,你会发现它真的简洁明了。

  Ruby在函数式编程中如何与Lisp竞争?让我们考虑一个保罗格拉厄姆的经典例子,一个函数,并建立一个累加器:

  (defun foo(n)((I)(incf n I)))

  如果用Ruby编写,这段代码会更短,并且C用户会更熟悉这种写法:

  def foo(n) lambda {i n=i} end

  acc=foo 3

  根据呼叫(1) # - 4

  acc.call(10) # - 14

  acc.call(0) # - 14

  但是Ruby中有一个有趣的特例,它允许我们输入更少的单词。考虑一个需要作为参数的(非常愚蠢的)函数:

  $对每个自然数调用一次“fn”。

  (defun每个自然数(fn)

  (从1 do开始循环n(funcall fn n)))

  $打印1,2,3.

  (每个自然数

  (lambda (n)(格式t ~D~% n)))

  现在,我们可以用Ruby编写相同的函数:

  定义每个自然数(fn)

  n=0

  loop { fn.call(n=1) }

  目标

  each _ natural _ number({ n puts n })

  但是我们可以做得更好。让我们用yield代替lambda和fn:

  定义每个自然数

  n=0

  循环{产量n=1 }

  目标

  每个自然数{n puts n }

  是的,yield是一种有特定目的的技能,它只在那些需要单个lambda的函数中起作用。但是在高功能代码中,yield对我们很有帮助。比较:

  [1,2,3].映射{n n*n }。拒绝{n n%3==1 }

  (remove-if (lambda (n) (=(mod n 3) 1))

  (mapcar (lambda (n) (* n n))

  (1 2 3)))

  在一个大型程序中,这很重要。(LISP的论点是,你可以写一个reader宏,让lambda更简洁。但是很少有人知道。)

  Ruby可以给你几乎80%你想要的宏。

  对此,LISP用户会说:“lambda的语法很棒,但是宏呢?”这是一个好问题。LISP宏是一个函数,并且:

  由编译器运行

  将自定义语法转换成原始LISP。

  宏最常见的用途是避免键入过多的lambda:

  (每个自然数的defmacro表达式)

  `(每个自然数((,n),expr)))

  (每个自然数n

  (格式t ~D~% n))

  Defmacro定义了一个需要一个列表作为参数的函数,并返回另一个列表。在这个例子中,每次编译器看到-each-natural-number时都会调用我们的宏。它使用LISP的“反引号”语法从模板快速构造一个列表,并替换N和expr。然后,该列表被传递回编译器。

  当然这个宏在Ruby中是没用的,因为Ruby中没有这个宏要解决的问题。

  宏的第二个最常见的用途是通过构建小型语言来定义事物:

  $生成一些到我们数据库的绑定

  $使用假设的“LISP on Rails”

  (定义模型顺序()

  (属于客户)

  (有-多项:依赖?t))

  使用Ruby on Rails,我们可以这样写:

  类别顺序ActiveRecord:Base

  属于_客户

  has_many :items,dependent=true

  目标

  这里,belongs_to是一个类方法。当被调用时,一批成员方法将被添加到顺序中。方法的实现比较难看,但是界面真的很美。

  对任何类似宏的函数的真正测试是迷你语言是否经常被建立。Ruby在这方面取得了不错的成绩:除了Rails,还有Rake(用来写Makefiles)、Needle(连接组件)、OptionParser(解析命令行选项)、DL(与C APIs交互)等等,数不胜数。Ruby程序员用Ruby写任何东西。

  当然,还有很多高级的LISP宏不能简单移植到Ruby中。特别是那些编译迷你语言的宏还没有出现,尽管有足够的工作使它们成为可能。(Ryan Davis在这个方向做了一些很有前途的工作,ParseTree和RubyInline。我会写一些相关技术的文章。)

  Ruby拥有优秀的库和社区,增长势头良好。

  所以如果LISP还是比Ruby强大,为什么不用LISP呢?反对LISP编程的常见原因有:

  没有足够的图书馆。

  我们不能雇佣LISP程序员。

  LISP已经20年没见过了。

  这些都不是压倒性的理由,但确实值得考虑。

  曾几何时,人们认为Common Lisp标准库过于庞大。然而今天,人们苦于它的体积小。Java的手册可以填满一面墙,Perl的CPAN档案有可以满足你能想象的任何目的的模块。相比之下,Common Lisp连网络通信的标准方法都没有。

  同样,LISP程序员也太少了。如果你在波士顿附近,有一小群黑客可以创造出神奇的灰发。在其他地方,渴望成功的年轻黑客们分散了。LISP永远是小众语言。

  另一方面,Ruby越来越受欢迎。最大的动力似乎是始于2004年末的Rails。如果你想开一家公司,每个可能的员工都是Rails的粉丝已经很普遍了。Rails将很快被整合到一般的web开发中,并最终从中产生巨大的商机。

  Ruby已经花了足够多的时间来开发一个优秀的标准库和大量的附加库。如果你需要下载网页,解析RSS,生成图形或者调用SOAP API,你需要的一切都已经做好了。

  现在,如果你必须在强大的语言和流行的语言之间做出选择,选择强大的可能会更好。但是如果强大的功能是次要的,那么流行的语言就具备了所有的优势。2005年,我会考虑很长一段时间很难从Ruby中选择LISP。我可能只在需要优化代码时,或者需要宏充当全功能编译器时才这样做。

  (感谢Michael Fromberger审阅了本文的早期草稿。)

ruby特点,RUby什么意思