Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Possible fix for unnecessary casts to KProperty1 inside validatableOf calls #53

Open
bejibx opened this issue Dec 13, 2024 · 6 comments
Labels
core The core of the library is involved DSL API design and its DSL enhancement New feature or request ksp-plugin The KSP plugin is involved

Comments

@bejibx
Copy link

bejibx commented Dec 13, 2024

I notice there are several places where library code have difficulties using definitely non-nullable types:

After checking referenced kotlin issue, it seems it is not an actual root of this problem. Actual referenced issue should be this one.
Looking at this second issue right now my guess it will stay in backlog for a very long time. And it is definitely not fixed in 1.9.20 and even in 2.0.21 (I checked).
I think this could actually be fixed internally just by using nullable type bounds instead of definitely non-nullable type on one method.
Instead of

@JvmName("nullableValidatableOfProperty")
public fun <T : Any?, V> Validatable<T>.validatableOf(getter: KProperty1<T & Any, V>): Validatable<V?> {
    return Validatable(unwrap()?.let { getter.get(it) }, getter.name, this)
}

we can do

@JvmName("nullableValidatableOfProperty")
public fun <T : Any, V> Validatable<T?>.validatableOf(getter: KProperty1<T, V>): Validatable<V?> {
    return Validatable(unwrap()?.let { getter.get(it) }, getter.name, this)
}

I already tried this change and everything seems to build/run/work without any problem and with KProperty1 casts removed.

After checking kotlin documentation I feel there is no need for definitely non-nullable type here. Some quotes:

The most common use case for declaring definitely non-nullable types is when you want to override a Java method that contains @NotNull as an argument. For example, consider the load() method

When working only with Kotlin, it's unlikely that you will need to declare definitely non-nullable types explicitly because Kotlin's type inference takes care of this for you.

@bejibx bejibx added the bug Something isn't working label Dec 13, 2024
@nesk
Copy link
Owner

nesk commented Dec 18, 2024

After checking referenced kotlin issue, it seems it is not an actual root of this problem. Actual referenced issue should be this one.

Yeah, I'm the author of both issues, just forgot to update the comments 😅

I already tried this change and everything seems to build/run/work without any problem and with KProperty1 casts removed.

The issue is with nullable validatables, did you manage to make this example work?

Validator<String?> {
    validatableOf(String::length)
}

Note that those methods shouldn't be used in userland at the moment, only the accessors generated by the KSP plugin should use them. I might have to put them behind an opt-in requirement.

Since they shouldn't be used in userland, I don't think the cast is really an issue?

@bejibx
Copy link
Author

bejibx commented Dec 18, 2024

Yeah, I'm the author of both issues, just forgot to update the comments 😅

Oh, I notice you're the author only in second one 😁

The issue is with nullable validatables, did you manage to make this example work?

I mean, looks like both tests I mention before are checking exactly this - nullable chaining scenaries and both tests were green after changes. Just to be sure I pasted your example into this method and compiler looked pretty happy:

image

Right now linter is liying to me about those casts:

image

But without this cast I get error during build:

None of the following functions can be called with the arguments supplied: 
public fun <T, V> Validatable<TypeVariable(T)>.validatableOf(getter: KFunction1<TypeVariable(T) & Any, TypeVariable(V)>): Validatable<TypeVariable(V)?> defined in dev.nesk.akkurate.validatables
public fun <T, V> Validatable<TypeVariable(T)>.validatableOf(getter: KProperty1<TypeVariable(T) & Any, TypeVariable(V)>): Validatable<TypeVariable(V)?> defined in dev.nesk.akkurate.validatables

When changing method like this

image

Cast become unnecessary, tests green and nothing seems to explode.

Since they shouldn't be used in userland, I don't think the cast is really an issue?

Right now methods are available. If you really decide to restrict access to those, some users most likely would pretty upset about it. And even in case this method be internal, this cast is adding several completely pointless bytecode operations to every invocation.
Not a huge deal, but I like it better without ugly cast and pointless bytecode operations 😊

@nesk
Copy link
Owner

nesk commented Dec 19, 2024

When changing method like this

image

I honestly can't make it work the way you did:

image

Would you mind sharing a reproducible example?

@bejibx
Copy link
Author

bejibx commented Dec 23, 2024

Can you please try again with added annotation?

@JvmName("nullableValidatableOfProperty")
@JsName("nullableValidatableOfProperty") // <-- THIS ONE
public fun <T : Any, V> Validatable<T?>.validatableOf(getter: KProperty1<T, V>): Validatable<V?> {
    return Validatable(unwrap()?.let { getter.get(it) }, getter.name, this)
}

@nesk nesk added enhancement New feature or request ksp-plugin The KSP plugin is involved core The core of the library is involved DSL API design and its DSL and removed bug Something isn't working labels Dec 29, 2024
@nesk
Copy link
Owner

nesk commented Dec 29, 2024

Seems to work, that's good news. Thank you for the insight!

However, I have some doubts on the reasons that led me to use definitely non-nullable types, I'm a bit afraid I might break something I'm not aware of now that the code is written. (I should have add more comments 😅 )

This issue doesn't seem to be a priority for the moment. Let's keep it open but I want to postpone it for the day I'll work on the K2 compiler plugin, those are related.

@bejibx
Copy link
Author

bejibx commented Dec 29, 2024

Yeah, I'm also worrying this change could somehow break something for none-jvm users, so absolutely agree with your resolution

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
core The core of the library is involved DSL API design and its DSL enhancement New feature or request ksp-plugin The KSP plugin is involved
Projects
Status: No status
Development

No branches or pull requests

2 participants