David Kubecka
11/14/2024, 9:59 AMcontext(Int)
fun prefixIt(): (String) -> String = { prefix: String -> prefix + getIt() }
context(Int)
fun getIt() = this@Int
fun caller(prefixer: (String) -> String) = prefixer("_")
fun test() {
with(1) {
caller(prefixIt())
}
}
Since prefixIt
doesn't accept any parameters I would like to convert it to a property, e.g. like this:
val prefixIt: Int.(String) -> String = { prefix: String -> prefix + getIt() }
Trying to do that I realized that this isn't semantically the same. Whereas currently I provide the Int context when creating the prefixer, the new approach wants the context when the prefixer gets actually called. This got me curious about how my current version even works. So I inspected the decompiled bytecode (in thread) and didn't find the answer 🙂David Kubecka
11/14/2024, 10:00 AMprefixIt
. The $context_receiver_0
seems unused there...
@NotNull
public static final Function1 prefixIt(int $context_receiver_0) {
return TestKt::prefixIt$lambda$0;
}
public static final int getIt(int $context_receiver_0) {
return $context_receiver_0;
}
@NotNull
public static final String caller(@NotNull Function1 prefixer) {
Intrinsics.checkNotNullParameter(prefixer, "prefixer");
return (String)prefixer.invoke("_");
}
public static final void test() {
byte var0 = 1;
int $this$test_u24lambda_u241 = var0;
int var2 = false;
caller(prefixIt($this$test_u24lambda_u241));
}
private static final String prefixIt$lambda$0(int $$context_receiver_0, String prefix) {
Intrinsics.checkNotNullParameter(prefix, "prefix");
return prefix + getIt($$context_receiver_0);
}
Youssef Shoaib [MOD]
11/14/2024, 4:22 PMcontext(Int)
immediately, but then it produces a lambda that only asks for a String
parameter. Your other version tries to ask for both, and hence it doesn't work. Btw, your new version can work if you just do:
val prefixIt: context(Int) (String) -> String = ...
context(C) operator fun <C, T, R> (context(C) (T) -> R).invoke(arg: T): R = this(this@C, arg)
// usage
caller { prefixIt(it) }
The only reason that that invoke
function is needed here is because it hasn't been implemented yet in Kotlin, but it should be coming eventuallyDavid Kubecka
11/14/2024, 4:57 PM$context_receiver_0
param of prefixIt
is unused. WDYT?Youssef Shoaib [MOD]
11/14/2024, 5:00 PMprefixIt
, it should be passing that value to the lambda)David Kubecka
11/14/2024, 5:04 PMprefixIt
.David Kubecka
11/14/2024, 5:14 PMYoussef Shoaib [MOD]
11/14/2024, 5:18 PM/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* kotlin.Metadata
* kotlin.jvm.functions.Function1
* kotlin.jvm.internal.Intrinsics
* org.jetbrains.annotations.NotNull
*/
import kotlin.Metadata;
import kotlin.jvm.functions.Function1;
import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;
@Metadata(mv={2, 0, 0}, k=2, xi=48, d1={"\u0000\u0018\n\u0000\n\u0002\u0018\u0002\n\u0002\u0010\u000e\n\u0002\u0010\b\n\u0002\b\u0006\n\u0002\u0010\u0002\n\u0000\u001a\u001b\u0010\u0000\u001a\u000e\u0012\u0004\u0012\u00020\u0002\u0012\u0004\u0012\u00020\u00020\u0001R\u00020\u0003\u00a2\u0006\u0002\u0010\u0004\u001a\u000f\u0010\u0005\u001a\u00020\u0003R\u00020\u0003\u00a2\u0006\u0002\u0010\u0006\u001a\u001a\u0010\u0007\u001a\u00020\u00022\u0012\u0010\b\u001a\u000e\u0012\u0004\u0012\u00020\u0002\u0012\u0004\u0012\u00020\u00020\u0001\u001a\u0006\u0010\t\u001a\u00020\n\u00a8\u0006\u000b"}, d2={"prefixIt", "Lkotlin/Function1;", "", "", "(I)Lkotlin/jvm/functions/Function1;", "getIt", "(I)I", "caller", "prefixer", "test", "", "library_test"})
public final class FooKt {
@NotNull
public static final Function1<String, String> prefixIt(int $context_receiver_0) {
return arg_0 -> FooKt.prefixIt$lambda$0($context_receiver_0, arg_0);
}
public static final int getIt(int $context_receiver_0) {
return $context_receiver_0;
}
@NotNull
public static final String caller(@NotNull Function1<? super String, String> prefixer) {
Intrinsics.checkNotNullParameter(prefixer, (String)"prefixer");
return (String)prefixer.invoke((Object)"_");
}
public static final void test() {
int $this$test_u24lambda_u241 = 1;
boolean bl = false;
FooKt.caller(FooKt.prefixIt($this$test_u24lambda_u241));
}
private static final String prefixIt$lambda$0(int $$context_receiver_0, String prefix) {
Intrinsics.checkNotNullParameter((Object)prefix, (String)"prefix");
return prefix + FooKt.getIt($$context_receiver_0);
}
}
and it does what you'd expectDavid Kubecka
11/14/2024, 5:20 PM