If Java People Go to Scala, C# Go to F#, Where Do Ruby People Go for Functional Nirvana

If Java people go to Scala, C# go to F#, where do Ruby people go for functional nirvana?

There's two very different definitions of what "functional programming" means. You can kind-of do the one in Ruby, but you cannot do the other.

Those two definitions are:

  • programming with first-class functions and
  • programming with mathematical functions

You can kind-of program with first-class functions in Ruby. It has support for first-class functions. In fact, it has too much support for them: there is Proc.new, proc, lambda, Method, UnboundMethod, blocks, #to_proc and ->() (and probably some others that I forget).

All of these behave slightly differently, have slightly different syntax, slightly different behavior and slightly different restrictions. For example: the only one of these which is syntactically lightweight enough that you can actually use it densely, is blocks. But blocks have some rather severe restrictions: you can only pass one block to a method, blocks aren't objects (which in an object-oriented language in wich "everything is an object" is a very severe restriction) and at least in Ruby 1.8 there are also some restrictions w.r.t parameters.

Referring to a method is another thing that is fairly awkward. In Python or ECMAScript for example, I can just say baz = foo.bar to refer to the bar method of the foo object. In Ruby, foo.bar is a method call, if I want to refer to the bar method of foo, I have to say baz = foo.method(:bar). And if I now want to call that method, I cannot just say baz(), I have to say baz.call or baz[] or (in Ruby 1.9) baz.().

So, first-class functions in Ruby aren't really first-class. They are much better than second-class, and they are good enough™, but they aren't fully first-class.

But generally, Rubyists do not leave Ruby just for first-class functions. Ruby's support is good enough that any advantages you might gain from better support in another language usually is eaten up by the training effort for the new language or by something else that you are accustomed to that you must now give up. Like, say RubyGems or tight Unix integration or Ruby on Rails or syntax or …

However, the second definition of FP is where Ruby falls flat on its face. If you want to do programming with mathematical functions in Ruby, you are in for a world of pain. You cannot use the absolute majority of Ruby libraries, because most of them are stateful, effectful, encourage mutation or are otherwise impure. You cannot use the standard library for the same reasons. You cannot use the core library. You cannot use any of the core datatypes, because they are all mutable. You could just say "I don't care that they are mutable, I will simply not mutate them and always copy them", but the problem is: someone else still can mutate them. Also, because they are mutable, Ruby cannot optimize the copying and the garbage collector isn't tuned for that kind of workload.

It just doesn't work.

There is also a couple of features that have really nothing to do with functional programming but that most functional languages tend to have, that Ruby is missing. Pattern matching, for example. Laziness also was not that easy to achieve before Enumerators were more aggressively used in Ruby 1.9. And there's still some stuff that works with strict Enumerables or Arrays but not with lazy Enumerators, although there's actually no reason for them to require strictness.

And for this definition of FP, it definitely makes sense to leave Ruby behind.

The two main languages that Rubyists have been flocking to, are Erlang and Clojure. These are both relatively good matches for Ruby, because they are both dynamically typed, have a similar REPL culture as Ruby, and (this is more a Rails thing than a Ruby thing) are also very good on the web. They have still pretty small and welcoming communities, the original language creators are still active in the community, there is a strong focus on doing new, exciting and edgy things, all of which are traits that the Ruby community also has.

The interest in Erlang started, when someone showed the original 1993 introduction video "Erlang: The Movie" at RubyConf 2006. A couple of high-profile Rails projects started using Erlang, for example PowerSet and GitHub. Erlang is also easy to master for Rubyists, because it doesn't take purity quite as far as Haskell or Clean. The inside of an actor is pretty pure, but the act of sending messages itself is of course a side-effect. Another thing that makes Erlang easy to grasp, is that Actors and Objects are actually the same thing, when you follow Alan Kay's definition of object-oriented programming.

Clojure has been a recent addition to the Rubyist's toolbelt. Its popularity is I guess mostly driven by the fact that the Ruby community has finally warmed up to the idea that JVM ≠ Java and embraced JRuby and then they started to look around what other interesting stuff there was on the JVM. And again, Clojure is much more pragmatic than both other functional languages like Haskell and other Lisps like Scheme and much simpler and more modern than CommonLisp, so it is a natural fit for Rubyists.

Another cool thing about Clojure is that because both Clojure and Ruby run on the JVM, you can combine them.

The author of "Programming Clojure" (Stuart Halloway) is a (former?) Rubyist, for example, as is Phil Hagelberg, the author of the Leiningen build tool for Clojure.

However, Rubyists are also looking at both Scala (as one of the more pragmatic statically typed FP languages) and Haskell (as one of the more elegant ones). Then there is projects like Scuby and Hubris which are bridges that let you integrate Ruby with Scala and Haskell, respectively. Twitter's decision to move part of their low-level messaging infrastructure first from MySQL to Ruby, then from Ruby to Scala is also pretty widely known.

F# doesn't seem to play any role at all, possibly due to an irrational fear towards all things Microsoft the Ruby community has. (Which, BTW, seems mostly unfounded, given that the F# team has always made versions available for Mono.)

What are the most important programming languages to know for concepts?

Must know:

1) C (system programming, understanding of machine architecture)

2) Perl or Python or Ruby (practical day-to-day tasks)

3) Java or C# or C++ (OOP, and quite important to get a job these days)

Really important:

1) Haskell or ML (functional programming; changes the way you think)

2) Lisp or Scheme (power of macros)

Nice additionals:

1) Forth (very low-level, explicit stack operation + joy to write your own interpreter)

2) Assembly languages (know how your CPU works)

3) Erlang (parallel processing)

4) Prolog (logic programming)

5) Smalltalk (true OOP and true interactive developent)

Significant Challengers to OOP

In my opinion, the reason OOP is used so widely isn't so much that it's the right tool for the job. I think it's more that a solution can be described to the customer in a way that they understand.

A CAR is a VEHICLE that has an ENGINE. That's programming and real world all in one!

It's hard to comprehend anything that can fit the programming and real world quite so elegantly.



Related Topics



Leave a reply



Submit