Thursday, March 1, 2012

To return, or not to return

Ruby guys sometimes discuss whether we should use return or not.  A few years ago at RubyConf, there was a panel discussion about coding, where questions were asked from the audience by Twitter.  I asked the question, and most people said they don't use return.  A panelist who use return was attacked as a Java guy.  If I had been a good English speaker,  I could have defended him.

Why do I like return?  It's because in the following code, we can't very well know whether the code expects that baz returns a value, or just counts on the side effect of baz.
def foo
  bar
  baz
end
Those who don't like return sometimes says that there's no return in functional languages (Haskell has return, but it's completely different from Ruby's).  But, it's obvious that a function returns a value, so it's reasonable for functional languages not to use return.  However, Ruby is very imperative.  Very.

It's OK not to use return in functional style code.  For example:
def sum_of_squares(ary)
  ary.map { |i| i ** 2 }.inject(&:+)
end
But the following code looks a bit awkward:
def sum_of_squares(ary)
  result = 0
  for i in ary
    result += i ** 2
  end
  result
end
The same awkwardness can be observed in code using inject.  The use of inject in the above code looks fine, but the following code looks awkward:
def to_hash(ary)
  ary.inject({}) do |h, (k, v)|
    h[k] = v
    h
  end
end
If you need side effects, you should use each_with_object instead of inject:
def to_hash(ary)
  ary.each_with_object({}) do |(k, v), h|
    h[k] = v
  end
end
Anyway, it's OK if your code is readable.  That's all.

No comments: