维基百科说Ruby是一种功能语言,但我不相信。为什么或为什么不呢?
答案 0 :(得分:57)
语言是否是函数式语言并不重要。功能编程是一篇论文,由Philip Wadler(功能编程的本质)和John Hughes(为什么功能编程事项)最佳解释。
一个有意义的问题是,'Ruby如何能够实现函数式编程的论点?'答案是“非常糟糕”。
我刚才就此发表了演讲。 Here are the slides.
答案 1 :(得分:34)
Ruby确实支持更高级别的功能(参见Array#map,inject和& select),但它仍然是一种必要的,面向对象的语言。
功能语言的一个关键特征是它避免了可变状态。函数式语言没有像Ruby,C,Java或任何其他命令式语言那样的变量概念。
功能语言的另一个关键特征是它侧重于用“什么”而不是“如何”来定义程序。当用OO语言编程时,我们编写类&从“what”(类/方法名称)隐藏实现(“how”)的方法,但最后这些方法仍然使用一系列语句编写。在函数式语言中,即使在最低级别,也不指定执行顺序。
答案 2 :(得分:29)
我绝对认为你可以在Ruby中使用功能样式。
能够以函数式编程的最关键方面之一是语言是否支持更高阶函数...... Ruby就是这样。
也就是说,在Ruby中以非功能性方式编程也很容易。功能样式的另一个关键方面是没有状态,并且具有对于给定输入集总是返回相同值的真实数学函数。这可以在Ruby中完成,但它并没有在像Haskell这样功能更严格的语言中强制执行。
所以,是的,它支持功能风格,但它也可以让你以非功能风格编程。
答案 3 :(得分:15)
我认为支持或能够使用功能风格的语言进行编程并不是一种功能性语言。
如果我想伤害我的同事,我自己甚至可以用函数式编写Java代码,而且我自己几个星期<罢工>
周。拥有一种功能语言不仅仅是你可以能做什么,比如高阶函数,一流函数和currying。它也与你不能做的事情有关,就像纯函数中的副作用一样。
这很重要,因为它是函数式程序或者函数代码更易于推理的重要原因。当代码更易于推理时,错误会变得更浅,并浮动到可以修复它们的概念表面,从而减少错误代码。
Ruby的核心是面向对象的,所以尽管它对功能风格有相当好的支持,但它本身并不是一种功能语言。
无论如何,这是我的非科学意见。
修改强> 回想起来,考虑到我到目前为止收到的这个答案的精美评论,我认为面向对象与功能的比较是苹果和橘子之一。
真正的区别在于在执行中是否具有比较性。函数式语言将表达式作为其主要语言结构,执行顺序通常未定义或定义为惰性。可以严格执行,但仅在需要时使用。在一种比较严格的语言中,严格执行是默认的,虽然延迟执行是可能的,但它通常很难做到,并且在许多边缘情况下会产生不可预测的结果。
现在,那是我的非科学意见。
答案 4 :(得分:11)
Ruby必须满足以下要求才能成为&#34; TRUELY&#34;功能
不可变值:一旦设置了“变量”,就无法更改。在Ruby中,这意味着您必须有效地处理变量,如常量。语言不完全支持,您必须手动冻结每个变量。
没有副作用:当传递给定值时,函数必须始终返回相同的结果。这与具有不可变的价值观密切相关;函数永远不会取值并改变它,因为这会导致副作用与返回结果相关。
高阶函数:这些函数允许函数作为参数,或者使用函数作为返回值。可以说,这是任何功能语言最重要的特征之一。
Currying:由高阶函数启用,currying正在转换一个函数,该函数将多个参数转换为带有一个参数的函数。这与部分函数应用程序密切相关,部分函数应用程序将多参数函数转换为一个函数,该函数比原来的参数少。{/ p>
递归:通过从内部调用函数来循环。当您无法访问可变数据时,递归用于构建和链数据构造。这是因为循环不是一个功能概念,因为它需要传递变量以在给定时间存储循环的状态。
延迟评估或延迟评估:延迟值的处理,直到实际需要它为止。举例来说,如果你有一些代码生成了启用了延迟评估的Fibonacci数列表,那么实际上不会处理和计算这个代码,直到另一个函数需要结果中的一个值,例如puts。
提案(只是一个想法)
如果有一个mode
指令来声明具有功能范例的文件,我会很高兴有一些定义,例如
模式&#39;功能性&#39;
答案 5 :(得分:10)
Ruby是一种支持函数式编程风格的多范式语言。
答案 6 :(得分:4)
Ruby是一种面向对象的语言,可以支持其他范例(功能,命令等)。但是,由于Ruby中的所有内容都是一个对象,因此它主要是一种OO语言。
示例:
“hello”.reverse()=“olleh”,每个字符串都是一个字符串对象实例,依此类推。
答案 7 :(得分:4)
这取决于您对“功能语言”的定义。就个人而言,我认为当用作绝对术语时,这个术语本身就很成问题。作为一种“功能语言”而不仅仅是语言功能,更多的方面取决于您所处的位置。例如,围绕语言的文化在这方面非常重要。它是否鼓励功能风格?可用的库怎么样?他们是否鼓励您以功能性的方式使用它们?
例如,大多数人会将Scheme称为功能语言。但Common Lisp怎么样?除了多/单命名空间问题和保证尾部调用消除(一些CL实现也支持,取决于编译器设置),没有太多使得Scheme作为一种语言更适合函数式编程而不是Common Lisp,而且,大多数Lispers都不会将CL称为函数式语言。为什么?因为围绕它的文化在很大程度上取决于CL的命令性特征(例如,大多数Schemer可能会皱眉的LOOP宏)。
另一方面,C程序员可能会认为CL是一种功能语言。毕竟,用任何Lisp方言编写的大多数代码在风格上都比通常的C代码块更具功能性。同样,与Haskell相比,Scheme是一种必要的语言。因此,我认为不会有明确的是/否答案。是否将语言称为功能性取决于您的观点。
答案 8 :(得分:2)
我认为Ruby也不是一种多范式的语言。多范式倾向于被想要将他们喜欢的语言标记为在许多不同领域有用的东西的人使用。
我将描述Ruby是一种面向对象的脚本语言。是的,函数是第一类对象(类型),但这并不能使它成为一种函数式语言。 IMO,我可能会补充一下。
答案 9 :(得分:2)
递归在函数式编程中很常见。几乎任何语言都支持递归,但如果没有tail call优化(TCO),递归算法通常是无效的。
函数式编程语言能够优化尾递归,并且可以在恒定空间中执行此类代码。一些Ruby实现确实优化了尾递归,另一些则没有,但通常Ruby实现不需要进行TCO。见Does Ruby perform Tail Call Optimization?
因此,如果您编写一些Ruby函数样式并依赖某些特定实现的TCO,那么您的代码在另一个Ruby解释器中可能非常无效。我认为这就是为什么Ruby不是一种函数式语言(也不是Python)。
答案 10 :(得分:2)
严格地说,将语言描述为“功能性”是没有意义的;大多数语言都能够进行函数式编程。甚至C ++也是。
功能样式或多或少是命令式语言特性的一个子集,支持语法糖和一些编译器优化,如不变性和尾递归展平,
后者可以说是具体的实现特定技术性,与实际语言无关。 x64 C#4.0编译器执行尾递归优化,而x86则不会出于任何愚蠢的原因。
语法糖通常可以在某种程度上解决,特别是如果语言有可编程的预编译器(即C的#define)。
要问,“语言__支持命令式编程吗?”可能稍微有点意义,而答案,例如使用Lisp,是“不”。
答案 11 :(得分:1)
请看一下本书的开头:"A-Great-Ruby-eBook"。它讨论了您要问的非常具体的主题。您可以在Ruby中执行不同类型的编程。如果你想像功能一样编程,你可以做到。如果你想像命令一样编程,你可以做到。这是一个定义问题,最终功能Ruby是如何实现的。请查看用户camflan的回复。