Can Ruby really be used as a functional language? What are some good tutorials to teach this facet of the language? Note: I really want to use and stick with Ruby as my primary language so I am not interested at this point in being converted to YAFL (yet another functional language). I am really interested in how well Ruby's functional facets perform against the standard functional language baseline. Thanks.
It depends what you mean by "Functional Programming". In my view, the most important thing is that functions are first class values, and in this respect Ruby is a functional language.
Yes...sort of. Ruby lacks a reasonable construct to enforce immutability. (Object#freeze
doesn't count) Immutability is really the cornerstone of functional languages. Further, Ruby's core libraries are highly oriented toward imperative design. Its Array
and Hash
classes are both mutable by nature, even String
has methods which make non-immutable (e.g. gsub!
). Ironically, Java is more "functional" than Ruby in this respect.
With that said, it is possible to do functional-like programming in Ruby. Any time you use a block/proc/lambda, you are using a feature that comes from functional programming. Likewise, collection methods like map
and zip
are also higher-order constructs which find their roots in languages like Lisp, ML and Haskell.
If you really want to do functional programming, you will want to use a language which is more geared toward that genre. Some suggestions:
- Clojure - Since you phrased the question using Ruby, I'm guessing you're of the dynamically typed persuasion. Clojure is like a strictly-functional Lisp that runs on the JVM.
- F# - Basically OCaml on the CLR. Very nice, very clean
- Scala - Not a strictly functional language, but much better for it than Ruby
- Haskell - Everybody's favorite!
You'll notice that three of these four languages are statically typed. In fact, in the case of Scala and Haskell, these are very statically typed languages (much stronger type systems than, say, Java). I'm not sure why this is a trend in functional languages, but there you have it.
It has a fairly comprehensive set of list comprehensions - see Martin Fowler's article. However, it's type system is not as powerful as the likes of Haskell. Also, its focus is not on immutability, as is typical for functional languages.
For most uses, yes. There is (albeit a somewhat limited) ability to do currying, first class functions, and recursion. But due to the high cost of object creation, and method dispatch, deep recursion can get you into trouble quick!
Ruby is plenty capable fitting into a variety of programming "molds", but it's certainly not optimal at most of them.
You'll also run into issues fairly quickly if you're using any kind of recursive algorithm. Ruby doesn't support tail-recursion, so if you can't reliably use recursion as an iteration technique like you would as the natural way of doing things in a more functional language. Something like:
def foo(n)
puts n
foo(n + 1)
end
foo(1)
Will give you
SystemStackError: stack level too deep
from (irb):2:in `puts'
from (irb):2:in `foo'
from (irb):3:in `foo'
from (irb):5
After a few thousand iterations (depending on your system)