min
09/02/2026, 6:36 AMval myAnnotation = maybeAnnotatedClass.getAnnotationByClassId(
classId = ANNOTATION_CLASS,
session = session,
)
?: return null
.getKClassArgument(ANNOTATION_ARG)!!
.classId!!
Is there a way to mark the end of the Elvis operand? The code above is rejected because the operator maximally munches the rest of the expressionmin
09/02/2026, 6:38 AMval myAnnotation = maybeAnnotatedClass.getAnnotationByClassId(
classId = ANNOTATION_CLASS,
session = session,
)
.let { nullable -> nullable ?: return null }
.getKClassArgument(ANNOTATION_ARG)!!
.classId!!
I constantly have to do this, which would have been fine if I could abstract out the .let { nullable -> nullable ?: return null } into its own extension function that I could reuse, but I cannot. I don’t want to wrap the whole function body in an Arrow nullable just so that I could call nullable.bind() either
val myAnnotation = maybeAnnotatedClass.getAnnotationByClassId(
classId = ANNOTATION_CLASS,
session = session,
)
?.getKClassArgument(ANNOTATION_ARG)
?.classId
?: return null
Also, please do not suggest alternatives such as this. I need to return early from the nullable (fallible) function if a given class is not annotated with the annotation class for my plugin (a failure mode). If it is annotated however but lacks a KClass argument, something inexplicable has gone profoundly wrong and there’s no recovery path for it which merits the use of !!phldavies
09/02/2026, 7:09 AM.let { it ?: return null} or (expr ?: return null).restOfChain()Marat Akhin
09/02/2026, 7:56 AMmin
09/02/2026, 8:01 AMMarat Akhin
09/02/2026, 8:04 AMval classAnno = maybeAnnotatedClass.getAnnotationByClassId(
classId = ANNOTATION_CLASS,
session = session,
) ?: return null
val classAnnoArgument = classAnno
.getKClassArgument(ANNOTATION_ARG)!!
.classId!!min
09/02/2026, 8:11 AMclassAnno is private to the call chain in the sense that it’s only the business of the chain and of nothing else. Why should it even be visible to the entire rest of the function? That’s one more binding for the reader of the function to keep track of in their head.phldavies
09/02/2026, 8:15 AMMarat Akhin
09/02/2026, 8:15 AMI need to return early from the nullable (fallible) function if a given class is not annotated with theinside a call chain, to my mind, that's one more thing the reader needs to (now) carefully read and still track. I'd trade that for one more variable.for my plugin (a failure mode). If it is annotated however but lacks aannotation classargument, something inexplicable has gone profoundly wrong and there’s no recovery path for it which merits the use ofKClass.!!
min
09/02/2026, 8:17 AMMarat Akhin
09/02/2026, 8:18 AMphldavies
09/02/2026, 8:18 AMmin
09/02/2026, 8:21 AMinline fun <T: Any> T?.elvis(f: () -> T): T {
return this ?: f()
}
I think I could also declare an extension like thisphldavies
09/02/2026, 8:21 AMinline fun <T: Any> T?.ifNull(f: () -> T): T helper so you can .ifNull { return null }min
09/02/2026, 8:22 AMval myAnnotation = maybeAnnotatedClass.getAnnotationByClassId(
classId = ANNOTATION_CLASS,
session = session,
)
.elvis { return null }
.getKClassArgument(ANNOTATION_ARG)!!
.classId!!
@phldavies I could live with this, thank you!phldavies
09/02/2026, 8:24 AMifNull) although personally I'd keep to .let { it ?: return null }min
09/02/2026, 8:25 AM.let { it ?: return null } is way too verbose given its frequency. But you make a good point about ifNull, thank you for your advice