J
Jarmo Pertman
Hey!
I had a discussion with my colleague about Java lacking decent
collection API. This is indeed true. One of the main reasons is that
there's no lambda and no closures in Java. The problem has been tried
to leverage with external libraries, but they're failing in my mind.
Check out the following example in lambdaj [1]:
with(sales).retain(having(on(Sale.class).getValue(),greaterThan(50000))).extract(on(Sale.class).getBuyer()).sort(on
(Person.class).getAge());
It is just awful. So my colleague created the same example in Scala:
sales.filter(_.value > 50000).map(_.buyer).sortBy(_.age)
He also created it in Ruby:
sales.find_all{|sale| sale.value > 50000}.map{|sale|
sale.buyer}.sort_by{|buyer| buyer.age}
I polished it by using Ruby 1.9 syntax and find_all alias called
select:
sales.select{|sale| sale.value > 50000}.map(&:buyer).sort_by(&:age)
It's still whopping 12 characters longer. So i decided to use
different block variable - more Scala-like underscore:
sales.select{|_| _.value > 50000}.map(&:buyer).sort_by(&:age)
Still 6 characters longer. Even if i'd be able to use syntax like
this, i'd win only 2 characters:
sales.select(&:value > 50000).map(&:buyer).sort_by(&:age)
My first question is, is there any meaningful way to shorten my
#select call by not creating any additional methods to my Sale class?
One solution would be to just create a method "good" and use it:
class Sale
def good
value > 50000
end
end
sales.select(&:good).map(&:buyer).sort_by(&:age)
I'd call it cheating though because the next step could be to use
alias_method to create one-character-length aliases to Enumerable
methods.
I'm thinking that one possible way to shorten my calls would be to use
instance-eval in #select, #map and #sort_by so i could do it like
this:
sales.select{value > 50000}.map{buyer}.sort_by{age}
Any other ideas how to beat a statically typed language with this
concrete example?
[1] - http://code.google.com/p/lambdaj
Jarmo Pertman
I had a discussion with my colleague about Java lacking decent
collection API. This is indeed true. One of the main reasons is that
there's no lambda and no closures in Java. The problem has been tried
to leverage with external libraries, but they're failing in my mind.
Check out the following example in lambdaj [1]:
with(sales).retain(having(on(Sale.class).getValue(),greaterThan(50000))).extract(on(Sale.class).getBuyer()).sort(on
(Person.class).getAge());
It is just awful. So my colleague created the same example in Scala:
sales.filter(_.value > 50000).map(_.buyer).sortBy(_.age)
He also created it in Ruby:
sales.find_all{|sale| sale.value > 50000}.map{|sale|
sale.buyer}.sort_by{|buyer| buyer.age}
I polished it by using Ruby 1.9 syntax and find_all alias called
select:
sales.select{|sale| sale.value > 50000}.map(&:buyer).sort_by(&:age)
It's still whopping 12 characters longer. So i decided to use
different block variable - more Scala-like underscore:
sales.select{|_| _.value > 50000}.map(&:buyer).sort_by(&:age)
Still 6 characters longer. Even if i'd be able to use syntax like
this, i'd win only 2 characters:
sales.select(&:value > 50000).map(&:buyer).sort_by(&:age)
My first question is, is there any meaningful way to shorten my
#select call by not creating any additional methods to my Sale class?
One solution would be to just create a method "good" and use it:
class Sale
def good
value > 50000
end
end
sales.select(&:good).map(&:buyer).sort_by(&:age)
I'd call it cheating though because the next step could be to use
alias_method to create one-character-length aliases to Enumerable
methods.
I'm thinking that one possible way to shorten my calls would be to use
instance-eval in #select, #map and #sort_by so i could do it like
this:
sales.select{value > 50000}.map{buyer}.sort_by{age}
Any other ideas how to beat a statically typed language with this
concrete example?
[1] - http://code.google.com/p/lambdaj
Jarmo Pertman