BREIZH <

to the camp

PREVIOUSLY ON BREIZHCAMP

Doc est parti quelques années dans le futur pour comprendre comment on developpera des applications sur la JVM.

IN THE PAST OF CFP.IO

commit cfc41bb48e4fc66dd2bf04588e24f590147cef45
Author: Nicolas De Loof <nicolas.deloof@gmail.com>
Date:   Tue Apr 25 16:24:44 2017 +0200

    ah le code legacy,
    même pas foutu de respected la norme javabean :-\

commit 771136b238f375edf44c092c8c37b6014919e6cf
Author: Nicolas De Loof <nicolas.deloof@gmail.com>
Date:   Wed Mar 8 19:15:11 2017 +0100

    java Date API sucks

commit 2b67097a80dc5e970b12665924ebc73b751adc10
Merge: f9fcc1b9 5b11b30d
Author: Marc <marc.audefroy@ovh.fr>
Date:   Tue Dec 8 18:27:06 2015 +0100

    Merge branch 'cospeakers'   Note du dev : GRRRRRRR

    Conflicts:
            src/main/java/fr/sii/controller/restricted/session/SessionController.java
            src/main/java/fr/sii/dto/TalkUser.java
            src/main/java/fr/sii/dto/mapping/TalkMapping.java
            src/main/java/fr/sii/service/TalkUserService.java
            src/main/resources/changelog/changelog-1.0.xml
            src/main/static/app/scripts/controllers/restricted/talks/edit.js

commit dc41801e45d6c1c23b17325eafe712824808e9be
Author: Nicolas De Loof <nicolas.deloof@gmail.com>
Date:   Sat Nov 7 14:33:42 2015 +0100

    can’t run with java 8

KOTLIN < > LE BACK DU FUTUR

STARRING

adrien

Adrien Pessu as Marty

Freelance

🐦 @adrien_pe

AND

gautier

Gautier de Saint Martin Lacaze as Doc

Freelance & Nantes JUG Leader

🐦 @darkjabberwock

INTRODUCTION

kotlin text

LES BASES DE LA SYNTAXE

VAL VS VAR

val quote: String = "Allô ? Allô ?"







//

VAL VS VAR

val name = "McFly"

var quote: String = ""

quote = """ Allô ? Allô ?
| Y'a personne au bout du fil ?
| Faut réfléchir ${name} !
| Faut réfléchir
"""

TYPE BASIQUE

  • Pas de type primitif

  • Any

  • Double, Float, Int, Char, String, …​

  • API Collection

ARRAY

val versions: Array<Int> = arrayOf(1, 2, 4)
versions[2] = 3

val sentence = "Il y a ${versions[versions.size - 1]} films."
print(sentence)

ARRAY

val versions: IntArray = intArrayOf(1, 2, 4)
versions[2] = 3

val sentence = "Il y a ${versions.size} films. Le dernier est le ${versions[versions.size - 1]}."
print(sentence)

ARRAY

val versions: Array<Int> = arrayOf(1, 2, 3)
val anyVersions: Array<Any> = versions // won't compile

RANGE

if (i in 1..3) {
  println("""Retour vers le futur ${i}""")
}

for (i in IntRange(1, 3)) {
  println("""Retour vers le futur ${i}""")
}

RANGE

for (i in 1..4 step 2) {
  println("""Retour vers le futur ${i}""")
}

for (i in 4 downTo 1 step 2) {
  println("""Retour vers le futur ${i}""")
}

SMART CAST

if (talk !is String) return
print(talk.length)

SMART CAST

val conf: String = bzhCmp as String?
val speaker: String? = mcFly as? String

DÉCLARATION FONCTIONS

fun speakerName(name: String, firstname: String) : String {
    return "${name} ${firstname}"
}

DÉCLARATION FONCTIONS

fun speakerNameInline(name: String, firstname: String) = "${name} ${firstname}"

// - 2.21 Gigowatts !! 2.21 Gigowatts !! Mon dieu !

PARAMETRE FACULTATIF

fun printHello(name: String?): Unit {
  if (name != null)
    println("Hello ${name}")
  else
   println("Hi there!")
}

VALEUR PAR DÉFAUT

fun printMessage(name: String = "galettes-saucisses"): Unit {
    println("Au BreizhCamp on aime les ${name} !")
}

fun main(args: Array) {
    printMessage()                  // Au BreizhCamp on aime les galettes-saucisses !
    printMessage("chapeaux ronds")  // Au BreizhCamp on aime les chapeaux ronds !
}

PARAMETRE NOMMÉ

fun buildMessage(
        name: String,
        upper: Boolean,
        withEmoji: Boolean
): String {

 // ...

}

PARAMETRE NOMMÉ

val message = buildMessage("Christopher Lloyd", true, false)

// On ne sait jamais, peut-être qu'on se rencontrera un jour futur.

PARAMETRE NOMMÉ

val messageWithNamedArguments = buildMessage("Christopher Lloyd",
  withEmoji = false,
  upper = true)

LAMBDA / IT

val adrien = Speaker("Adrien")
val doc = Speaker("Doc")
val gautier = Speaker("Gautier")
val marty = Speaker("Marty")

val speakers = arrayOf(marty, adrien, gautier, doc)

val speakersNames = speakers
        .filter { it.name.length <= 5 }
        .sortedBy { it.name }
        .map { it.name.toUpperCase() }

print(speakersNames) // [DOC, MARTY]

CLASS

class UserServices(val name: String, val age: Int) {
  var credentials: Credentials;
  fun getUsers()...
}

val userServices = UserServices('Marty', 33)

OBJECT CLASS

object class MySingleton

DATA CLASS

data class User(var name: String, var age: Int)

