SlideShare a Scribd company logo
Decoding Kotlin -
Your guide to
solving the
mysterious in
Kotlin
By João Esperancinha 2024/04/24
Nullability
1. Working with the Spring Framework
2. Reflection to force nulls
Inline and cross-inline
1. The Java overview
Tail recursive => Tail Cal Optimization
(TCO)
1. What is it
2. Why?
3. How it makes us work recursively
and not use mutable
Data classes
1. Why things work and why things
don't work
2. How to fix the ones that don't
3. How to work with use-site targets.
What does a `delegate` do? and other
use-site targets.
Topics for today
Nullability
Kotlin promises a guarantee of
null-safety. Although we can use
nullable members in our classes,
we really shouldn’t whenever
possible.
Whenever possible?
@Table(name = "CAR_PARTS")
@Entity
data class CarPart(
@Id
val id: Long,
val name: String,
val productionDate: Instant,
val expiryDate: Instant,
val barCode: Long,
val cost: BigDecimal
)
CREATE SEQUENCE car_parts_id_sequence
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
CREATE TABLE CAR_PARTS (
id BIGINT NOT NULL DEFAULT
nextval('car_parts_id_sequence'::regclass)
,
name VARCHAR(100),
production_date timestamp,
expiry_date timestamp,
bar_code BIGINT,
cost float
);
CRUD Entity Example
CRUD Entity Example
INSERT INTO CAR_PARTS
(name, production_date, expiry_date, bar_code, cost)
VALUES ('screw', current_date, current_date, 12345, 1.2);
INSERT INTO CAR_PARTS
(name, production_date, expiry_date, bar_code, cost)
VALUES (null, current_date, current_date, 12345, 1.2);
@Test
fun `should mysteriously get a list with a
car part with a name null`() {
carPartDao.findAll()
.filter { it.name == null }
.shouldHaveSize(1)
}
Is this
possible?
Reflection Example
val carPartDto = CarPartDto(
id = 123L,
name = "name",
productionDate = Instant.now(),
expiryDate = Instant.now(),
cost = BigDecimal.TEN,
barCode = 1234L
)
println(carPartDto)
val field: Field = CarPartDto::class.java
.getDeclaredField("name")
field.isAccessible = true
field.set(carPartDto, null)
println(carPartDto)
assert(carPartDto.name == null)
println(carPartDto.name == null)
data class CarPartDto(
val id: Long,
val name: String,
val productionDate:
Instant,
val expiryDate: Instant,
val barCode: Long,
val cost: BigDecimal
)
Is this
possible?
Inline and
crossinline.
Inline and crossline can be used in
combination with each other.
Inline provides bytecode copies of
the code per each call point and
they can even help avoid type
erasure. Crossinline improves
readability and some safety, but
nothing really functional.
Why does this
matter?
Crossinline as just a marker
fun main() {
callEngineCrossInline {
println("Place key in ignition")
println("Turn key or press push button ignition")
println("Clutch to the floor")
println("Set the first gear")
}.run { println(this) }
}
inline fun callEngineCrossInline(startManually: () -> Unit) {
run loop@{
println("This is the start of the loop.")
introduction {
println("Get computer in the backseat")
return@introduction
}
println("This is the end of the loop.")
}
println("Engine started!")
}
fun introduction(intro: () -> Unit) {
println(LocalDateTime.now())
intro()
return
}
public final class IsolatedCarPartsExampleKt {
public static final void main() {
int $i$f$callEngineCrossInline = false;
int var1 = false;
String var2 = "This is the start of the loop.";
System.out.println(var2);
introduction((Function0)IsolatedCarPartsExampleKt$ca
llEngineCrossInline$1$1.INSTANCE);
var2 = "This is the end of the loop.";
System.out.println(var2);
String var4 = "Engine started!";
System.out.println(var4);
Unit var3 = Unit.INSTANCE;
int var5 = false;
System.out.println(var3);
}
public static final void introduction(@NotNull
Function0 intro) {
Intrinsics.checkNotNullParameter(intro,
"intro");
LocalDateTime var1 = LocalDateTime.now();
System.out.println(var1);
intro.invoke();
} public final void invoke() {
String var1 = "Get computer in the
backseat";
System.out.println(var1);
}
Decompiled
code
Crossinline as just a marker
fun main() {
callEngineCrossInline {
println("Place key in ignition")
println("Turn key or press pus button ignition")
println("Clutch to the floor")
println("Set the first gear")
}.run { println(this) }
}
inline fun callEngineCrossInline(crossinline startManually: () -
> Unit) {
run loop@{
println("This is the start of the loop.")
introduction {
println("Get computer in the backseat")
startManually()
return@introduction
}
println("This is the end of the loop.")
}
println("Engine started!")
}
fun introduction(intro: () -> Unit) {
println(LocalDateTime.now())
intro()
return
}
public final class IsolatedCarPartsExampleKt {
public static final void main() {
int $i$f$callEngineCrossInline = false;
int var1 = false;
String var2 = "This is the start of the loop.";
System.out.println(var2);
introduction((Function0)(new
IsolatedCarPartsExampleKt$main$$inlined$callEngineCr
ossInline$1()));
var2 = "This is the end of the loop.";
System.out.println(var2);
String var4 = "Engine started!";
System.out.println(var4);
Unit var3 = Unit.INSTANCE;
int var5 = false;
System.out.println(var3);
}
public static final void introduction(@NotNull
Function0 intro) {
Intrinsics.checkNotNullParameter(intro,
"intro");
LocalDateTime var1 = LocalDateTime.now();
System.out.println(var1);
intro.invoke();
}
public final void invoke() {
String var1 = "Get computer in the
backseat";
System.out.println(var1);
int var2 = false;
String var3 = "Place key in ignition";
System.out.println(var3);
var3 = "Turn key or press push button
ignition";
System.out.println(var3);
var3 = "Clutch to the floor";
System.out.println(var3);
var3 = "Set the first gear";
System.out.println(var3);
}
Decompiled
code
Crossinline for safety
object SpecialShopNonLocalReturn {
inline fun goToStore(chooseItems: () -> Unit) {
println("Walks in")
chooseItems()
}
@JvmStatic
fun main(args: Array<String> = emptyArray()) {
goToStore {
println("Make purchase")
return@main
}
println("Never walks out")
}
}
object SpecialShopLocalReturn {
inline fun goToStore(crossinline block: () -> Unit) {
println("Walks in")
block()
}
@JvmStatic
fun main(args: Array<String> = emptyArray()) {
goToStore {
println("Make purchase")
return@goToStore
}
println("Walks out")
}
}
@JvmStatic
public static final void main(@NotNull String[] args) {
Intrinsics.checkNotNullParameter(args, "args");
SpecialShopNonLocalReturn this_$iv = INSTANCE;
int $i$f$goToStore = false;
String var3 = "Walks in";
System.out.println(var3);
int var4 = false;
String var5 = "Make purchase";
System.out.println(var5);
}
@JvmStatic
public static final void main(@NotNull String[] args) {
Intrinsics.checkNotNullParameter(args, "args");
SpecialShopLocalReturn this_$iv = INSTANCE;
int $i$f$goToStore = false;
String var3 = "Walks in";
System.out.println(var3);
int var4 = false;
String var5 = "Make purchase";
System.out.println(var5);
String var6 = "Walks out";
System.out.println(var6);
}
?
Decompiled
code
Tail Call
Optimization
Since the late 50’s TCO was
already a theory intentend to be
applied to Tail Recursivity. It
allows tail recursive functions to
be transformed into iterative
functions in the compiled code for
better performance.
What is the catch?
Tail Call Optimization
sealed interface Part {
val totalWeight: Double
}
sealed interface ComplexPart : Part{
val parts: List<Part>
}
data class CarPart(val name: String, val weight:
Double) : Part {
override val totalWeight: Double
get() = weight
}
data class ComplexCarPart(
val name: String,
val weight: Double,
override val parts: List<Part>
) :
ComplexPart {
override val totalWeight: Double
get() = weight
}
data class Car(
val name: String,
override val parts: List<Part>
) : ComplexPart {
override val totalWeight: Double
get() = parts.sumOf { it.totalWeight }
}
tailrec fun totalWeight(parts: List<Part>, acc: Double =
0.0): Double {
if (parts.isEmpty()) {
return acc
}
val part = parts.first()
val remainingParts = parts.drop(1)
val currentWeight = acc + part.totalWeight
return when (part) {
is ComplexPart -> totalWeight(remainingParts +
part.parts, currentWeight)
else -> totalWeight(remainingParts, currentWeight)
}
}
Why use this?
All variables
are immutable
Tail recursive
Tail Call Optimization
tailrec fun totalWeight(parts: List<Part>, acc: Double =
0.0): Double {
if (parts.isEmpty()) {
return acc
}
val part = parts.first()
val remainingParts = parts.drop(1)
val currentWeight = acc + part.totalWeight
return when (part) {
is ComplexPart -> totalWeight(remainingParts +
part.parts, currentWeight)
else -> totalWeight(remainingParts, currentWeight)
}
}
public static final double totalWeight(@NotNull List parts, double acc) {
while(true) {
Intrinsics.checkNotNullParameter(parts, "parts");
if (parts.isEmpty()) {
return acc;
}
Part part = (Part)CollectionsKt.first(parts);
List remainingParts = CollectionsKt.drop((Iterable)parts, 1);
double currentWeight = acc + part.getTotalWeight();
if (part instanceof ComplexPart) {
List var10000 = CollectionsKt.plus((Collection)remainingParts,
(Iterable)((ComplexPart)part).getParts());
acc = currentWeight;
parts = var10000;
} else {
acc = currentWeight;
parts = remainingParts;
}
}
}
Variables are
mutable and
algorithm is
iterative
Data classes and
Frameworks
Kotlin provides use-site targets
that allow us to specify where
particular annotations have to be
applied. Sometimes we need them
and sometimes we don’t
Why?
Working with Data classes
@Table(name = "CAR_PARTS")
@Entity
data class CarPart(
@Id
val id: Long,
@Column
@field:NotNull
@field:Size(min=3, max=20)
val name: String,
val productionDate: Instant,
val expiryDate: Instant,
val barCode: Long,
@field:Min(value = 5)
val cost: BigDecimal
)
@Table(name = "CAR_PARTS")
@Entity
data class CarPart(
@Id
val id: Long,
@Column
@NotNull
@Size(min=3, max=20)
val name: String,
val productionDate: Instant,
val expiryDate: Instant,
val barCode: Long,
@Min(value = 5)
val cost: BigDecimal
)
Doesn’t work Works!
Why
use-site
targets?
Working with Data classes
https://kotlinlang.org/docs/annotations.html#annotation-use-site-targets
If you don't specify a use-site target, the target is chosen
according to the @Target annotation of the annotation
being used. If there are multiple applicable targets, the first
applicable target from the following list is used:
● param
● property
● field
Working with Data classes
@Target({ElementType.METHOD,
ElementType.FIELD,
ElementType.ANNOTATION_TYPE,
ElementType.CONSTRUCTOR,
ElementType.PARAMETER,
ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(List.class)
@Documented
@Constraint(
validatedBy = {}
)
public @interface Size {
PARAMETER
is
selected
Working with Data classes
public final class CarPart {
@Id
private final long id;
@Column
@NotNull
private final String name;
@NotNull
private final Instant productionDate;
@NotNull
private final Instant expiryDate;
private final long barCode;
@NotNull
private final BigDecimal cost;
public final long getId() {
return this.id;
}
@NotNull
public final String getName() {
return this.name;
}
@NotNull
public final Instant getProductionDate() {
return this.productionDate;
}
@NotNull
public final Instant getExpiryDate() {
return this.expiryDate;
}
public final long getBarCode() {
return this.barCode;
}
@NotNull
public final BigDecimal getCost() {
return this.cost;
}
public CarPart(long id, @jakarta.validation.constraints.NotNull @Size(min =
3,max = 20) @NotNull String name, @NotNull Instant productionDate, @NotNull
Instant expiryDate, long barCode, @Min(5L) @NotNull BigDecimal cost) {
Intrinsics.checkNotNullParameter(name, "name");
Intrinsics.checkNotNullParameter(productionDate, "productionDate");
Intrinsics.checkNotNullParameter(expiryDate, "expiryDate");
Intrinsics.checkNotNullParameter(cost, "cost");
Not where we want
them to be,
but where they are
expected
@Table(name = "CAR_PARTS")
@Entity
data class CarPart(
@Id
val id: Long,
@Column
@field:NotNull
@field:Size(min=3, max=20)
val name: String,
val productionDate: Instant,
val expiryDate: Instant,
val barCode: Long,
@field:Min(value = 5)
val cost: BigDecimal
)
Working with Data classes
public final class CarPart {
@Id
private final long id;
@Column
@NotNull
@Size(
min = 3,
max = 20
)
@org.jetbrains.annotations.NotNull
private final String name;
@org.jetbrains.annotations.NotNull
private final Instant productionDate;
@org.jetbrains.annotations.NotNull
private final Instant expiryDate;
private final long barCode;
@Min(5L)
@org.jetbrains.annotations.NotNull
private final BigDecimal cost;
Since @field forces
the target, these
annotations get
applied where they
should
Delegates and
other use-site
targets
Delegation is a great part of the
Kotlin language and it is quite
different than what we are used to
seeing in Java
But how can we use
it?
Working with Delegates
interface Horn {
fun beep()
}
class CarHorn : Horn {
override fun beep() {
println("beep!")
}
}
class WagonHorn : Horn {
override fun beep() {
println("bwooooooo!")
}
}
annotation class DelegateToWagonHorn
annotation class DelegateToCarHorn
class SoundDelegate(private val initialHorn: Horn) {
operator fun getValue(thisRef: Any?, property: KProperty<*>): Horn {
return initialHorn
}
}
class HornPack {
@delegate:DelegateToWagonHorn
val wagonHorn: Horn by SoundDelegate(CarHorn())
@delegate:DelegateToCarHorn
val carHorn: Horn by SoundDelegate(WagonHorn())
}
Where is this being applied
to?
Horn or SoundDelegate?
Working with Delegates
public final class HornPack {
// $FF: synthetic field
static final KProperty[] $$delegatedProperties = new KProperty[]{Reflection.property1(new
PropertyReference1Impl(HornPack.class, "wagonHorn", "getWagonHorn()Lorg/jesperancinha/talks/carparts/Horn;",
0)), Reflection.property1(new PropertyReference1Impl(HornPack.class, "carHorn",
"getCarHorn()Lorg/jesperancinha/talks/carparts/Horn;", 0))};
@DelegateToWagonHorn
@NotNull
private final SoundDelegate wagonHorn$delegate = new SoundDelegate((Horn)(new CarHorn()));
@DelegateToCarHorn
@NotNull
private final SoundDelegate carHorn$delegate = new SoundDelegate((Horn)(new WagonHorn()));
@NotNull
public final Horn getWagonHorn() {
return this.wagonHorn$delegate.getValue(this, $$delegatedProperties[0]);
}
@NotNull
public final Horn getCarHorn() {
return this.carHorn$delegate.getValue(this, $$delegatedProperties[1]);
}
}
SoundDelegate
No Horn!
Working with Delegates
class SanitizedName(var name: String?) {
operator fun getValue(thisRef: Any?,
property: KProperty<*>): String? = name
operator fun setValue(thisRef: Any?,
property: KProperty<*>, v: String?) {
name = v?.trim()
}
}
class PartNameDto {
@get:NotBlank
@get:Size(max = 12)
var name: String? by SanitizedName(null)
override fun toString(): String {
return name ?: "N/A"
}
}
class ImpossiblePartNameDto {
@delegate:NotBlank
@delegate:Size(max = 12)
var name: String? by SanitizedName(null)
override fun toString(): String {
return name ?: "N/A"
}
}
public final class PartNameDto {
static final KProperty[] $$delegatedProperties = new KProperty[]{Reflection.mutableProperty1(new
MutablePropertyReference1Impl(PartNameDto.class, "name", "getName()Ljava/lang/String;", 0))};
@Nullable
private final SanitizedName name$delegate = new SanitizedName((String)null);
@NotBlank
@Size(
max = 12
)
@Nullable
public final String getName() {
return this.name$delegate.getValue(this, $$delegatedProperties[0]);
}
…
public final class ImpossiblePartNameDto {
static final KProperty[] $$delegatedProperties = new KProperty[]{Reflection.mutableProperty1(new
MutablePropertyReference1Impl(ImpossiblePartNameDto.class, "name", "getName()Ljava/lang/String;",
0))};
@NotBlank
@Size(
max = 12
)
@Nullable
private final SanitizedName name$delegate = new SanitizedName((String)null);
@Nullable
public final String getName() {
return this.name$delegate.getValue(this, $$delegatedProperties[0]);
}
Working with Delegates
@Service
data class DelegationService(
val id: UUID = UUID.randomUUID()
) {
@delegate:LocalDateTimeValidatorConstraint
@get: Past
val currentDate: LocalDateTime by LocalDateTimeDelegate()
}
public class DelegationService {
// $FF: synthetic field
static final KProperty[] $$delegatedProperties = new KProperty[]{Reflection.property1(new
PropertyReference1Impl(DelegationService.class, "currentDate",
"getCurrentDate()Ljava/time/LocalDateTime;", 0))};
@LocalDateTimeValidatorConstraint
@NotNull
private final LocalDateTimeDelegate currentDate$delegate;
@NotNull
private final UUID id;
@Past
@NotNull
public LocalDateTime getCurrentDate() {
return this.currentDate$delegate.getValue(this, $$delegatedProperties[0]);
}
What’s next?
➔ Better understanding of the Kotlin Language.
➔ Don’t fight the Spring Framework or anything else like Quarkus. They are not evil and they are not
magic.
➔ Read the Kotlin documentation and only use Google as a last resort.
➔ Nothing is perfect and Kotlin also falls into that category and recognizing that, allow us to be
better.
Thank you!
Questions?
Resources
● Null Safety: https://kotlinlang.org/docs/null-safety.html
● Inline: https://kotlinlang.org/docs/inline-functions.html
● Tail Call Optimization: https://kotlinlang.org/docs/functions.html#tail-recursive-functions
● Annotation use-site targets: https://kotlinlang.org/docs/annotations.html#annotation-use-site-targets
● Spring Validation via AOP : https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-
controller/ann-validation.html
Source code
● https://github.com/jesperancinha/kotlin-mysteries
About me
● Homepage - https://joaofilipesabinoesperancinha.nl
● LinkedIn - https://www.linkedin.com/in/joaoesperancinha/
● YouTube - JESPROTECH
■ https://www.youtube.com/channel/UCzS_JK7QsZ7ZH-zTc5kBX_g
■ https://www.youtube.com/@jesprotech
● X - https://twitter.com/joaofse
● GitHub - https://github.com/jesperancinha
● Hackernoon - https://hackernoon.com/u/jesperancinha
● DevTO - https://dev.to/jofisaes
● Medium - https://medium.com/@jofisaes
See you
Next time!

More Related Content

Similar to Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx

07-Basic-Input-Output.ppt
07-Basic-Input-Output.ppt07-Basic-Input-Output.ppt
07-Basic-Input-Output.ppt
Ajenkris Kungkung
 
Kotlin
KotlinKotlin
Kotlin
BoKaiRuan
 
C++aptitude questions and answers
C++aptitude questions and answersC++aptitude questions and answers
C++aptitude questions and answers
sheibansari
 
Java 5 Features
Java 5 FeaturesJava 5 Features
Java 5 Features
sholavanalli
 
In Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docx
In Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docxIn Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docx
In Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docx
bradburgess22840
 
Introduction to Kotlin.pptx
Introduction to Kotlin.pptxIntroduction to Kotlin.pptx
Introduction to Kotlin.pptx
AzharFauzan9
 
01 Introduction to Kotlin - Programming in Kotlin.pptx
01 Introduction to Kotlin - Programming in Kotlin.pptx01 Introduction to Kotlin - Programming in Kotlin.pptx
01 Introduction to Kotlin - Programming in Kotlin.pptx
IvanZawPhyo
 
PQTimer.java A simple driver program to run timing t.docx
  PQTimer.java     A simple driver program to run timing t.docx  PQTimer.java     A simple driver program to run timing t.docx
PQTimer.java A simple driver program to run timing t.docx
joyjonna282
 
C# labprograms
C# labprogramsC# labprograms
C# labprograms
Jafar Nesargi
 
33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests
Tomek Kaczanowski
 
2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests
Tomek Kaczanowski
 
documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...
documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...
documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...
Akaks
 
C-Sharp Arithmatic Expression Calculator
C-Sharp Arithmatic Expression CalculatorC-Sharp Arithmatic Expression Calculator
C-Sharp Arithmatic Expression Calculator
Neeraj Kaushik
 
Appium Automation with Kotlin
Appium Automation with KotlinAppium Automation with Kotlin
Appium Automation with Kotlin
RapidValue
 
C - aptitude3
C - aptitude3C - aptitude3
C - aptitude3
Srikanth
 
C aptitude questions
C aptitude questionsC aptitude questions
C aptitude questions
Srikanth
 
Threads, Queues, and More: Async Programming in iOS
Threads, Queues, and More: Async Programming in iOSThreads, Queues, and More: Async Programming in iOS
Threads, Queues, and More: Async Programming in iOS
TechWell
 
Microkernel Development
Microkernel DevelopmentMicrokernel Development
Microkernel Development
Rodrigo Almeida
 
Java fundamentals
Java fundamentalsJava fundamentals
Java fundamentals
HCMUTE
 
SystemVerilog OOP Ovm Features Summary
SystemVerilog OOP Ovm Features SummarySystemVerilog OOP Ovm Features Summary
SystemVerilog OOP Ovm Features Summary
Amal Khailtash
 

Similar to Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx (20)

07-Basic-Input-Output.ppt
07-Basic-Input-Output.ppt07-Basic-Input-Output.ppt
07-Basic-Input-Output.ppt
 
Kotlin
KotlinKotlin
Kotlin
 
C++aptitude questions and answers
C++aptitude questions and answersC++aptitude questions and answers
C++aptitude questions and answers
 
Java 5 Features
Java 5 FeaturesJava 5 Features
Java 5 Features
 
In Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docx
In Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docxIn Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docx
In Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docx
 
Introduction to Kotlin.pptx
Introduction to Kotlin.pptxIntroduction to Kotlin.pptx
Introduction to Kotlin.pptx
 
01 Introduction to Kotlin - Programming in Kotlin.pptx
01 Introduction to Kotlin - Programming in Kotlin.pptx01 Introduction to Kotlin - Programming in Kotlin.pptx
01 Introduction to Kotlin - Programming in Kotlin.pptx
 
PQTimer.java A simple driver program to run timing t.docx
  PQTimer.java     A simple driver program to run timing t.docx  PQTimer.java     A simple driver program to run timing t.docx
PQTimer.java A simple driver program to run timing t.docx
 
C# labprograms
C# labprogramsC# labprograms
C# labprograms
 
33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests
 
2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests
 
documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...
documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...
documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...
 
C-Sharp Arithmatic Expression Calculator
C-Sharp Arithmatic Expression CalculatorC-Sharp Arithmatic Expression Calculator
C-Sharp Arithmatic Expression Calculator
 
Appium Automation with Kotlin
Appium Automation with KotlinAppium Automation with Kotlin
Appium Automation with Kotlin
 
C - aptitude3
C - aptitude3C - aptitude3
C - aptitude3
 
C aptitude questions
C aptitude questionsC aptitude questions
C aptitude questions
 
Threads, Queues, and More: Async Programming in iOS
Threads, Queues, and More: Async Programming in iOSThreads, Queues, and More: Async Programming in iOS
Threads, Queues, and More: Async Programming in iOS
 
Microkernel Development
Microkernel DevelopmentMicrokernel Development
Microkernel Development
 
Java fundamentals
Java fundamentalsJava fundamentals
Java fundamentals
 
SystemVerilog OOP Ovm Features Summary
SystemVerilog OOP Ovm Features SummarySystemVerilog OOP Ovm Features Summary
SystemVerilog OOP Ovm Features Summary
 

More from João Esperancinha

Managing gRPC Services using Kong KONNECT and the KONG API Gateway
Managing gRPC Services using Kong KONNECT and the KONG API GatewayManaging gRPC Services using Kong KONNECT and the KONG API Gateway
Managing gRPC Services using Kong KONNECT and the KONG API Gateway
João Esperancinha
 
Kuma Meshes Part I - The basics - A tutorial
Kuma Meshes Part I - The basics - A tutorialKuma Meshes Part I - The basics - A tutorial
Kuma Meshes Part I - The basics - A tutorial
João Esperancinha
 
Fields in Java and Kotlin and what to expect.pptx
Fields in Java and Kotlin and what to expect.pptxFields in Java and Kotlin and what to expect.pptx
Fields in Java and Kotlin and what to expect.pptx
João Esperancinha
 
Demystifying Co, Contra, In Kotlin modifier keywords.pptx
Demystifying Co, Contra, In Kotlin modifier keywords.pptxDemystifying Co, Contra, In Kotlin modifier keywords.pptx
Demystifying Co, Contra, In Kotlin modifier keywords.pptx
João Esperancinha
 
Unlocking the Power of Kotlin Channels.pptx
Unlocking the Power of Kotlin Channels.pptxUnlocking the Power of Kotlin Channels.pptx
Unlocking the Power of Kotlin Channels.pptx
João Esperancinha
 
Exploring Tailrec Through Time Until Kotlin.pptx
Exploring Tailrec Through Time Until Kotlin.pptxExploring Tailrec Through Time Until Kotlin.pptx
Exploring Tailrec Through Time Until Kotlin.pptx
João Esperancinha
 
Reactive programming with Spring Webflux.pptx
Reactive programming with Spring Webflux.pptxReactive programming with Spring Webflux.pptx
Reactive programming with Spring Webflux.pptx
João Esperancinha
 
KONNECT Kong-Presentation How to protect web applications
KONNECT Kong-Presentation How to protect web applicationsKONNECT Kong-Presentation How to protect web applications
KONNECT Kong-Presentation How to protect web applications
João Esperancinha
 

More from João Esperancinha (8)

Managing gRPC Services using Kong KONNECT and the KONG API Gateway
Managing gRPC Services using Kong KONNECT and the KONG API GatewayManaging gRPC Services using Kong KONNECT and the KONG API Gateway
Managing gRPC Services using Kong KONNECT and the KONG API Gateway
 
Kuma Meshes Part I - The basics - A tutorial
Kuma Meshes Part I - The basics - A tutorialKuma Meshes Part I - The basics - A tutorial
Kuma Meshes Part I - The basics - A tutorial
 
Fields in Java and Kotlin and what to expect.pptx
Fields in Java and Kotlin and what to expect.pptxFields in Java and Kotlin and what to expect.pptx
Fields in Java and Kotlin and what to expect.pptx
 
Demystifying Co, Contra, In Kotlin modifier keywords.pptx
Demystifying Co, Contra, In Kotlin modifier keywords.pptxDemystifying Co, Contra, In Kotlin modifier keywords.pptx
Demystifying Co, Contra, In Kotlin modifier keywords.pptx
 
Unlocking the Power of Kotlin Channels.pptx
Unlocking the Power of Kotlin Channels.pptxUnlocking the Power of Kotlin Channels.pptx
Unlocking the Power of Kotlin Channels.pptx
 
Exploring Tailrec Through Time Until Kotlin.pptx
Exploring Tailrec Through Time Until Kotlin.pptxExploring Tailrec Through Time Until Kotlin.pptx
Exploring Tailrec Through Time Until Kotlin.pptx
 
Reactive programming with Spring Webflux.pptx
Reactive programming with Spring Webflux.pptxReactive programming with Spring Webflux.pptx
Reactive programming with Spring Webflux.pptx
 
KONNECT Kong-Presentation How to protect web applications
KONNECT Kong-Presentation How to protect web applicationsKONNECT Kong-Presentation How to protect web applications
KONNECT Kong-Presentation How to protect web applications
 

Recently uploaded

High Profile Girls Call Delhi 9711199171 Provide Best And Top Girl Service An...
High Profile Girls Call Delhi 9711199171 Provide Best And Top Girl Service An...High Profile Girls Call Delhi 9711199171 Provide Best And Top Girl Service An...
High Profile Girls Call Delhi 9711199171 Provide Best And Top Girl Service An...
janvikumar4133
 
carpentry-11-module-1.docx 1 identifying tools
carpentry-11-module-1.docx 1 identifying toolscarpentry-11-module-1.docx 1 identifying tools
carpentry-11-module-1.docx 1 identifying tools
ChristopherAltizen2
 
李易峰祝绪丹做爱视频流出【网芷:ht28.co】可爱学生妹>>>[网趾:ht28.co】]<<<
李易峰祝绪丹做爱视频流出【网芷:ht28.co】可爱学生妹>>>[网趾:ht28.co】]<<<李易峰祝绪丹做爱视频流出【网芷:ht28.co】可爱学生妹>>>[网趾:ht28.co】]<<<
李易峰祝绪丹做爱视频流出【网芷:ht28.co】可爱学生妹>>>[网趾:ht28.co】]<<<
amzhoxvzidbke
 
DPWH - DEPARTMENT OF PUBLIC WORKS AND HIGHWAYS
DPWH - DEPARTMENT OF PUBLIC WORKS AND HIGHWAYSDPWH - DEPARTMENT OF PUBLIC WORKS AND HIGHWAYS
DPWH - DEPARTMENT OF PUBLIC WORKS AND HIGHWAYS
RyanMacayan
 
AFCAT STATIC Genral knowledge important CAPSULE.pdf
AFCAT STATIC Genral knowledge important CAPSULE.pdfAFCAT STATIC Genral knowledge important CAPSULE.pdf
AFCAT STATIC Genral knowledge important CAPSULE.pdf
vibhapatil140
 
RMC FPV.docx_fpv solar energy panels----
RMC FPV.docx_fpv solar energy panels----RMC FPV.docx_fpv solar energy panels----
RMC FPV.docx_fpv solar energy panels----
Khader Mallah
 
ECONOMIC FEASIBILITY AND ENVIRONMENTAL IMPLICATIONS OF PERMEABLE PAVEMENT IN ...
ECONOMIC FEASIBILITY AND ENVIRONMENTAL IMPLICATIONS OF PERMEABLE PAVEMENT IN ...ECONOMIC FEASIBILITY AND ENVIRONMENTAL IMPLICATIONS OF PERMEABLE PAVEMENT IN ...
ECONOMIC FEASIBILITY AND ENVIRONMENTAL IMPLICATIONS OF PERMEABLE PAVEMENT IN ...
Fady M. A Hassouna
 
Sustainable construction is the use of renewable and recyclable materials in ...
Sustainable construction is the use of renewable and recyclable materials in ...Sustainable construction is the use of renewable and recyclable materials in ...
Sustainable construction is the use of renewable and recyclable materials in ...
RohitGhulanavar2
 
Adv. Digital Signal Processing LAB MANUAL.pdf
Adv. Digital Signal Processing LAB MANUAL.pdfAdv. Digital Signal Processing LAB MANUAL.pdf
Adv. Digital Signal Processing LAB MANUAL.pdf
T.D. Shashikala
 
Updated Limitations of Simplified Methods for Evaluating the Potential for Li...
Updated Limitations of Simplified Methods for Evaluating the Potential for Li...Updated Limitations of Simplified Methods for Evaluating the Potential for Li...
Updated Limitations of Simplified Methods for Evaluating the Potential for Li...
Robert Pyke
 
UNIT 1 - INTRODUCTION ON DISASTER MANAGEMENT.ppt
UNIT 1 - INTRODUCTION ON DISASTER MANAGEMENT.pptUNIT 1 - INTRODUCTION ON DISASTER MANAGEMENT.ppt
UNIT 1 - INTRODUCTION ON DISASTER MANAGEMENT.ppt
shanmugamram247
 
ISO 9001 - 2015 Quality Management Awareness.pdf
ISO 9001 - 2015 Quality Management Awareness.pdfISO 9001 - 2015 Quality Management Awareness.pdf
ISO 9001 - 2015 Quality Management Awareness.pdf
InfoDqms
 
Lab session on Robot Control using teach pendant.pptx
Lab session on Robot Control using teach pendant.pptxLab session on Robot Control using teach pendant.pptx
Lab session on Robot Control using teach pendant.pptx
KPavanKumarReddy4
 
Fix Production Bugs Quickly - The Power of Structured Logging in Ruby on Rail...
Fix Production Bugs Quickly - The Power of Structured Logging in Ruby on Rail...Fix Production Bugs Quickly - The Power of Structured Logging in Ruby on Rail...
Fix Production Bugs Quickly - The Power of Structured Logging in Ruby on Rail...
John Gallagher
 
If we're running two pumps, why aren't we getting twice as much flow? v.17
If we're running two pumps, why aren't we getting twice as much flow? v.17If we're running two pumps, why aren't we getting twice as much flow? v.17
If we're running two pumps, why aren't we getting twice as much flow? v.17
Brian Gongol
 
NOVEC 1230 Fire Suppression System Presentation
NOVEC 1230 Fire Suppression System PresentationNOVEC 1230 Fire Suppression System Presentation
NOVEC 1230 Fire Suppression System Presentation
miniruwan1
 
ANATOMY OF SOA - Thomas Erl - Service Oriented Architecture
ANATOMY OF SOA - Thomas Erl - Service Oriented ArchitectureANATOMY OF SOA - Thomas Erl - Service Oriented Architecture
ANATOMY OF SOA - Thomas Erl - Service Oriented Architecture
Divya Rajasekar
 
Buy a fake University of Washington diploma
Buy a fake University of Washington diplomaBuy a fake University of Washington diploma
Buy a fake University of Washington diploma
College diploma
 
Safety Operating Procedure for Testing Lifting Tackles
Safety Operating Procedure for Testing Lifting TacklesSafety Operating Procedure for Testing Lifting Tackles
Safety Operating Procedure for Testing Lifting Tackles
ssuserfcf701
 
20240710 ISSIP GGG Qtrly Community Connection Slides.pptx
20240710 ISSIP GGG Qtrly Community Connection Slides.pptx20240710 ISSIP GGG Qtrly Community Connection Slides.pptx
20240710 ISSIP GGG Qtrly Community Connection Slides.pptx
VaishaliM24
 

Recently uploaded (20)

High Profile Girls Call Delhi 9711199171 Provide Best And Top Girl Service An...
High Profile Girls Call Delhi 9711199171 Provide Best And Top Girl Service An...High Profile Girls Call Delhi 9711199171 Provide Best And Top Girl Service An...
High Profile Girls Call Delhi 9711199171 Provide Best And Top Girl Service An...
 
carpentry-11-module-1.docx 1 identifying tools
carpentry-11-module-1.docx 1 identifying toolscarpentry-11-module-1.docx 1 identifying tools
carpentry-11-module-1.docx 1 identifying tools
 
李易峰祝绪丹做爱视频流出【网芷:ht28.co】可爱学生妹>>>[网趾:ht28.co】]<<<
李易峰祝绪丹做爱视频流出【网芷:ht28.co】可爱学生妹>>>[网趾:ht28.co】]<<<李易峰祝绪丹做爱视频流出【网芷:ht28.co】可爱学生妹>>>[网趾:ht28.co】]<<<
李易峰祝绪丹做爱视频流出【网芷:ht28.co】可爱学生妹>>>[网趾:ht28.co】]<<<
 
DPWH - DEPARTMENT OF PUBLIC WORKS AND HIGHWAYS
DPWH - DEPARTMENT OF PUBLIC WORKS AND HIGHWAYSDPWH - DEPARTMENT OF PUBLIC WORKS AND HIGHWAYS
DPWH - DEPARTMENT OF PUBLIC WORKS AND HIGHWAYS
 
AFCAT STATIC Genral knowledge important CAPSULE.pdf
AFCAT STATIC Genral knowledge important CAPSULE.pdfAFCAT STATIC Genral knowledge important CAPSULE.pdf
AFCAT STATIC Genral knowledge important CAPSULE.pdf
 
RMC FPV.docx_fpv solar energy panels----
RMC FPV.docx_fpv solar energy panels----RMC FPV.docx_fpv solar energy panels----
RMC FPV.docx_fpv solar energy panels----
 
ECONOMIC FEASIBILITY AND ENVIRONMENTAL IMPLICATIONS OF PERMEABLE PAVEMENT IN ...
ECONOMIC FEASIBILITY AND ENVIRONMENTAL IMPLICATIONS OF PERMEABLE PAVEMENT IN ...ECONOMIC FEASIBILITY AND ENVIRONMENTAL IMPLICATIONS OF PERMEABLE PAVEMENT IN ...
ECONOMIC FEASIBILITY AND ENVIRONMENTAL IMPLICATIONS OF PERMEABLE PAVEMENT IN ...
 
Sustainable construction is the use of renewable and recyclable materials in ...
Sustainable construction is the use of renewable and recyclable materials in ...Sustainable construction is the use of renewable and recyclable materials in ...
Sustainable construction is the use of renewable and recyclable materials in ...
 
Adv. Digital Signal Processing LAB MANUAL.pdf
Adv. Digital Signal Processing LAB MANUAL.pdfAdv. Digital Signal Processing LAB MANUAL.pdf
Adv. Digital Signal Processing LAB MANUAL.pdf
 
Updated Limitations of Simplified Methods for Evaluating the Potential for Li...
Updated Limitations of Simplified Methods for Evaluating the Potential for Li...Updated Limitations of Simplified Methods for Evaluating the Potential for Li...
Updated Limitations of Simplified Methods for Evaluating the Potential for Li...
 
UNIT 1 - INTRODUCTION ON DISASTER MANAGEMENT.ppt
UNIT 1 - INTRODUCTION ON DISASTER MANAGEMENT.pptUNIT 1 - INTRODUCTION ON DISASTER MANAGEMENT.ppt
UNIT 1 - INTRODUCTION ON DISASTER MANAGEMENT.ppt
 
ISO 9001 - 2015 Quality Management Awareness.pdf
ISO 9001 - 2015 Quality Management Awareness.pdfISO 9001 - 2015 Quality Management Awareness.pdf
ISO 9001 - 2015 Quality Management Awareness.pdf
 
Lab session on Robot Control using teach pendant.pptx
Lab session on Robot Control using teach pendant.pptxLab session on Robot Control using teach pendant.pptx
Lab session on Robot Control using teach pendant.pptx
 
Fix Production Bugs Quickly - The Power of Structured Logging in Ruby on Rail...
Fix Production Bugs Quickly - The Power of Structured Logging in Ruby on Rail...Fix Production Bugs Quickly - The Power of Structured Logging in Ruby on Rail...
Fix Production Bugs Quickly - The Power of Structured Logging in Ruby on Rail...
 
If we're running two pumps, why aren't we getting twice as much flow? v.17
If we're running two pumps, why aren't we getting twice as much flow? v.17If we're running two pumps, why aren't we getting twice as much flow? v.17
If we're running two pumps, why aren't we getting twice as much flow? v.17
 
NOVEC 1230 Fire Suppression System Presentation
NOVEC 1230 Fire Suppression System PresentationNOVEC 1230 Fire Suppression System Presentation
NOVEC 1230 Fire Suppression System Presentation
 
ANATOMY OF SOA - Thomas Erl - Service Oriented Architecture
ANATOMY OF SOA - Thomas Erl - Service Oriented ArchitectureANATOMY OF SOA - Thomas Erl - Service Oriented Architecture
ANATOMY OF SOA - Thomas Erl - Service Oriented Architecture
 
Buy a fake University of Washington diploma
Buy a fake University of Washington diplomaBuy a fake University of Washington diploma
Buy a fake University of Washington diploma
 
Safety Operating Procedure for Testing Lifting Tackles
Safety Operating Procedure for Testing Lifting TacklesSafety Operating Procedure for Testing Lifting Tackles
Safety Operating Procedure for Testing Lifting Tackles
 
20240710 ISSIP GGG Qtrly Community Connection Slides.pptx
20240710 ISSIP GGG Qtrly Community Connection Slides.pptx20240710 ISSIP GGG Qtrly Community Connection Slides.pptx
20240710 ISSIP GGG Qtrly Community Connection Slides.pptx
 

Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx

  • 1. Decoding Kotlin - Your guide to solving the mysterious in Kotlin By João Esperancinha 2024/04/24
  • 2. Nullability 1. Working with the Spring Framework 2. Reflection to force nulls Inline and cross-inline 1. The Java overview Tail recursive => Tail Cal Optimization (TCO) 1. What is it 2. Why? 3. How it makes us work recursively and not use mutable Data classes 1. Why things work and why things don't work 2. How to fix the ones that don't 3. How to work with use-site targets. What does a `delegate` do? and other use-site targets. Topics for today
  • 3. Nullability Kotlin promises a guarantee of null-safety. Although we can use nullable members in our classes, we really shouldn’t whenever possible. Whenever possible?
  • 4. @Table(name = "CAR_PARTS") @Entity data class CarPart( @Id val id: Long, val name: String, val productionDate: Instant, val expiryDate: Instant, val barCode: Long, val cost: BigDecimal ) CREATE SEQUENCE car_parts_id_sequence START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; CREATE TABLE CAR_PARTS ( id BIGINT NOT NULL DEFAULT nextval('car_parts_id_sequence'::regclass) , name VARCHAR(100), production_date timestamp, expiry_date timestamp, bar_code BIGINT, cost float ); CRUD Entity Example
  • 5. CRUD Entity Example INSERT INTO CAR_PARTS (name, production_date, expiry_date, bar_code, cost) VALUES ('screw', current_date, current_date, 12345, 1.2); INSERT INTO CAR_PARTS (name, production_date, expiry_date, bar_code, cost) VALUES (null, current_date, current_date, 12345, 1.2); @Test fun `should mysteriously get a list with a car part with a name null`() { carPartDao.findAll() .filter { it.name == null } .shouldHaveSize(1) } Is this possible?
  • 6. Reflection Example val carPartDto = CarPartDto( id = 123L, name = "name", productionDate = Instant.now(), expiryDate = Instant.now(), cost = BigDecimal.TEN, barCode = 1234L ) println(carPartDto) val field: Field = CarPartDto::class.java .getDeclaredField("name") field.isAccessible = true field.set(carPartDto, null) println(carPartDto) assert(carPartDto.name == null) println(carPartDto.name == null) data class CarPartDto( val id: Long, val name: String, val productionDate: Instant, val expiryDate: Instant, val barCode: Long, val cost: BigDecimal ) Is this possible?
  • 7. Inline and crossinline. Inline and crossline can be used in combination with each other. Inline provides bytecode copies of the code per each call point and they can even help avoid type erasure. Crossinline improves readability and some safety, but nothing really functional. Why does this matter?
  • 8. Crossinline as just a marker fun main() { callEngineCrossInline { println("Place key in ignition") println("Turn key or press push button ignition") println("Clutch to the floor") println("Set the first gear") }.run { println(this) } } inline fun callEngineCrossInline(startManually: () -> Unit) { run loop@{ println("This is the start of the loop.") introduction { println("Get computer in the backseat") return@introduction } println("This is the end of the loop.") } println("Engine started!") } fun introduction(intro: () -> Unit) { println(LocalDateTime.now()) intro() return } public final class IsolatedCarPartsExampleKt { public static final void main() { int $i$f$callEngineCrossInline = false; int var1 = false; String var2 = "This is the start of the loop."; System.out.println(var2); introduction((Function0)IsolatedCarPartsExampleKt$ca llEngineCrossInline$1$1.INSTANCE); var2 = "This is the end of the loop."; System.out.println(var2); String var4 = "Engine started!"; System.out.println(var4); Unit var3 = Unit.INSTANCE; int var5 = false; System.out.println(var3); } public static final void introduction(@NotNull Function0 intro) { Intrinsics.checkNotNullParameter(intro, "intro"); LocalDateTime var1 = LocalDateTime.now(); System.out.println(var1); intro.invoke(); } public final void invoke() { String var1 = "Get computer in the backseat"; System.out.println(var1); } Decompiled code
  • 9. Crossinline as just a marker fun main() { callEngineCrossInline { println("Place key in ignition") println("Turn key or press pus button ignition") println("Clutch to the floor") println("Set the first gear") }.run { println(this) } } inline fun callEngineCrossInline(crossinline startManually: () - > Unit) { run loop@{ println("This is the start of the loop.") introduction { println("Get computer in the backseat") startManually() return@introduction } println("This is the end of the loop.") } println("Engine started!") } fun introduction(intro: () -> Unit) { println(LocalDateTime.now()) intro() return } public final class IsolatedCarPartsExampleKt { public static final void main() { int $i$f$callEngineCrossInline = false; int var1 = false; String var2 = "This is the start of the loop."; System.out.println(var2); introduction((Function0)(new IsolatedCarPartsExampleKt$main$$inlined$callEngineCr ossInline$1())); var2 = "This is the end of the loop."; System.out.println(var2); String var4 = "Engine started!"; System.out.println(var4); Unit var3 = Unit.INSTANCE; int var5 = false; System.out.println(var3); } public static final void introduction(@NotNull Function0 intro) { Intrinsics.checkNotNullParameter(intro, "intro"); LocalDateTime var1 = LocalDateTime.now(); System.out.println(var1); intro.invoke(); } public final void invoke() { String var1 = "Get computer in the backseat"; System.out.println(var1); int var2 = false; String var3 = "Place key in ignition"; System.out.println(var3); var3 = "Turn key or press push button ignition"; System.out.println(var3); var3 = "Clutch to the floor"; System.out.println(var3); var3 = "Set the first gear"; System.out.println(var3); } Decompiled code
  • 10. Crossinline for safety object SpecialShopNonLocalReturn { inline fun goToStore(chooseItems: () -> Unit) { println("Walks in") chooseItems() } @JvmStatic fun main(args: Array<String> = emptyArray()) { goToStore { println("Make purchase") return@main } println("Never walks out") } } object SpecialShopLocalReturn { inline fun goToStore(crossinline block: () -> Unit) { println("Walks in") block() } @JvmStatic fun main(args: Array<String> = emptyArray()) { goToStore { println("Make purchase") return@goToStore } println("Walks out") } } @JvmStatic public static final void main(@NotNull String[] args) { Intrinsics.checkNotNullParameter(args, "args"); SpecialShopNonLocalReturn this_$iv = INSTANCE; int $i$f$goToStore = false; String var3 = "Walks in"; System.out.println(var3); int var4 = false; String var5 = "Make purchase"; System.out.println(var5); } @JvmStatic public static final void main(@NotNull String[] args) { Intrinsics.checkNotNullParameter(args, "args"); SpecialShopLocalReturn this_$iv = INSTANCE; int $i$f$goToStore = false; String var3 = "Walks in"; System.out.println(var3); int var4 = false; String var5 = "Make purchase"; System.out.println(var5); String var6 = "Walks out"; System.out.println(var6); } ? Decompiled code
  • 11. Tail Call Optimization Since the late 50’s TCO was already a theory intentend to be applied to Tail Recursivity. It allows tail recursive functions to be transformed into iterative functions in the compiled code for better performance. What is the catch?
  • 12. Tail Call Optimization sealed interface Part { val totalWeight: Double } sealed interface ComplexPart : Part{ val parts: List<Part> } data class CarPart(val name: String, val weight: Double) : Part { override val totalWeight: Double get() = weight } data class ComplexCarPart( val name: String, val weight: Double, override val parts: List<Part> ) : ComplexPart { override val totalWeight: Double get() = weight } data class Car( val name: String, override val parts: List<Part> ) : ComplexPart { override val totalWeight: Double get() = parts.sumOf { it.totalWeight } } tailrec fun totalWeight(parts: List<Part>, acc: Double = 0.0): Double { if (parts.isEmpty()) { return acc } val part = parts.first() val remainingParts = parts.drop(1) val currentWeight = acc + part.totalWeight return when (part) { is ComplexPart -> totalWeight(remainingParts + part.parts, currentWeight) else -> totalWeight(remainingParts, currentWeight) } } Why use this? All variables are immutable Tail recursive
  • 13. Tail Call Optimization tailrec fun totalWeight(parts: List<Part>, acc: Double = 0.0): Double { if (parts.isEmpty()) { return acc } val part = parts.first() val remainingParts = parts.drop(1) val currentWeight = acc + part.totalWeight return when (part) { is ComplexPart -> totalWeight(remainingParts + part.parts, currentWeight) else -> totalWeight(remainingParts, currentWeight) } } public static final double totalWeight(@NotNull List parts, double acc) { while(true) { Intrinsics.checkNotNullParameter(parts, "parts"); if (parts.isEmpty()) { return acc; } Part part = (Part)CollectionsKt.first(parts); List remainingParts = CollectionsKt.drop((Iterable)parts, 1); double currentWeight = acc + part.getTotalWeight(); if (part instanceof ComplexPart) { List var10000 = CollectionsKt.plus((Collection)remainingParts, (Iterable)((ComplexPart)part).getParts()); acc = currentWeight; parts = var10000; } else { acc = currentWeight; parts = remainingParts; } } } Variables are mutable and algorithm is iterative
  • 14. Data classes and Frameworks Kotlin provides use-site targets that allow us to specify where particular annotations have to be applied. Sometimes we need them and sometimes we don’t Why?
  • 15. Working with Data classes @Table(name = "CAR_PARTS") @Entity data class CarPart( @Id val id: Long, @Column @field:NotNull @field:Size(min=3, max=20) val name: String, val productionDate: Instant, val expiryDate: Instant, val barCode: Long, @field:Min(value = 5) val cost: BigDecimal ) @Table(name = "CAR_PARTS") @Entity data class CarPart( @Id val id: Long, @Column @NotNull @Size(min=3, max=20) val name: String, val productionDate: Instant, val expiryDate: Instant, val barCode: Long, @Min(value = 5) val cost: BigDecimal ) Doesn’t work Works! Why use-site targets?
  • 16. Working with Data classes https://kotlinlang.org/docs/annotations.html#annotation-use-site-targets If you don't specify a use-site target, the target is chosen according to the @Target annotation of the annotation being used. If there are multiple applicable targets, the first applicable target from the following list is used: ● param ● property ● field
  • 17. Working with Data classes @Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE}) @Retention(RetentionPolicy.RUNTIME) @Repeatable(List.class) @Documented @Constraint( validatedBy = {} ) public @interface Size { PARAMETER is selected
  • 18. Working with Data classes public final class CarPart { @Id private final long id; @Column @NotNull private final String name; @NotNull private final Instant productionDate; @NotNull private final Instant expiryDate; private final long barCode; @NotNull private final BigDecimal cost; public final long getId() { return this.id; } @NotNull public final String getName() { return this.name; } @NotNull public final Instant getProductionDate() { return this.productionDate; } @NotNull public final Instant getExpiryDate() { return this.expiryDate; } public final long getBarCode() { return this.barCode; } @NotNull public final BigDecimal getCost() { return this.cost; } public CarPart(long id, @jakarta.validation.constraints.NotNull @Size(min = 3,max = 20) @NotNull String name, @NotNull Instant productionDate, @NotNull Instant expiryDate, long barCode, @Min(5L) @NotNull BigDecimal cost) { Intrinsics.checkNotNullParameter(name, "name"); Intrinsics.checkNotNullParameter(productionDate, "productionDate"); Intrinsics.checkNotNullParameter(expiryDate, "expiryDate"); Intrinsics.checkNotNullParameter(cost, "cost"); Not where we want them to be, but where they are expected
  • 19. @Table(name = "CAR_PARTS") @Entity data class CarPart( @Id val id: Long, @Column @field:NotNull @field:Size(min=3, max=20) val name: String, val productionDate: Instant, val expiryDate: Instant, val barCode: Long, @field:Min(value = 5) val cost: BigDecimal ) Working with Data classes public final class CarPart { @Id private final long id; @Column @NotNull @Size( min = 3, max = 20 ) @org.jetbrains.annotations.NotNull private final String name; @org.jetbrains.annotations.NotNull private final Instant productionDate; @org.jetbrains.annotations.NotNull private final Instant expiryDate; private final long barCode; @Min(5L) @org.jetbrains.annotations.NotNull private final BigDecimal cost; Since @field forces the target, these annotations get applied where they should
  • 20. Delegates and other use-site targets Delegation is a great part of the Kotlin language and it is quite different than what we are used to seeing in Java But how can we use it?
  • 21. Working with Delegates interface Horn { fun beep() } class CarHorn : Horn { override fun beep() { println("beep!") } } class WagonHorn : Horn { override fun beep() { println("bwooooooo!") } } annotation class DelegateToWagonHorn annotation class DelegateToCarHorn class SoundDelegate(private val initialHorn: Horn) { operator fun getValue(thisRef: Any?, property: KProperty<*>): Horn { return initialHorn } } class HornPack { @delegate:DelegateToWagonHorn val wagonHorn: Horn by SoundDelegate(CarHorn()) @delegate:DelegateToCarHorn val carHorn: Horn by SoundDelegate(WagonHorn()) } Where is this being applied to? Horn or SoundDelegate?
  • 22. Working with Delegates public final class HornPack { // $FF: synthetic field static final KProperty[] $$delegatedProperties = new KProperty[]{Reflection.property1(new PropertyReference1Impl(HornPack.class, "wagonHorn", "getWagonHorn()Lorg/jesperancinha/talks/carparts/Horn;", 0)), Reflection.property1(new PropertyReference1Impl(HornPack.class, "carHorn", "getCarHorn()Lorg/jesperancinha/talks/carparts/Horn;", 0))}; @DelegateToWagonHorn @NotNull private final SoundDelegate wagonHorn$delegate = new SoundDelegate((Horn)(new CarHorn())); @DelegateToCarHorn @NotNull private final SoundDelegate carHorn$delegate = new SoundDelegate((Horn)(new WagonHorn())); @NotNull public final Horn getWagonHorn() { return this.wagonHorn$delegate.getValue(this, $$delegatedProperties[0]); } @NotNull public final Horn getCarHorn() { return this.carHorn$delegate.getValue(this, $$delegatedProperties[1]); } } SoundDelegate No Horn!
  • 23. Working with Delegates class SanitizedName(var name: String?) { operator fun getValue(thisRef: Any?, property: KProperty<*>): String? = name operator fun setValue(thisRef: Any?, property: KProperty<*>, v: String?) { name = v?.trim() } } class PartNameDto { @get:NotBlank @get:Size(max = 12) var name: String? by SanitizedName(null) override fun toString(): String { return name ?: "N/A" } } class ImpossiblePartNameDto { @delegate:NotBlank @delegate:Size(max = 12) var name: String? by SanitizedName(null) override fun toString(): String { return name ?: "N/A" } } public final class PartNameDto { static final KProperty[] $$delegatedProperties = new KProperty[]{Reflection.mutableProperty1(new MutablePropertyReference1Impl(PartNameDto.class, "name", "getName()Ljava/lang/String;", 0))}; @Nullable private final SanitizedName name$delegate = new SanitizedName((String)null); @NotBlank @Size( max = 12 ) @Nullable public final String getName() { return this.name$delegate.getValue(this, $$delegatedProperties[0]); } … public final class ImpossiblePartNameDto { static final KProperty[] $$delegatedProperties = new KProperty[]{Reflection.mutableProperty1(new MutablePropertyReference1Impl(ImpossiblePartNameDto.class, "name", "getName()Ljava/lang/String;", 0))}; @NotBlank @Size( max = 12 ) @Nullable private final SanitizedName name$delegate = new SanitizedName((String)null); @Nullable public final String getName() { return this.name$delegate.getValue(this, $$delegatedProperties[0]); }
  • 24. Working with Delegates @Service data class DelegationService( val id: UUID = UUID.randomUUID() ) { @delegate:LocalDateTimeValidatorConstraint @get: Past val currentDate: LocalDateTime by LocalDateTimeDelegate() } public class DelegationService { // $FF: synthetic field static final KProperty[] $$delegatedProperties = new KProperty[]{Reflection.property1(new PropertyReference1Impl(DelegationService.class, "currentDate", "getCurrentDate()Ljava/time/LocalDateTime;", 0))}; @LocalDateTimeValidatorConstraint @NotNull private final LocalDateTimeDelegate currentDate$delegate; @NotNull private final UUID id; @Past @NotNull public LocalDateTime getCurrentDate() { return this.currentDate$delegate.getValue(this, $$delegatedProperties[0]); }
  • 25. What’s next? ➔ Better understanding of the Kotlin Language. ➔ Don’t fight the Spring Framework or anything else like Quarkus. They are not evil and they are not magic. ➔ Read the Kotlin documentation and only use Google as a last resort. ➔ Nothing is perfect and Kotlin also falls into that category and recognizing that, allow us to be better.
  • 28. Resources ● Null Safety: https://kotlinlang.org/docs/null-safety.html ● Inline: https://kotlinlang.org/docs/inline-functions.html ● Tail Call Optimization: https://kotlinlang.org/docs/functions.html#tail-recursive-functions ● Annotation use-site targets: https://kotlinlang.org/docs/annotations.html#annotation-use-site-targets ● Spring Validation via AOP : https://docs.spring.io/spring-framework/reference/web/webmvc/mvc- controller/ann-validation.html
  • 30. About me ● Homepage - https://joaofilipesabinoesperancinha.nl ● LinkedIn - https://www.linkedin.com/in/joaoesperancinha/ ● YouTube - JESPROTECH ■ https://www.youtube.com/channel/UCzS_JK7QsZ7ZH-zTc5kBX_g ■ https://www.youtube.com/@jesprotech ● X - https://twitter.com/joaofse ● GitHub - https://github.com/jesperancinha ● Hackernoon - https://hackernoon.com/u/jesperancinha ● DevTO - https://dev.to/jofisaes ● Medium - https://medium.com/@jofisaes