Carson Gross
Posts: 153
Nickname: cgross
Registered: Oct, 2006
|
|
Re: Will Closures Make Java Less Verbose?
|
Posted: Apr 1, 2008 2:10 PM
|
|
> Carson, regarding your sort by salary example, I have some > comments / questions. > > If Employee implements Comparable, and uses the salary to > compare, then it's also just one line of Java code. In > general, for any *one* "natural" way of sorting, Java is > just as easy. (And same for the other "organize me" > example) It's when you have multiple ways you want to > sort/organize that it gets icky, and closures have an > edge.
Regarding sorting a list on its natural order, yeah, they are both one liners, although in GScript if you have a List of Comparable objects you can just say:
myListOfComparables.sort()
The method isn't available on lists of non-Comparable objects through some magic that we call enhancements.
> For sorting, what we have done is write various > Comparators for the class (usually as static instances, > but they could be little classes) like > > Employee.COMPARATOR_NAME, Employee.COMPARATOR_SALARY, > etc. > > Yes, it's extra work. But it's nicely localized and > hopefully reuseable / extensible.
That's the key question: how useful it the localization and reuse? Depending on your app it might be very useful. For most of the code I write a "find usages" function in my IDE would be good enough. Since I end up deleting half my code anyway, not committing to a complicated heavyweight code artifact like a class is worth the cost.
Even though I'm kind of an ass about this sometimes, I don't think it's a cut and dry "this way is always better" question. Both approaches definitely have their virtues.
> 1) What if you ship your software to China where names > sort differently? In our case, you change one small > section of code. Not sure in your case. How would > closures handle this?
It would be more work in the closures case but with a "find usages" function I don't see it being too bad. Seems like it just depends.
> 2) What happens if you want to include tips in the salary > sometimes? In our case you could do something like > Employee.COMPARATOR_SALARY_PLUS_TIPS or, if it were a > class, new Employee.SalaryComparator(true). In the > closure case, you'd do something like > > var sortedEmployees = getEmployees().sortBy( \ e -> > e.SalaryPlusTips ) > > So we add a comparator, you would add a method. Seems > like roughly similar work. Whether adding a comparator or > a new method is "better" is a matter of taste (BTW, does > salaryPlusTips have to be public?)
You could also do the sum directly in the sortBy expression:
var sortedEmployees = getEmployees.sortBy( \ e -> e.Salary + e.Tips )
Extracting a new property or method should probably depend on how often you access that functionality, and the clarity gained by doing so.
> 3) What if you want to sort by name and salary? We'd add > a comparator, Employee.COMPARATOR_NAME_THEN_SALARY. I > guess closures would go something like > > var firstSort = emps.sortby(e.Name); > var finalSort = firstSort.sortBy(e.Salary)
So here the closure story isn't as compelling in my opinion. You can use the more general but less attractive sort() method which is almost exactly like the logic you would have in the comparator:
var sortedEmployees = getEmployees.sort( \ e1, e2 ->
if(e1.Name > e2.Name){
return true
} else {
return e1.Salary > e2.Salary
})
which in my opinion is ugly. C# 3.0 has an elegant syntax for just this case:
var sortedList = emps.sortby( \ e -> e.Name ).thenBy( \ e -> e.Salary )
I think that internally they end up sorting the list twice, but I haven't looked at whether the implementation is lazy or not. Making that work in GScript would be a bit tricky so we haven't done so yet.
Anyway that's a case, right now, where I would say a Comparator might be a better approach.
> Thanks again for your good examples.
Sure. Thanks keeping me honest. I definitely see your points on the advantages of Comparator objects.
Cheers, Carson
|
|