如果我决定像Haskell一样编写所有Ruby,可以吗?


10

鉴于Ruby具有内置的良好列表操作功能-减少,映射,选择,收集等。它具有Procs,Blocks和Lambdas,并且具有良好的迭代支持(该each系列),如果我尝试这样做会是一个错误的设计决定以最纯功能的方式编写我所有的Ruby内容?尤其是对于几乎没有I / O的代码(因此不太明显的副作用)?

我一直在学习Haskell(称为“真正的”黑客语言),并且喜欢它的做事方式-我爱Ruby,但是当更多的Haskell精神融入其中时,它可能会变得更加有趣(嗯,没有露比不是一开始就从它那里学到很多东西吗?)

欢迎提供建设性的指导...


13
那么为什么不只写Haskell呢?

1
我会单独用Haskell编写,但是Ruby并不坏,值得完全抛弃。我喜欢在编写脚本时可以使用它的事实,并且对于许多快速实验,我喜欢在学习AI知识时一起学习。但也可能是因为我刚刚开始学习Haskell,最终可能会遵循您的建议:-)
nemesisfixx 2011年

2
我不明白您为什么要请求Stack Overflow的许可。如果您要编写要与团队中的其他人共享的代码,则无论如何都必须协调您的编码样式。否则,这有什么关系?
Mike Daniels

为什么要问呢?因为我尊重经验丰富的黑客和程序员的诚实意见。使用纯功能性方法进行编程可能会有好处,有经验的头脑可能能够与我(以及其他类似我的人)分享。
nemesisfixx 2011年

考虑到存在“否”的客观原因,这是一个合理的问题。
安德鲁·格林

Answers:


16

我一直在用python做这个。我发现用遗传性纯函数式风格编写的语言不是针对此语言设计的,这很麻烦。例如,对比in_order的两个定义:

def in_order(xs):
    for i in range(1,len(xs)):
        if xs[i] > xs[i+1]:
            return False
    return True

inOrder :: (Ord a) => [a] -> Bool
inOrder xs = and $ zipWith (<=) xs (tail xs)

in_order用python 写Haskell方式既冗长(因为python不能很好地支持必要的惯用语),又很慢(由于懒惰,线性空间代替了Haskell的恒定空间)。

但是,我已经成功创建了具有功能组织的 python程序,并且每个功能都有惯用的实现。认为这是一种很好的编程方式的想法实际上是我的代码目录项目的主题。因此,我的组件面向的是在其上操作的抽象和函数(具有纯接口),而不是带有状态的类,并且它们组合得很好。实际上,用这种方式组织的代码似乎比使用类组织的代码更灵活地重用。但是,这可能是个人偏见,因为我仍然是Haskell的奉献者。

因此,我想说您的问题的答案有点。用您的功能根源来帮助您思考,但不要过度使用。例如。仅仅为了成语而在Ruby中模拟懒惰列表可能会比它值得的麻烦更多。


您的描述使我想起了帕斯卡。
rasjani 2011年

@rasjani,哦?有什么原因吗?

我不知道,也许是因为它对英语的理解不够好,或者您所描述的内容与帕斯卡单位的排列方式/结构无关。只是一种心理上的联系,由于首选,您可能没有任何真正的联系;)
rasjani 2011年

1
陈述“由于懒惰而不是Haskell的常数空间而不是线性空间”是不正确的。懒惰仍然意味着线性顺序。我理解你的意思。

3
@aromero,不过我听不懂你的话。订单与它有什么关系?来自Haskell垃圾的恒定空间来自and消耗比较表的头部; 它的行为就像一个循环。相比之下,python的比较列表必须完整生成and(除非您使用生成器...我想这是可能的),否则的模拟将看不到它们中的任何一个。

7

您可以按功能样式编写Ruby代码,就好像它是Scheme而不是Haskell。要像Haskell一样编写它,就需要一个类似Haskell的类型系统,以及普遍的惰性评估。


1

我发现了解函数式编程,尤其是Haskell,对于在Ruby中遇到的某些情况对我有帮助。但是我对Haskell的了解越多,我越能意识到Ruby与Haskell完全相距甚远。

一方面,模块/代码的加载情况非常糟糕。当前的解释器未启用尾部调用优化,因此您不能像在Haskell中那样使用递归。一旦进入Monads,您实际上就无法在Haskell与Ruby中获得抽象级别的比较。

如果您有兴趣,我在学习的过程中会在gist.github.com上发布一些Ruby / Haskell比较代码。

我带给Ruby的最好的技术就是在我能找到的地方找到纯函数,这听起来就像您正在尝试做的那样。


在我的Smalltalk测试之一中:self assert: ((m >>= f) >>= g) equals: (m >>= [:x | (f value: x) >>= g])。根本没有理由为什么您不能有意识地使用monad,而不是甚至在不知道您正在使用monad的情况下就使用它们(如列表)。
Frank Shearar

0

我会说“是”。(我认为)您所谈论的是红宝石语言中的函数式编程影响。功能范式具有一些非常好的概念,可以与面向对象相辅相成或重叠(特别是没有副作用)。

红宝石的伟大之处在于它允许您以线性,面向对象或功能的样式或它们的某种混合形式进行编码。而且,如果复杂度增加,您的简单线性脚本可以变成OO /功能样式。


0

这取决于您是否将与他人合作。如果您自己编写代码,请使用您最喜欢的任何样式。但是,如果您正在与其他Ruby程序员一起工作,则它们可能不习惯于纯粹的函数式编程风格,因此可能会使您的代码感到困惑。再说一次,如果您的合作者也是迁移到Ruby的Haskell程序员,那么您可能不会遇到此问题。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.