Convert closure to Comparator, JS backend?


#1

I thought I could convert a closure into an SAM object like this. The numbered lines 1 and 2 give errors below. (JS backend).

import java.util.*

var cmp: Comparator<dynamic>

cmp = Comparator { a, b -> 1 }           // 1
cmp = Comparator<dynamic> { a, b -> 1 }   // 2


The errors are:

  1. Kotlin: Expression ‘Comparator’ cannot be invoked as a function. The function invoke() is not found
  2. Kotlin: Unresolved reference: Comparator

Any ideas?

Rob


#2

SAM-conversions are only supported for Java. What is your use case?


#3

abreslav wrote: SAM-conversions are only supported for Java. What is your use case?

I tried to sort an Array<dynamic>, found the `sortBy` function (by IDE auto completion) and I see that it takes a Comparator. I was looking for short syntax to construct that comparator, something like:

rows.sortBy { a,b ->
  // return 1,-1,0 as needed
}

I was also looking for in-place array sort (like native JS) in this particular case, so I it looks like I need to write a native method, but that’s a separate issue.

Rob


#4

Is your question related to Kotlin Javascript? If yes then I do this:

 

array.sortBy(object: java.util.Comparator<T> {
    override fun compare(obj1: T, obj2: T): Int {
        return -1,0,1 as required
    } }

where array is Iterable<T>


#5

You can create a comparator from comparison lambda with the comparator function:

comparator { a, b -> /* return 1,-1,0 as needed */ }

Please note that in M13
Array.sortBy(comparator) would be renamed to
Array.sortedWith(comparator). We’re also going to provide a method to sort an array in-place, which would delegate to native Array.sort method.


#6

Great, thanks!


#7

That is nice, but it doesn't solve the general need:

  To make calling SAMs with lambdas as efficient as possible.

It sounds like the support for calling Java code with lambdas is better than the support for calling Kotlin code!

Groovy has this capability and it is very handy: the code is clear and succinct.

Please consider adding this feature for Kotlin calling Kotlin.

Neil


#8

I do not believe that this need is a valid one. "SAMs" are a concept introduced in Java to work around the issue of not having function types historically. It does not seem to be a very appealing style to rely on SAMs instead of function types.

The only issue that I’m aware of that function types in their present state in Kotlin don’t address and SAMs in Java do, is giving a name to such a type to refer to it instead of copying the same signature all over the place.

This issue will be addressed with type aliases in some foreseable future (after 1.0).