# Subtraction accumulator

I'm currently following the tutorials over at RubyMonk, and one of the problems I need to solve is to write a subtract function that would meet these conditions:

• invoking subtract(4, 5) should return -1
• invoking subtract(-10, 2, 3) should return -15
• invoking subtract(0, 0, 0, 0, -10) should return 10

Coming from a traditional imperative programming background (C, Lua, Java, etc.), my first attempt would have been something like this:

def subtract *numbers
start = numbers[0]
tail  = numbers.drop(1)

for i in tail do
start -= i
end

return start
end


But, this just felt wrong in Ruby, and I don't doubt that it is. Trying to use a more Ruby-esque style, I thought it would be better to use some of Array's methods.

def subtract *numbers
(numbers.drop 1).inject(numbers[0]) { |x, y| x-y}
end


One thing to note is that this is essentially the same thing as above, I just moved most of the looping into Array#inject. To me, simply moving logic isn't a new style per se, and so conceptually this is nothing new to me.

Therefore my questions are:

• Is this true Ruby style? If not, how could I make it so, and how would that new style differ from the current?
• Is there any way to improve readability? ('Cause honestly the current version lacks quite a bit).

Some notes:

• def subtract *numbers: While Ruby allows to omit parens, the community consensus is that it makes signatures harder to read.

• (numbers.drop 1): When you have to write parens like this, it's a signal that you should just write them in the method call. It looks like Scala or Haskell, not Ruby.

• As @Nakilon pointed out, you can drop the drop/first, a fold without an initial value takes the first one.

• The identity value for subtraction is 0, let's use it for empty inputs.

• xs.inject(initial) { |acc, x| acc.method(x) } -> xs.inject(initial, :method)

We can now write:

def subtract(*numbers)
numbers.inject(0, :-)
end


For me, simply moving logic isn't a new style per se, and so conceptually this is nothing new to me.

I don't agree. The steps followed are conceptually the same, yes, but the use of a widely known generic abstraction like reduce/inject has reduced the overall complexity. Of course, one abstraction does not make much difference, but dozens of them change the way a whole program describes what it's doing. And that's what programing is about: building abstractions to reduce complexity.

• Okay thank you for the guidance. :) I agree that abstraction is key. I just felt that perhaps Ruby had a more awesome, totally new, nothing a C programmer could of thought up way of doing it. :P P.S. I actually wanted my Ruby to look like Haskell, but okay, whatever...*shrugs* haha – Miguel Apr 23 '13 at 23:57
• @Miguel. In fact we can write numbers.inject(0, :-) as Nakilon suggested. In any case, nothing special about Ruby on this regard, that can be done in any language that supports basic functional programming. – tokland Apr 24 '13 at 9:38

I don't understand, why do you need .first and .drop:

def subtract(*numbers)
numbers.inject{ |acc, x| acc - x }
end


Or:

def subtract(*numbers)
numbers.inject :-
end


They are NOT the same:
Original: "invoking subtract(4, 5) should return -1"

def subtract(*numbers)
numbers.inject :-
end
subtract(4,5) -> -9


How do we get the correct result with nice Ruby code?