From: Justin Collins Date: 2012-06-22T09:31:45+09:00 Subject: Re: inject was Benchmark obsession? This is a multi-part message in MIME format. --------------080804010608080901090704 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit On 06/21/2012 04:30 PM, Henry Maddocks wrote: > > On 21/06/2012, at 9:50 AM, Ryan Davis wrote: > >> Given #inject's other alias, #reduce, it is obvious that you don't >> use #inject for building up other objects. Even in a functional style >> of programming you'd _never_ see it building up anything. You'd see >> it REDUCING (folding) an object. If #inject is applied in a >> non-folding manner, it isn't functional, it is just dumb. Don't >> pretend otherwise (and if you do pretend otherwise, go read more >> books on lisp--start with SICP). The second I see a semicolon (or >> return) in an inject, I immediately suspect that someone is writing >> clevar/stupid code. >> >> I don't have any recent examples from the list, but I'm on record in >> multiple mediums ranting against people who use #inject improperly. >> I'll make up one based on examples I've seen time and time again: > > I come across this quite often, especially in Rails apps. > > a = {:list => [1,2,3,4]} > b = {:list => [9,8,7,6,5]} > > c = [a,b] > > c.inject([]) {|memo, run| memo + run[:list] } > > I always cringe when I see it but I haven't found an alternative that > is as clear and concise. > collect and flatten looks ugly. I'd love to be able to do... > > c.collect {|run| *run[:list]} > > > Henry You could move the array outside: a = {:list => [1,2,3,4]} b = {:list => [9,8,7,6,5]} c = [a,b] all = [] c.each { |h| all.concat h[:list] } Saves a little memory, too? -Justin --------------080804010608080901090704 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit On 06/21/2012 04:30 PM, Henry Maddocks wrote:

On 21/06/2012, at 9:50 AM, Ryan Davis wrote:

Given #inject's other alias, #reduce, it is obvious that you don't use #inject for building up other objects. Even in a functional style of programming you'd _never_ see it building up anything. You'd see it REDUCING (folding) an object. If #inject is applied in a non-folding manner, it isn't functional, it is just dumb. Don't pretend otherwise (and if you do pretend otherwise, go read more books on lisp--start with SICP). The second I see a semicolon (or return) in an inject, I immediately suspect that someone is writing clevar/stupid code.

I don't have any recent examples from the list, but I'm on record in multiple mediums ranting against people who use #inject improperly. I'll make up one based on examples I've seen time and time again:

I come across this quite often, especially in Rails apps.

a = {:list => [1,2,3,4]}
b = {:list => [9,8,7,6,5]}

c = [a,b]

c.inject([]) {|memo, run| memo + run[:list] } 

I always cringe when I see it but I haven't found an alternative that is as clear and concise. 
collect and flatten looks ugly. I'd love to be able to do...

c.collect {|run| *run[:list]}


Henry

You could move the array outside:

a = {:list => [1,2,3,4]}
b = {:list => [9,8,7,6,5]}

c = [a,b]

all = []

c.each { |h| all.concat h[:list] }

Saves a little memory, too?

-Justin
--------------080804010608080901090704--