10

Given that Ruby has good list operation capabilities in-built - reduce, map, select, collect etc. It has Procs, Blocks and Lambdas, and has nice iteration support (the each family), would it be a bad design decision if I attempt to write all my Ruby stuff in the most pure-functional way possible? Escpecially for code that has little or no I/O (thus less obvious side-effects)?

I've been learning Haskell (called the 'real' Hacker's language), and am in love with it's way of doing things - I love Ruby, but think it can be even more fun when more Haskell spirit flows into it (well, didn't Ruby borrow / learn lots from it in the first place?)

Constructive guidance is welcome...

6
  • 13
    Why not just write in Haskell then?
    – Don Stewart
    Commented Apr 26, 2011 at 23:36
  • 1
    I would write in Haskell alone, but Ruby is not so bad as to deserve to be thrown away completely. I like the fact that I can use it when scripting, and for the many quick experiments I like to hack together when learning AI stuff. But probably also because I've just started learning Haskell, might follow you advice eventually :-)
    – JWL
    Commented Apr 26, 2011 at 23:58
  • 2
    I don't understand why you're asking for Stack Overflow's permission. If you're writing code that you're going to share with others on a team, you're going to have to coordinate your coding styles anyway. Otherwise, what does it matter? Commented Apr 27, 2011 at 0:00
  • Why am asking SO? because I respect the honest opinion of experienced hackers and programmers. There might be benefits in using a pure-functional approach to programming that experienced minds might be able to share with me (and others like me).
    – JWL
    Commented Apr 27, 2011 at 0:03
  • Considering that there's objective reasons for "no", this is a legitimate question. Commented Apr 27, 2011 at 2:38

5 Answers 5

16

I have been doing this with python. I find that it is cumbersome to write in a hereditarily pure functional style in a language that wasn't designed for it. For example, contrast the two definitions of 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)

Writing in_order the Haskell way in python is going to be both verbose (since python does not support the necessary idioms very well) and slow (linear space instead of Haskell's constant space due to laziness).

However, I have had success creating python programs with functional organization, and an idiomatic implementation of each function. The idea that this is a good way to program is actually the thesis behind my codecatalog project. So, my components are oriented around abstractions and functions (with pure interface) operating on them, rather than classes with state, and it is coming together nicely. In fact, code organized this way seems to be more flexible to reuse than code organized with classes. That could be a personal bias, however, since I am still a Haskell devotee.

So I would say the answer to your question is kinda. Use your functional roots to help you think, but don't overdo it. Eg. simulating lazy lists in Ruby just for idiom's sake is probably going to be more trouble than it's worth.

9
  • Somehow your description made me think of pascal.
    – rasjani
    Commented Apr 27, 2011 at 1:00
  • @rasjani, oh? Any reason why?
    – luqui
    Commented Apr 27, 2011 at 1:03
  • I dont know, maybe its lack of understanding english well or what you described sort of fits how (i atleast) things where arranged/structure in pascal units. Just a sort of mental connection, might not have any real connection thou due to first option ;)
    – rasjani
    Commented Apr 27, 2011 at 1:10
  • 1
    The statement "linear space instead of Haskell's constant space due to laziness" isn't accurate. Laziness still implies linear order. I understand your point however.
    – aromero
    Commented Apr 27, 2011 at 1:45
  • 3
    @aromero, I don't understand yours, though. What does order have to do with it? Constant space comes from Haskell garbage collecting the heads of the list of comparisons after and consumes them ; it will behave just like a loop. Whereas python's list of comparisons will have to be generated in full before the analog of and would see any of them (unless you use generators... which I suppose is a possibility).
    – luqui
    Commented Apr 27, 2011 at 2:15
8

You can write Ruby code in functional style as if it were Scheme, not Haskell. To write it as if it were Haskell, it would need a Haskell-like type system, plus pervasive lazy evaluation.

1

I've found understanding functional programming, and Haskell in particular, to be helpful to me in certain situations I've encountered in Ruby. But the more I learn Haskell, the more I realize how far Ruby is from ever being able to be much like Haskell at all.

The module / code loading situation is abysmal, for one thing. The current interpreter doesn't have tail call optimization turned on, so you can't use recursion the way you do in Haskell. And once you get into Monads, there's really no comparison of the levels of abstraction you can achieve in Haskell vs. Ruby.

If you're interested, I've been posting some Ruby/Haskell comparison code on gist.github.com as I've been learning.

The technique I've brought over to Ruby that has worked out the best has been finding pure functions where I can, which is what it sounds like you are trying to do.

1
  • In one of my Smalltalk tests: self assert: ((m >>= f) >>= g) equals: (m >>= [:x | (f value: x) >>= g]). There's no reason at all why you can't consciously use monads, as opposed to using them without even knowing you're using them (like lists). Commented Jul 8, 2011 at 18:28
0

I would say "yes". What (I think) you're talking about is the functional programming influence in the ruby language. The functional paradigm has some really nice concepts that compliment or overlap with object oriented (no side effects, in particular).

The great thing about ruby is it allows you to code in a linear, objected oriented or functional style, or some blend of these. And your simple, linear script can morph into OO/functional style if and when it's complexity increases.

0

It depends on whether you will be collaborating with others. If you are working on the code by yourself, use whatever style you feel most comfortable with. However, if you are working with other Ruby programmers, they may not be used to a purely functional style of programming and thus be confused by your code. Then again, if your collaborators are also Haskell programmers who migrated to Ruby, you may not have this problem.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.