Tue
4
Apr '06
Rubybashing: Why use implicit return?
by Frank Spychalski filed under Rants, Ruby

I like Ruby, I really do. But there is one thing I just don’t get. I seems to be good Ruby style to use as much implicit returns as possible. Why?

If you take a look at the code from this very interesting article

class DataRecord
[...]
      end
      data.close
      array
    end

    klass
  end

end

Why not use a additional return here:

class DataRecord
[...]
      end
      data.close
      array
    end

    return klass
  end

end

Leaving out the return saves you 7 characters but I think at the cost of clarity. But I’m wondering if I’m missing something here…

Addendum

I learn a lot and like Emmet said:

The really big win you get from implicit return isn’t in functions like the one you gave as an example, it’s in functions like this…

Thanks everybody for the great responses.


6 Responses to “Rubybashing: Why use implicit return?”

  1. 1

    Yes, you are missing something.

    It is an attempt to remedy the problem mentioned here, in point #6
    http://www.paulgraham.com/diff.html

    “6. Programs composed of expressions. Lisp programs are trees of expressions, each of which returns a value. (In some Lisps expressions can return multiple values.) This is in contrast to Fortran and most succeeding languages, which distinguish between expressions and statements.

    It was natural to have this distinction in Fortran because (not surprisingly in a language where the input format was punched cards) the language was line-oriented. You could not nest statements. And so while you needed expressions for math to work, there was no point in making anything else return a value, because there could not be anything waiting for it.

    This limitation went away with the arrival of block-structured languages, but by then it was too late. The distinction between expressions and statements was entrenched. It spread from Fortran into Algol and thence to both their descendants.”

    You clearly have grown up in a Fortran-derived world. The guy who created Ruby actually knows other languages, and must think they are somehow superior for not having this arbitrary limitation.

    When a language is made entirely of expressions, you can compose expressions however you want. You can say either (using Arc syntax)

    (if foo (= x 1) (= x 2))

    or

    (= x (if foo 1 2))

    asdf (April 4th, 2006 at 13:29)
  2. 2

    I understand, why it’s a neat thing if every operation returns something, but I still find it hard to read such code. I guess you are right, this is probably due to the lack of functional programming in my past.

    Frank Spychalski (April 4th, 2006 at 14:07)
  3. 3

    A subtle point is that implicit and explicit return can have different semantics. In the following example:

    def pig_out(bushel)
     bushel.map do |fruit|
      eat(fruit)
      if sick? then
       return “this #{fruit} is bad!”
      end
      ”this #{fruit} is delicious!
     end
    end

    If all the fruit are good, then the result of #pig_out will be a list of strings like “this … is delicious!”. If there’s a bad apple in the bushel, however, the result of #pig_out will be a single string “this apple is bad!”. When “return” is used, it tells Ruby to abandon whatever it was doing and immediately return from the containing method. The semantics of return are just like those of the “throw” kernel method.

    So it may be that the reason a lot of Ruby code eschews “return” is because, since it is a more “drastic” operation, it is reserved for the special cases when it is genuinely required.

    Avdi (April 4th, 2006 at 18:13)
  4. 4

    The really big win you get from implicit return isn’t in functions like the one you gave as an example, it’s in functions like this:

    def collect_times_two(array)
      array.collect{ |x| x*2 }
    end

    With required returns, this elegant looking piece of code turns into:

    def collect_times_two(array)
      return array.collect{ |x| return x*2 }
    end

    which is definitely less readable.

    Emmett Shear (April 5th, 2006 at 03:57)
  5. 5

    The “programs are composed of expressions” view can also increase readability. Here are a couple examples:
    def fact(n)
      if n ==0
        1
      else n * fact(n-1)
      end
    end

    Also I find this:

    if cond
      temp = foo
    else temp = bar
    end
    temp.some_complicated_expr

    less readable than:

    (if cond
      foo
    else bar
    end).some_complicated_expr

    Kartik Vaddadi (April 5th, 2006 at 06:13)
  6. 6

    Ignoring these wanna-be lispers… :P

    One thing to note is that the implicit return is (slightly-but-measurably) faster than the explicit return.

    zenspider (April 7th, 2006 at 00:42)

Any comments? Or questions? Just leave a Reply:

Bot-Check