arrow-kt / arrow

Λrrow - Functional companion to Kotlin's Standard Library
http://arrow-kt.io
Other
6.17k stars 447 forks source link

["Request"] Generic Type parameter support for optics #2552

Closed Sintrastes closed 2 years ago

Sintrastes commented 2 years ago

What version are you currently using?

1.0.0

What would you like to see?

The generated output of arrow-optics for an @optics annotated data class with generic parameter(s) fails to compile. I'd like to see this use-case supported.

This issue has already been reported on the old repo for arrow optics -- but I did not see any activity either there or here. I originally saw this issue with older versions of arrow, but just confirmed that that same issue occurs with 1.0.0.

Fully supporting this would complicate the codegen a little bit, as making the generated lenses would require them to be funs instead of vals -- but beyond that, I think this should be pretty straightforward to support -- as in the generated optics, we should be able to just carry-over the generic parameter context to the definition of the generic lenses.

I wouldn't mind taking a look at this myself as a first issue for contributing to arrow, honestly -- if someone could maybe point me to the appropriate place to make changes.

raulraja commented 2 years ago

@Sintrastes I just got news that the new FIR API is available in master and we are gonna have to adapt meta to it https://github.com/JetBrains/kotlin/blob/master/plugins/fir/fir-plugin-prototype/src/org/jetbrains/kotlin/fir/plugin/FirAllOpenComponentRegistrar.kt . I think it's worth exploring together with this new compiler plugin API what a pure synthetic optics plugin looks like that does not rely on code generation and provides automatic field access to all declarations in Kotlin as you type. If you are not in a rush and would like to explore this with @nomisRev @serras and I, we can coordinate together. Otherwise, if you just want to fix the current codegen candidate for publishing is currently located in the arrow-meta repository. https://github.com/arrow-kt/arrow-meta/blob/main/plugins/optics/optics-plugin/src/main/kotlin/arrow/meta/plugins/optics/OpticsPlugin.kt Feel free to ping us in slack with any questions.

Sintrastes commented 2 years ago

@raulraja Wow, that's exciting news! Does this mean that the FIR API will be available in Kotlin 1.6.0? Or was the merge after the latest RC that was just cut recently?

I am intrigued by the idea of an approach that does not rely on codegen -- as far as I know, there aren't even any Haskell libraries that accomplish something like that (though, maybe something like that would be possible via GHC generics?).

I am not in a huge rush -- but this is a use case that would be helpful for a project of mine at work, so however this is done, I'd ideally like to see it in the next stable version of arrow-optics. However, I think regardless I'd be interested in looking into the FIR stuff.

Am I understanding this workflow properly for the proposed "fully synthetic" plugin?

Let's say I have an interface I don't control (or maybe a data class if that's problematic at all), I, with a property val I.someProperty: String, if I start typing I., the IDE will show me I.someProperty: Lens<I, String> as a completion candidate. If I enter that in and use it in my code, the appropriate lens will be generated "behind the scenes" at compile-time of the module where it is used, but (for instance), no IR or code needs to be generated for any properties of I that I did not use as a lens.

raulraja commented 2 years ago

Let's say I have an interface I don't control (or maybe a data class if that's problematic at all), I, with a property val I.someProperty: String, if I start typing I., the IDE will show me I.someProperty: Lens<I, String> as a completion candidate. If I enter that in and use it in my code, the appropriate lens will be generated "behind the scenes" at compile-time of the module where it is used, but (for instance), no IR or code needs to be generated for any properties of I that I did not use as a lens.

yes, that's exactly the idea, though if you are writing a library or you want to export it all you can selective opt into codegen, but the idea is to bring lenses and in general optics as if it was a proposed language feature. It may not even need to create a Lens type, just desugar the code to whatever is appropriate based on how fields are accessed.

serras commented 2 years ago

Closed by #2776