0

In C#, a common optimization for methods that use delegates is to provide an overloaded method with an additional argument that lets you eliminate free variables from the lambda.

For example:

System.Collections.Concurrent.ConcurrentDictionary<TKey,TValue>
{
    public TValue GetOrAdd (TKey key, Func<TKey,TValue> valueFactory);
    public TValue GetOrAdd<TArg> (TKey key, Func<TKey,TArg,TValue> valueFactory, TArg factoryArgument);
}

The "factoryArgument" in the second overload lets you use a static delegate for valueFactory instead of a closure, eliminating the need to allocate a new object each time the method is called with new arguments.

Java also has lambda expressions. However, the method for translating them into MethodHandles is different than C#. From what I've read, since the transformation is deferred until execution, Java can transparently eliminate free variables for capturing lambdas. Thus, whether or not calling a lambda expression allocates a new object is runtime-dependent.

If I'm designing a Java API that uses lambdas, would it still be worthwhile to provide overloaded methods similar to C#?

e.g.

interface Foo<T>
{
    public T get(Supplier<? extends T> supp);
    public <A> T get(Function<? super A, ? extends T> supp, A arg);
}

Or is it best to rely on the runtime to provide any optimizations and only include a single method?

e.g.

interface Foo<T>
{
    public T get(Supplier<? extends T> supp);
}

To clarify my main question is: considering the differences in how the Java and C# runtimes translate closures, is providing an overload with manual lambda-lifting necessary in Java?

David Kleszyk
  • 642
  • 3
  • 10
  • Would it be worthwhile to design a Java API based on lessons learned as a C# developer? No. Unless you're developing it especially for C# developers who don't like change. – Kayaman Jul 28 '20 at 12:47
  • No problem. So your question is whether it's better for a caller to do `get(someVar::method)` vs `get(SomeClass::method, someVar)`? – Michael Jul 28 '20 at 12:47
  • Not "whether it's better for a caller to do". Rather, due to the differences in how the C# and Java runtimes handle lambdas, whether it's even necessary to provide the overload. – David Kleszyk Jul 28 '20 at 12:50
  • It's definitely not necessary in Java. There's no such boiler-plate idiom in Java lambdas. – Kayaman Jul 28 '20 at 12:52

0 Answers0