Search code examples
kotlinfunctional-programmingarrow-kt

Generating lenses with Kotlin Arrow library


I'm reading "Functional Kotlin" which describes the generation of lenses using annotations.

@lenses

import arrow.lenses
import arrow.optics.Lens
import arrow.optics.modify

typealias GB = Int
@lenses data class Memory(val size: GB)
@lenses data class MotherBoard(val brand: String, val memory: Memory)
@lenses data class Laptop(val price: Double, val motherBoard: MotherBoard)

fun main(args: Array<String>) {
    val laptopX8 = Laptop(500.0, MotherBoard("X", Memory(8)))
    val laptopMemorySize: Lens<Laptop, GB> = laptopMotherBoard() compose
motherBoardMemory() compose memorySize()
    val laptopX16 = laptopMemorySize.modify(laptopPrice().set(laptopX8, 780.0)) { size ->
        size * 2
    }
    println("laptopX16 = $laptopX16")
}

Arrow generates as many lenses as constructor parameters our data classes have, with the name convention classProperty and in the same package, so no extra imports are needed

But when I'm trying to use the @lenses annotation, it is not found.

@optics

In the Arrow documentation, I noticed they use the @optics annotation

@optics data class Memory(val size: GB) {
  companion object
}

Which will create a Memory.Companion.size lens.

Since I'm not able to find any other material on the @lenses annotation, it got me wondering whether this might be a deprecated implementation.

Is my hunch correct or am I missing something here?


Solution

  • Your question actually is answer. Annotation was renamed.

    As I remember that annotation existed and was experimental addition for "kategory" (library was renamed to "arrow" since). I can't find commit when it was appear because library reorganised many times. But I'm sure it was nondocumented and highly experimental feature when its renamed.

    Is that the fault of the authors of the book? I don't read it but that feature was very interesting and perspective for kotlin developers, although that highly experimental.

    Why name was changed

    "Optics" is more general term than "Lenses". When it started there was only Lenses (and partially Prism). For now Optics include: Lens, Iso, Traversal, Fold, Prism, Getter, Setter. You can find out more info in the docs. Between I'm sure that book is nice source although its out of date. The Arrows Docs is very beginner friendly unlike many other lenses-libs in different languages.