An advantage of typical lambda expressions is that they implicitly close over their defining environment, whereas FunctorObject''''''s require an explicit specification of environment. '''The problem...''' Imagine we're coding in Java and need to sort a list of numeric strings... List list = Arrays.asList("10", "1", "20", "11", "21", "12"); ...in numeric order. '''Example 1 -- FunctorObject''' In the following example, a FunctorObject class called N''''''umStringComparator is defined -- it implements the appropriate comparison operation -- and an instance of it is passed to the built-in Collections.sort() method: private static class N''''''umStringComparator implements Comparator { public int compare(String str1, String str2) { return Integer.valueOf(str1).compareTo(Integer.valueOf(str2)); } } List list = Arrays.asList("10", "1", "20", "11", "21", "12"); Collections.sort(list, new N''''''umStringComparator()); '''Example 2 -- FunctorObject with context''' Now let's imagine that the compare() method needs to make reference to the external environment. For example, it needs to access some context (called Context) that affects the run-time collating order of the sort operation. Adapting the example, it would probably look like this: private static class N''''''umStringComparator implements Comparator { private Context context; public N''''''umStringComparator(Context context) { this.context = context; } public int compare(String str1, String str2) { return Integer.valueOf(str1).compareTo(Integer.valueOf(str2)) * context.compareAdjustment(); } } List list = Arrays.asList("10", "1", "20", "11", "21", "12"); Context context = new Context(); Collections.sort(list, new N''''''umStringComparator(context)); Note that we've had to explicitly pass the Context to the "new N''''''umStringComparator" functor object via its constructor. That's an illustration of the general FunctorObject approach, and in some ObjectOriented languages that's all we've got. '''Example 3 -- LambdaExpression''' Using Java 8 lambda expressions (i.e., AnonymousFunction''''''s), the equivalent to the first example can be: List list = Arrays.asList("10", "1", "20", "11", "21", "12"); Collections.sort(list, (str1, str2) -> Integer.valueOf(str1).compareTo(Integer.valueOf(str2)) ); '''Example 4 -- LambdaExpression with Closure''' Using a lambda expression, the equivalent to Example 2 would be: List list = Arrays.asList("10", "1", "20", "11", "21", "12"); Context context = new Context(); Collections.sort(list, (str1, str2) -> Integer.valueOf(str1).compareTo(Integer.valueOf(str2)) * context.compareAdjustment() ); A lambda expression can reference -- i.e., close over -- its defining environment, so using 'context.compareAdjustment()' is simply a matter of specifying it. '''Example 5 -- Using anonymous classes to emulate lambda expressions and 'final' to simulate closures.''' To be fair to older (pre version 8) Java, it does let us come half-way to lambda expressions by using anonymous classes. We (almost) get closures as long as we can get away with declaring 'context' as 'final', in other words, if we can guarantee that it won't change throughout the lifetime of the FunctorObject. So, we ''can'' do the following: List list = Arrays.asList("10", "1", "20", "11", "21", "12"); final Context context = new Context(); Collections.sort(list, new Comparator() { public int compare(String str1, String str2) { return Integer.valueOf(str1).compareTo(Integer.valueOf(str2)) * context.compareAdjustment(); } }); Obviously, it's not as simple and clean as Example 4, above. ------ Discussion of practical usage at PageAnchor customized-collation-01 under EvidenceDiscussion. ---- CategoryJava CategoryFunctionalProgramming