DATA CLASS

people.copy(age = 32)

OVERLOADING JAVA

class RegisterService{
  public RegisterService(String speaker){
    this.speaker = speaker;
    this.isFromBzh = true;
  }
  public RegisterService(String speaker, String coSpeaker){
    this.speaker = speaker;
    this.coSpeaker = coSpeaker;
    this.isFromBzh = true;
  }
  public RegisterService(String speaker, String coSpeaker, Boolean isFromBzh){
    this.speaker = speaker;
    this.coSpeaker = coSpeaker;
    this.isFromBzh = isFromBzh;
  }
}

OVERLOADING KOTLIN

class RegisterService(val speaker: String, val coSpeaker: String?, val isFromBzh = true)














// BZH

FLOW CONTROL

IF

val marty = Speaker("Marty")
val adrien = Speaker("Adrien")

// The program runs some mystic algorithms

val speakerForBreizhCamp = if (marty.isNotInThePast()) {
  print("Choose ${marty.name}")
  marty
} else {
  print("Choose ${adrien.name}")
  adrien
}

ELVIS OPERATOR

val city = user?.address?
  .city ?: throw IllegalArgumentException("Invalid User")
findOrder()?.let { dun(it.customer) }

WHEN

val currentAction = when (year) {
  1985 -> "On the parking lot with Doc and Marty"
  1955 -> "Marty in the past"
  2015, 2030 -> "Marty in the futur"
  in 2011..2018 -> "Marty in the BreizhCamp"
  else -> {
    print("Qui t'appelles « banane », banane ?")
  }
}

WHEN

when {
  isGeorgeWantToDateLorraine() -> scareHimWithADarkVadorVoice()
  !isTheCityHallClockSettedUp() -> findDoc()
  isDeloreanFullyCharged(delorean) -> travel()
}



// BZH

TRY CATCH

val answer: Int = try {
  parseInt(input)
}
catch (e: NumberFormatException) {
  42
}

KOTLIN STANDARD LIBRARY

val speaker = "McFly"
val year = 1985
if(speaker.isNotBlank()){
  print("""BTTF with ${speaker.capitalize()}""")
  print(year.plus(33))
}

KOTLIN STANDARD LIBRARY

val years = arrayOf(1985, 1992, 2018)
print(years.average())



//

EXTENSIONS

Le polyfill du Java dans Kotlin

EXTENSIONS

open class Humain {
    fun voyager(destination: String) {
        print("Voyager ${destination}")
    }
}

class Doc : Humain() {
    fun voyagerDansLeTemps(destination: String, annee: Int) {
        // ...
    }
}

val humain: Humain = Humain()
humain.voyager("en Bretagne")
humain.voyagerDansLeTemps("en Bretagne", 1985) // won't compile

val doc: Doc = Doc()
doc.voyagerDansLeTemps("en Bretagne", 1985)

//Back to the Breizh

EXTENSIONS

open class Humain {
    fun voyager(destination: String) {
        print("Voyager ${destination}")
    }
}

fun Humain.voyagerDansLeTemps(destination: String, annee: Int) {



}

val humain: Humain = Humain()
humain.voyager("en Bretagne")
humain.voyagerDansLeTemps("en Bretagne", 1985)




//Back to the Breizh

FUNCTIONAL PROGRAMMING

Kotlin n’est pas un langage fonctionnel

IMMUTABILITÉ

data class Speaker (val name: String, val location: String)

val marty = Speaker("Marty", "Hill Valley")

// Marty doit aller au BreizhCamp

IMMUTABILITÉ

data class Speaker (val name: String, val location: String)

val marty = Speaker("Marty", "Hill Valley")

marty.location = "BreizhCamp" // won't compile

IMMUTABILITÉ

data class Speaker (val name: String, val location: String)

val marty = Speaker("Marty", "Hill Valley")

val martyAuBreizhCamp = marty.copy(location = "BreizhCamp")

FONCTION D’ORDRE SUPÉRIEUR

fun doSomething(speaker: String, fn: (String) -> String): Unit {
    val result = fn(speaker)
    println(result)
}

doSomething("Marty", {s -> "${s} va à la plage de Treac’h er Goured"})

FONCTION D’ORDRE SUPÉRIEUR

fun goTo(destination: String): (String) -> Unit
  = { speaker -> println("${speaker} va à la ${destination}") }




// Marty doit aller à la plage

FONCTION D’ORDRE SUPÉRIEUR

fun goTo(destination: String): (String) -> Unit
  = { speaker -> println("${speaker} va à la ${destination}") }

val goToPlage = goTo("plage de Treac’h er Goured")


goToPlage("Marty")

POUR ALLER PLUS LOIN

COROUTINE

 

 

 

COROUTINE

frise

COROUTINE

fun journeyInThePast() = async(1955Context) {
    messUpParentProm().await()
    findPower().await()
    print "Marty"
}

launch() {
    print("fight Lebaneses")
    journeyInThePast().await()
    print("go away from Lebaneses")
}

COROUTINE

val messUpParentProm = async(){...}

val findPower = async(){...}

suspend fun journeyInThePast(): String {
    messUpParentProm().await()
    findPower().await()
    return "Marty"
}

launch() {
    print("fight Lebaneses")
    print(journeyInThePast().await())
    print("go away from Lebaneses")
}

KOTLIN ET LES FRAMEWORKS

  • Spring Boot + JUnit 5

  • jackson-kotlin

  • kTor

  • Javalin

  • Kotlin arrow

  • Jhipster-kotlin

  • Gradle - Kotlin DSL

KOTLIN MULTIPLATEFORME

  • JVM

  • JS

  • Natif

THANKS

Any Question ?