java.interop icon indicating copy to clipboard operation
java.interop copied to clipboard

Better support for Kotlin FunctionX types

Open mattleibow opened this issue 5 years ago • 2 comments

As Kotlin is moving towards being the main language and is right now the default and recommended language for Android development, many new features rely on Kotlin features.

One such example is the new IFunction# types - basically the equivalent of C#'s Action<T> and Func<T>. Originally in this issue: https://github.com/xamarin/java.interop/issues/464#issuecomment-522444887

For example, if you have a collection, there is an extension method map which is used line the Select in Linq:

Kotlin:

val names = people.map { it.name }

The equivalent C#:

var names = people.Select(p => p.Name);

The Kotlin binding is missing support for creating extension methods, but it can be seen here:

public unsafe static IList Map (Java.Lang.Object[] array, IFunction1 mapper);

If we had to use this:

var people = new[]
{
	new Person { Name = "Matthew" },
	new Person { Name = "Ruth" },
	new Person { Name = "Benjamin" },
	new Person { Name = "Hannah" }
};

var names = ArraysKt.Map(people, new Mapper());

class Person : Java.Lang.Object
{
	public string Name { get; set; }
}

class Mapper : Java.Lang.Object, IFunction1
{
	public Java.Lang.Object Invoke(Java.Lang.Object p0)
	{
		var person = p0 as Person;
		return person.Name;
	}
}

This actually brings the very good question... Should Kotlin be better integrated or get better interop support. Like with the listeners and the events, this could potentially be wrapped into actions.

mattleibow avatar Sep 04 '20 16:09 mattleibow

Are functions still not supported?

seansparkman avatar Aug 24 '21 04:08 seansparkman

Part of the reason that generator emits partial classes is so that it doesn't need to do everything. Consider java.lang.Runnable, which can be considered as equivalent to System.Action. generator does not have builtin support for wrapping an Action in an IRunnable; instead, we do that manually, e.g. https://github.com/xamarin/xamarin-android/blob/ca8f5617cc55cc3510a61433d8d50c6a58ec0ac2/src/Mono.Android/Android.OS/Handler.cs#L13-L16

namespace Android.OS {
	public partial class Handler {
		public bool Post (Action action)
		{
			return Post (new Java.Lang.Thread.RunnableImplementor (action, true));
		}
	}
}

generator doesn't need to do everything, and nothing stops you from providing "utility overloads" for Kotlin function types.

I realize everyone would prefer that generator do it, but we're already running into the limits of its architecture. I do not see this being implemented anytime soon.

jonpryor avatar Oct 04 '22 17:10 jonpryor