# Kotlin and SAM interface with two parameters

**URL:** <https://discuss.kotlinlang.org/t/kotlin-and-sam-interface-with-two-parameters/293>\
**Category:** Uncategorized\
**Created:** [March 30, 2015, 4:07am UTC](https://discuss.kotlinlang.org/t/kotlin-and-sam-interface-with-two-parameters/293 "2015-03-30T04:07:51Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![cedricbeust](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/cedricbeust/32/1429_2.png) [@cedricbeust](https://discuss.kotlinlang.org/u/cedricbeust)\
**Post date:** [March 30, 2015, 4:07am UTC](https://discuss.kotlinlang.org/t/kotlin-and-sam-interface-with-two-parameters/293/1 "2015-03-30T04:07:51Z")

</div>

I'm trying to get a SAM with two parameters to work with a Kotlin closure. The best I could do is this:

 

// Java

public interface Two {

 &nbsp;&nbsp;Integer f(Integer i, String s);

}

 

 

 

// Kotlin

fun f2(two: Two) {

}

 

fun test() {

 &nbsp;&nbsp;f2 ( Two { i, s -\> 42 } )

}

 

I expected to be able to write:

 

f2 { i, s -\> 42 }

 

Why do I need to explicitly coerce this expression to `Two`?

---

<div class="post-metadata">

**Author:** ![abreslav](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/abreslav/32/8279_2.png) [@abreslav](https://discuss.kotlinlang.org/u/abreslav)\
**Post date:** [March 30, 2015, 10:02am UTC](https://discuss.kotlinlang.org/t/kotlin-and-sam-interface-with-two-parameters/293/2 "2015-03-30T10:02:58Z")

</div>

SAM-conversions only work for Java methods, not supported for Kotlin functions, because Kotlin has nice functional types, and there's no need for SAM conversion (in your case, I'd convert the lambda inside f2)

---

<div class="post-metadata">

**Author:** ![cedricbeust](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/cedricbeust/32/1429_2.png) [@cedricbeust](https://discuss.kotlinlang.org/u/cedricbeust)\
**Post date:** [March 30, 2015, 5:09pm UTC](https://discuss.kotlinlang.org/t/kotlin-and-sam-interface-with-two-parameters/293/3 "2015-03-30T17:09:12Z")

</div>

That's what I suspected.

I can’t help but feel it’s inconsistent, though: it would be nice if the shortcut form was available everywhere, regardless of the language the function is written in.

---

<div class="post-metadata">

**Author:** ![mikehearn](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/mikehearn/32/1424_2.png) [@mikehearn](https://discuss.kotlinlang.org/u/mikehearn)\
**Post date:** [April 2, 2015, 4:41pm UTC](https://discuss.kotlinlang.org/t/kotlin-and-sam-interface-with-two-parameters/293/4 "2015-04-02T16:41:14Z")

</div>

+1 for this, it's especially odd when working with Java APIs that use SAM interfaces extensively like JavaFX. The "Runnable" here and "Callable" there is redundant and doesn't add readability - the compiler should be able to figure this out.

---

<div class="post-metadata">

**Author:** ![Groostav](https://avatars.discourse-cdn.com/v4/letter/g/85f322/32.png) [@Groostav](https://discuss.kotlinlang.org/u/Groostav)\
**Post date:** [April 23, 2016, 10:05pm UTC](https://discuss.kotlinlang.org/t/kotlin-and-sam-interface-with-two-parameters/293/5 "2016-04-23T22:05:36Z")

</div>

another +1 to this, because without it I’m going to have to reinvent some idioms I have around guice.

In java, if a class has non-guice-time dependency, we use AssistedInject, so one example of such a class might be

```auto
class CoolService{
  public @FunctionalInterface Factory{
    CoolService create(int importantValue)
  }

  @Inject
  CoolService(Component1 comp, @Assisted int importantValue){ 
    //...
  }
}

```

for _consumers_ of CoolService (that is to say components that depend on it, typically controllers of one sort or another), they would inject this factory:

```auto
class DependsOnCoolService{
  DependsOnCoolService(CoolServiceFactory svcFactory){
    //...
  }
}

```

this is nice from a testing environment, since we can stub that factory out nicely with a mock or stub or something.

```auto
class DependsOnCoolServiceTest{
  @Test doSomething(){
    //setup
    DependsOnCoolService componentUnderTest = new DependsOnCoolService(
        x -> mock(CoolService.class)
    );

    //... 
  }
}

```

The actual plumbing at runtime code is to configure guice to use the factory to create a `DependsOnCoolService`:

```auto
Guice.createInjector(binder -> {
  binder.install(new FactoryModuleBinding().build(CoolService.Factory.class));
  //...

```

notice we explicitly leverage javas SAM to convert the lambda `x -> mock(...` to a `CoolService.Factory`.

The same idiom _now doesn’t work_ in kotlin. So what can we do instead?

- The equivalent `CoolService` is now a kotlin object,
- The `DependsOnCoolService` is a kotlin object
- The `DependsOnCoolServiceTest` is a kotlin object
- The guice plumbing is sill done in java, though thats easy enough to port.

so, whats our new idiom? I can go back to anonymous nested class, but that’s no fun at all, and I’m drawing a blank on an alternative.

Instead of taking a `CoolServiceFactory` we could ‘lift’ that to a `svcFactory : () -> CoolService`, which places the burden on the guice configuration… which I just attempted, and unfortunately theres something between kotlins implied contravariance and guice that dont agree with each other.

```auto
Guice.createInjector(object : Module{
    override fun configure(binder: Binder) {
        binder.install(FactoryModuleBuilder()
                .implement(OPYLConfigurationApplier::class.java, OPYLConfigurationApplier::class.java)
                .build(object : TypeLiteral<kotlin.jvm.functions.Function0<CoolService>>(){})
        )
    }
})

//throws 
com.google.inject.CreationException: Unable to create injector, see the following errors:

1) An exception was caught and reported. Message: Expected a Class, ParameterizedType, or GenericArrayType, but <? extends com.my_company.CoolService> is of type com.google.inject.internal.MoreTypes$WildcardTypeImpl
  at com.empowerops.api.OPYLImporterFixture$canGuice$1.configure(OPYLImporterFixture.kt:25) (via modules: com.empowerops.api.OPYLImporterFixture$canGuice$1 -> com.google.inject.assistedinject.FactoryModuleBuilder$1)

1 error

```

would really like SAM conversion in kotlin

---

<div class="post-metadata">

**Author:** ![fvasco](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/fvasco/32/1961_2.png) [@fvasco](https://discuss.kotlinlang.org/u/fvasco)\
**Post date:** [April 26, 2016, 8:07am UTC](https://discuss.kotlinlang.org/t/kotlin-and-sam-interface-with-two-parameters/293/6 "2016-04-26T08:07:20Z")

</div>

+1  
Kotlin must be Java fully interoperable and functional interfaces is a Java 8 feature.

Define an inline object is an ugly workaround, Java does it better.

---

<div class="post-metadata">

**Author:** ![mplatvoet](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/mplatvoet/32/7121_2.png) [@mplatvoet](https://discuss.kotlinlang.org/u/mplatvoet)\
**Post date:** [April 26, 2016, 11:14am UTC](https://discuss.kotlinlang.org/t/kotlin-and-sam-interface-with-two-parameters/293/7 "2016-04-26T11:14:19Z")

</div>

You both will be so happy 😉 [https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions](https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions)

---

<div class="post-metadata">

**Author:** ![fvasco](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/fvasco/32/1961_2.png) [@fvasco](https://discuss.kotlinlang.org/u/fvasco)\
**Post date:** [April 26, 2016, 12:25pm UTC](https://discuss.kotlinlang.org/t/kotlin-and-sam-interface-with-two-parameters/293/8 "2016-04-26T12:25:01Z")

</div>

> Also note that this feature works only for Java interop

A “Java interoperable” Kotlin library should use Kotlin Function0 or Java Supplier?

---

<div class="post-metadata">

**Author:** ![Groostav](https://avatars.discourse-cdn.com/v4/letter/g/85f322/32.png) [@Groostav](https://discuss.kotlinlang.org/u/Groostav)\
**Post date:** [May 6, 2016, 11:01pm UTC](https://discuss.kotlinlang.org/t/kotlin-and-sam-interface-with-two-parameters/293/9 "2016-05-06T23:01:01Z")

</div>

Ahh, so I’m actually requesting a kotlin native SAM conversion, not just Java conversion:

```auto
@Test fun when_binding_things(){
    //setup
    val injector = Guice.createInjector(object : AbstractModule() {
        override fun configure() {
            install(FactoryModuleBuilder().build(KotlinClassWithSAMFactory.Factory::class.java))
        }
    })

    val guiceInstance : KotlinClassWithSAMFactory.Factory = injector.getInstance(KotlinClassWithSAMFactory.Factory::class.java)
    val lambdaInstance : KotlinClassWithSAMFactory.Factory = { value : Int -> KotlinClassWithSAMFactory(value) }
    //error: cannot convert value:Int -> KCWSAMF to KCWSAMF.F

    assertThat(guiceInstance)
            .isNotNull()
            .isInstanceOf(KotlinClassWithSAMFactory.Factory::class.java)

    assertThat(lambdaInstance)
            .isNotNull()
            .isInstanceOf(KotlinClassWithSAMFactory.Factory::class.java)
}

class KotlinClassWithSAMFactory @Inject constructor(@Assisted val importantValue : Int){

    @FunctionalInterface interface Factory {
        fun create(important : Int) : KotlinClassWithSAMFactory
    }
}

```

☹

---

<div class="post-metadata">

**Author:** ![fvasco](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/fvasco/32/1961_2.png) [@fvasco](https://discuss.kotlinlang.org/u/fvasco)\
**Post date:** [May 12, 2016, 6:38am UTC](https://discuss.kotlinlang.org/t/kotlin-and-sam-interface-with-two-parameters/293/10 "2016-05-12T06:38:35Z")

</div>

Kotlin support for JDK 7/8 don’t use the “nice functional types”, there is an example:

> <https://github.com/Kotlin/kotlinx.support/blob/master/kotlinx-support-jdk8/src/main/kotlin/collections/Collections.kt>

Can you justify this “bad design”? Why use SAM interface and avoid functional types?

Thanks

PS: “it works” or “special case” aren’t -in my opinion- a enough good motivations for an absolute constraint.

---

<div class="post-metadata">

**Author:** ![yole](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/yole/32/1425_2.png) [@yole](https://discuss.kotlinlang.org/u/yole)\
**Post date:** [May 12, 2016, 8:09am UTC](https://discuss.kotlinlang.org/t/kotlin-and-sam-interface-with-two-parameters/293/11 "2016-05-12T08:09:35Z")

</div>

Not sure why you’re calling this “bad design”. No design was involved here. The kotlinx.support library does not define any APIs; it simply exposes the APIs defined in JDK 7 and 8, which, unsurprisingly, use the JDK SAM interfaces and not the Kotlin functional types.

---

<div class="post-metadata">

**Author:** ![fvasco](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/fvasco/32/1961_2.png) [@fvasco](https://discuss.kotlinlang.org/u/fvasco)\
**Post date:** [May 12, 2016, 8:44am UTC](https://discuss.kotlinlang.org/t/kotlin-and-sam-interface-with-two-parameters/293/12 "2016-05-12T08:44:37Z")

</div>

It seems a “special case” ☹

You can expose same API to Kotlin in “Kotlin way”, right?  
Therefore -in my opinion- there is a design choice.

I think that actual design is a good choice but an fully interoperable language can’t discriminate “Java way” vs “Kotlin way”.

This is a “Java library case”, it isn’t a special case; a Java/Kotlin library is full of this cases, may I write it in Kotlin only without penalties?

Please reconsider your opinion, thanks.

---

<div class="post-metadata">

**Author:** ![yole](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/yole/32/1425_2.png) [@yole](https://discuss.kotlinlang.org/u/yole)\
**Post date:** [May 12, 2016, 9:13am UTC](https://discuss.kotlinlang.org/t/kotlin-and-sam-interface-with-two-parameters/293/13 "2016-05-12T09:13:29Z")

</div>

No, we can’t expose it in a different way. The JDK method accepts an instance of Supplier, so we need to pass an instance of Supplier to it.

---

<div class="post-metadata">

**Author:** ![ilya.gorbunov](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/ilya.gorbunov/32/1645_2.png) [@ilya.gorbunov](https://discuss.kotlinlang.org/u/ilya.gorbunov)\
**Post date:** [May 12, 2016, 3:18pm UTC](https://discuss.kotlinlang.org/t/kotlin-and-sam-interface-with-two-parameters/293/14 "2016-05-12T15:18:47Z")

</div>

> [@fvasco](#):
>
> You can expose same API to Kotlin in “Kotlin way”, right?

And we do so indeed.  
Look for example at `MutableCollection.removeIf`: overloads for both `Predicate<in T>` and `(T) -> Boolean` are provided.

---

<div class="post-metadata">

**Author:** ![fvasco](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/fvasco/32/1961_2.png) [@fvasco](https://discuss.kotlinlang.org/u/fvasco)\
**Post date:** [May 12, 2016, 5:09pm UTC](https://discuss.kotlinlang.org/t/kotlin-and-sam-interface-with-two-parameters/293/15 "2016-05-12T17:09:27Z")

</div>

Thanks,  
honestly.

But I disagree, doubling the code seems like a workaround.  
You can found a solution to “verbose way”, in the next release, in further releases.  
This isn’t a key feature but -in my opinion- the current solution requires more considerations, like  
[http://www.artima.com/intv/simplexity2.html](http://www.artima.com/intv/simplexity2.html)

Thanks for your consideration,  
these feedback are very appreciated.  
Vasco

---

<div class="post-metadata">

**Author:** ![fvasco](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/fvasco/32/1961_2.png) [@fvasco](https://discuss.kotlinlang.org/u/fvasco)\
**Post date:** [May 13, 2016, 6:29am UTC](https://discuss.kotlinlang.org/t/kotlin-and-sam-interface-with-two-parameters/293/16 "2016-05-13T06:29:38Z")

</div>

This is a consequence of “Java way” and “Kotlin way” distinction when programming a shared interface for Java and Kotlin.

```
    interface TaskMeter {
        fun measure(runnable: Runnable) : Long
        
        fun measure(function: () -> Unit) : Long

        // and so on...
        fun measure(runnables: Iterable<Runnable>) : Long
        
        fun measure(functions: Sequence<() -> Unit>) : Long
    }

```

Hard to implement and use both in Java and Kotlin.  
Is this the right way for a pragmatic, concise, interoperable language?

---

<div class="post-metadata">

**Author:** ![yole](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/yole/32/1425_2.png) [@yole](https://discuss.kotlinlang.org/u/yole)\
**Post date:** [May 13, 2016, 8:23am UTC](https://discuss.kotlinlang.org/t/kotlin-and-sam-interface-with-two-parameters/293/17 "2016-05-13T08:23:19Z")

</div>

Sorry, you seem to be putting forward a lot of principle-based arguments, but I fail to see what is the actual problem that you want us to solve.

In your TaskMeter example, there is absolutely no need to duplicate the method declarations. Java SAM conversions work just fine with Kotlin function types, so the second declaration for `measure()` works equally well for Java and for Kotlin users and implementers.

For the second example, the semantics of the `Sequence` interface (lazily evaluated, potentially infinite sequence) is simply not appropriate for the task, so it’s much better to use `Iterable`, regardless of any Java/Kotlin interop concerns.

---

<div class="post-metadata">

**Author:** ![fvasco](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/fvasco/32/1961_2.png) [@fvasco](https://discuss.kotlinlang.org/u/fvasco)\
**Post date:** [May 13, 2016, 9:16am UTC](https://discuss.kotlinlang.org/t/kotlin-and-sam-interface-with-two-parameters/293/18 "2016-05-13T09:16:54Z")

</div>

Hi yole,  
I am sorry but I disagree again.  
I think that the right Java interoperable interface is

```
        interface TaskMeter {
            fun measure(runnable: Runnable) : Long
            
            fun measure(runnables: Iterable<Runnable>) : Long
        }

```

I have no reason to expose “in a public shared interface”(\*) any detail about Kotlin/Scala/Groovy implementation, otherwise I am free to swith from Java to Kotlin but I can’t throw away Kotlin later.

Moreover I think that every language must avoid code duplication as much as possible; Kotlin JDK support is a common case, the common solution in an adapter (i provide interface A, you require interface B), this adapter can be create automatically at compile time and, in my opinion, Kotlin compiler may do it.

Kotlin declares Java compatibility, not vice versa.

I’m sorry for my poor english, I think to have some difficult to explain my ideas.  
I wish this is an usefull exchange, not a dispute.

Thanks for your patience,  
Vasco

(\*) TaskMeter can by a legacy interface translated in Kotlin

---

<div class="post-metadata">

**Author:** ![Rudiger.moller](https://avatars.discourse-cdn.com/v4/letter/r/4bbf92/32.png) [@Rudiger.moller](https://discuss.kotlinlang.org/u/Rudiger.moller)\
**Post date:** [May 20, 2017, 12:55am UTC](https://discuss.kotlinlang.org/t/kotlin-and-sam-interface-with-two-parameters/293/19 "2017-05-20T00:55:40Z")

</div>

+1 as more java 8 libraries arise, SAM’s like Function, Consumer are everywher in java libs. For polyglott projects, one would like Kotlin’s type inference to recognize SAM’s. I know type inference of SAM’s works for methods defined in “real” java classes, however it fails when defined inside a kotrlin class.

e.g. a method  
`fun foo(Consumer<Bar> c)`

has to be called from kotlin like this  
`obj.foo( Consumer { bar -> ... })`

vs. java8  
`obj.foo( bar -> ... )`.

IMO kotlin type inference should enable  
`obj.foo { bar -> ...}`

---

<div class="post-metadata">

**Author:** ![Zhuinden](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/zhuinden/32/5923_2.png) [@Zhuinden](https://discuss.kotlinlang.org/u/Zhuinden)\
**Post date:** [October 14, 2017, 7:17pm UTC](https://discuss.kotlinlang.org/t/kotlin-and-sam-interface-with-two-parameters/293/20 "2017-10-14T19:17:20Z")

</div>

This seems to mean that using auto-conversion, **any code** that used a _custom interface_ and _lambda expression_ in Java 8, must be converted manually to be inline object as `object: MyInterface { override fun blah() { ... } }` (like in pre-Java 8 times and anonymous interface implementation)
