De java à swift en 2 temps trois mouvements

61
DE JAVA À SWIFT EN 2 TEMPS TROIS MOUVEMENTS 3 novembre 2016 ( ) Didier Plaindoux @dplaindoux

Transcript of De java à swift en 2 temps trois mouvements

Page 1: De java à swift en 2 temps trois mouvements

DE JAVA À SWIFT  EN 2 TEMPS  

TROIS MOUVEMENTS

3 novembre 2016 ( )Didier Plaindoux @dplaindoux

Page 2: De java à swift en 2 temps trois mouvements

Computer scientist Freelance

λ

Page 3: De java à swift en 2 temps trois mouvements

Développement lancé en 2010 par Chris Lattner

HISTORIQUE DE SWIFT

v1.0: Dévoilé durant la WWDC en 2014v2.0: Ouverture du compilateur en 2015v3.0: Publication en septembre 2016

Page 4: De java à swift en 2 temps trois mouvements

DÉVELOPPER AVEC SWIFT

XCode

CLion

Vi, Emacs

Page 5: De java à swift en 2 temps trois mouvements

EXÉCUTER SWIFT

iOS, OSX

Version 14.04+

(Docker)

IBM Cloud (LinuxOne)

Page 6: De java à swift en 2 temps trois mouvements

LANGAGE INSPIRÉ PAR ...

Objective-C C#

Orienté Objet

Haskell OCaml

Fonctionnel

Ruby Python

Expressivité

Page 7: De java à swift en 2 temps trois mouvements

MÉTAMORPHOSE D'UNE CLASSE JAVA

public class Personne { private final String nom; private int age;

public Personne(String nom, int age) { this.nom = nom; this.age = age; }

public void anniversaire() { this.age += 1; } }

Page 8: De java à swift en 2 temps trois mouvements

SÉPARATEURS

public class Personne { private final String nom private int age

public Personne(String nom, int age) { this.nom = nom this.age = age } public void anniversaire() { this.age += 1 } }

Page 9: De java à swift en 2 temps trois mouvements

ATTRIBUTS

public class Personne { private let nom:String // Constant private var age:Int // Variable

public Personne(String nom, int age) { this.nom = nom this.age = age }

public void anniversaire() { this.age += 1 } }

Page 10: De java à swift en 2 temps trois mouvements

PARAMÈTRES

public class Personne { private let nom:String private var age:Int

public Personne(nom:String, age:Int) { this.nom = nom this.age = age }

public void anniversaire() { this.age += 1 } }

Page 11: De java à swift en 2 temps trois mouvements

INITIALISATION

public class Personne { private let nom:String private var age:Int

public init(nom:String, age:Int) { this.nom = nom this.age = age }

public void anniversaire() { this.age += 1 } }

Page 12: De java à swift en 2 temps trois mouvements

FONCTION

public class Personne { private let nom:String private var age:Int

public init(nom:String, age:Int) { this.nom = nom this.age = age }

public func anniversaire() -> Void { this.age += 1 } }

Page 13: De java à swift en 2 temps trois mouvements

FONCTION OU PROCÉDURE

public class Personne { private let nom:String private var age:Int

public init(nom:String, age:Int) { this.nom = nom this.age = age }

public func anniversaire() { this.age += 1 } }

Page 14: De java à swift en 2 temps trois mouvements

UNE CLASSE SWIFT

public class Personne { private let nom:String private var age:Int

public init(nom:String, age:Int) { self.nom = nom self.age = age }

public func anniversaire() { self.age += 1 } }

Page 15: De java à swift en 2 temps trois mouvements

SURVOL DU LANGAGE

Page 16: De java à swift en 2 temps trois mouvements

DONNÉES, TYPES INITIAUX ETC.

Le Fonctionnel

Les Objets

Page 17: De java à swift en 2 temps trois mouvements

VARIABLES OU CONSTANTES

JAVA SWIFT

int age

final String nom

var age:Int

let nom:String

Page 18: De java à swift en 2 temps trois mouvements

LES COLLECTIONS

JAVA SWIFT

Arrays.asList("Hello", "World")

Map<String, Integer> m = new HashMap<>(); m.put("A", 10); m.put("B", 20);

["Hello", "World"]

["A":10, "B":20]

Fonctions disponibles map, �atMap, �lter etc.

Page 19: De java à swift en 2 temps trois mouvements

DONNÉE OPTIONNELLE

JAVA SWIFT

Optional<String> n = Optional.of("A"); Optional<Integer> t = n.map(v -> v.length()); if (t.isPresent()) { // t.get(); }

let n:String? = "A" // ou nil let t:Int? = n?.characters.count if let taille = t { // taille utilisable }

Fonctions disponibles map, �atMap, �lter etc.

Donnée optionnelle "portée" par le typage uniquement. Non structurel !

Page 20: De java à swift en 2 temps trois mouvements

TUPLES

JAVA

SWIFT

Index ↔ Nom

(42, "John Doe") // (Int, String) (42, "John Doe").1 == "John Doe"

(42, nom:"John Doe") // (Int, String) (42, nom:"John Doe").1 == "John Doe" (42, nom:"John Doe").nom == "John Doe"

Page 21: De java à swift en 2 temps trois mouvements

STRUCTURES DE CONTRÔLE

Sélection conditionnelle

Garde pour les optionnels

Répétition

if expression { // bloc en cas de succés } else { // bloc optionnel en cas d'échec }

guard let valeur = expression else { // valeur n'est pas définie }

// valeur est définie

let segment = 0..<100 for index in segment { // bloc répété}

Page 22: De java à swift en 2 temps trois mouvements

Données, Types initiaux etc.

LE FONCTIONNEL

Les Objets

Page 23: De java à swift en 2 temps trois mouvements

TYPE FONCTIONNEL

JAVA SWIFT

Type aliasing

Function<A,B> Supplier<B> Consumer<A> Predicate<A> ...

(A) -> B () -> B (A) -> () (A) -> Bool ...

typealias Supplier<B> = () -> B

Page 24: De java à swift en 2 temps trois mouvements

FONCTION

func Nom(Parametres) -> Type Resultat { Corps De La Fonction }

Page 25: De java à swift en 2 temps trois mouvements

FONCTION :: PARAMÈTRES

func multiplier(a:Int, b:Int) -> Int { return a * b }

En interne les noms des paramètres capturent les valeurs lors de l'appel

multiplier(a:2, b:3)

En externe les noms des paramètres servent de "marques" pour les arguments

Permutation des arguments interdite

Page 26: De java à swift en 2 temps trois mouvements

FONCTION :: NOM EXTERNE SPÉCIFIQUE

Spéci�cation d'un nom externe di�érent

func multiplier(a:Int, par b:Int) -> Int { return multiplier(a:a, b:b) }

multiplier(a:2, par:3)

Page 27: De java à swift en 2 temps trois mouvements

FONCTION :: AUCUN NOM EXTERNE

Spéci�cation a�n de ne pas avoir de nom externe

func multiplier( _ a:Int, par b:Int) -> Int { return multiplier(a:a, b:b) }

multiplier(2, par:3)

Page 28: De java à swift en 2 temps trois mouvements

FONCTION ANONYME :: CLOSURE

JAVA

SWIFT

[Parametres] -> [Corps De La Fonction]

{ [Parametres] -> [Type Retour] in [Corps De La Fonction] } { [Parametres] in [Corps De La Fonction] }

Objet de Première Classe

Page 29: De java à swift en 2 temps trois mouvements

CLOSURE :: EXEMPLES

let multiplier = { (a:Int, b:Int) -> Int in a * b }

Pas de séléction par nommage des paramètres car inutile !

multiplier(2,3)

Page 30: De java à swift en 2 temps trois mouvements

CLOSURE :: SYNTHÈSE DE TYPE

let multiplier = { (a:Int,b:Int) in a * b } let multiplier = { (a,b:Int) in a * b } let multiplier = { a,b -> Int in a * b }

// (Int, Int) -> Int

Page 31: De java à swift en 2 temps trois mouvements

CLOSURE :: SYNTHÈSE DE TYPE

let multiplier = { a,b in a * b }

error ambiguous use of operator '*'

Int ? Float ? Double ? ...

Page 32: De java à swift en 2 temps trois mouvements

CLOSURE :: SYNTHÈSE DE TYPE !

let multiplier : (Int,Int) -> Int = { a,b in a * b }

Spéci�cation vs. Mise en oeuvre

Page 33: De java à swift en 2 temps trois mouvements

FONCTION :: ORDRE SUPÉRIEUR

Fonction qui manipule une fonction

func appliquer(_ f:(Int) -> Int, _ a:Int) -> Int { return f(a) }

// appliquer(f,a) ⟶* f(a)

Forme restreinte au type Int → Int !

Page 34: De java à swift en 2 temps trois mouvements

FONCTION :: GÉNÉRICITÉ

Paramétrisation à la C++, Java, C#

func appliquer<A,B>(_ f:(A) -> B, _ a:A) -> B { return f(a) }

Possibilité de spéci�er des contraintes

func estEgal<A:Equatable>(_ a:A, _ b:A) -> Bool { return a == b }

Page 35: De java à swift en 2 temps trois mouvements

INCONSISTANCE & PIÈCES MANQUANTES

η-conversion pas généralisable en présence de surcharges équivalentes

Récursivité terminale Non garantie par le compilateur

Compréhension Concept inexistant

{ x in f(x) } ≡? f

Page 36: De java à swift en 2 temps trois mouvements

Données, Types initiaux etcs.

Le Fonctionnel

LES OBJETS

Page 37: De java à swift en 2 temps trois mouvements

LES OBJETS

Ecole Scandinave

Simula, C++, Objective-C, Ei�el, Java, C# ... Swift

Abstraction de donnée ↔ Classe ↔ Type

Repose sur un Typage Statique

Page 38: De java à swift en 2 temps trois mouvements

PARADIGME OBJET

JAVA SWIFT

Interface Protocole

Classe Classe

∅ Structure

Enumération Enumération

Page 39: De java à swift en 2 temps trois mouvements

PROTOCOLE

Base de connaissancesExtension de Protocoles

Page 40: De java à swift en 2 temps trois mouvements

PROTOCOLE :: BASE DE CONNAISSANCES

public protocol Monde { func vivants() -> [Personne] func recherche(nom:String) -> Personne? }

Page 41: De java à swift en 2 temps trois mouvements

PROTOCOLE :: MISE EN OEUVRE

extension Monde { func recherche(nom:String) -> Personne? { return vivants().filter{ p in p.nom == nom }.first } }

Assimilable au "default" des interfaces dans Java 8

Idem pour les classes, structures et enumérations

Page 42: De java à swift en 2 temps trois mouvements

PROTOCOLE :: GÉNÉRICITÉ

protocol Copiable { associatedtype E func copier<C:Copiable where C.E == E>() -> C // 0_o }

Spéci�cation de Type Membre ≢ Paramétrisation

Spécialisation par le typealias

Page 43: De java à swift en 2 temps trois mouvements

CLASSE

Etat interneBase de connaissancesHéritage simpleMise en oeuvre de Protocoles

Page 44: De java à swift en 2 temps trois mouvements

CLASSE :: ETAT INTERNE & INITIALISATION

public class Personne { private let nom:String private var age:Int

public init(nom:String, age:Int) { self.nom = nom self.age = age } }

Pas de mot clé new

Personne(nom:"John Doe", age:42)

Page 45: De java à swift en 2 temps trois mouvements

CLASSE :: INITIALISATION & OPTIONNEL

Initialisation pouvant retourner nil

public class Personne { private let nom:String private var age:Int

public init?(nom:String, age:Int) { guard age > -1 else { return nil } // if age < 0 { return nil }

self.nom = nom self.age = age } }

let personne:Personne? = Personne(nom:"John Doe", age:-1)

Page 46: De java à swift en 2 temps trois mouvements

CLASSE :: BASE DE CONNAISSANCES

Méthode d'instance(surchargeable)

Méthode statique(non surchargeable)

Méthode de classe(surchargeables)

class Personne { ⊞ ... func aPourNom() -> String { return self.nom } }

class Personne { ⊞ ... static func new(nom:String) -> Personne {...} }

class Personne { ⊞ ... class func new(nom:String) -> Personne {...} }

Page 47: De java à swift en 2 temps trois mouvements

CLASSE :: REFERENCE TYPEpublic class Personne { private let nom:String private var age:Int

⊞ public init(nom:String, age:Int) { ... } }

let personne1 = Personne(nom:"John Doe", age:42)let personne2 = personne1

personne1 et personne2 référencent la même donnée en mémoire

Page 48: De java à swift en 2 temps trois mouvements

STRUCTURE

Etat interneBase de connaissancesMise en oeuvre de Protocoles

Page 49: De java à swift en 2 temps trois mouvements

STRUCTURE :: INITIALISATION

public struct Personne { let nom:String var age:Int }

Méthode init implicite. Redé�nition possible.

Personne(nom:"John Doe", age:42)

Page 50: De java à swift en 2 temps trois mouvements

STRUCTURE :: REFERENCE VALUEvar personne1 = Personne(nom:"John Doe", age:42)let personne2 = personne1

personne1.age += 1

// personne1.age == 43 // personne2.age == 42

personne1 et personne2 ne référencent pas la même donnée en mémoire

Page 51: De java à swift en 2 temps trois mouvements

ENUMÉRATION

Spéci�cation de formesEtat interneBase de connaissancesMise en oeuvre de Protocoles

Page 52: De java à swift en 2 temps trois mouvements

ENUMÉRATION :: SPÉCIFICATION DE FORMES

public enum StadePersonne { case Enfant, Adolescent, Adulte }

let s : StadePersonne = ... switch s { case StadePersonne.Enfant: // ... case StadePersonne.Adolescent: // ... case StadePersonne.Adulte: // ... }

Le switch/case doit être exhaustif / Véri�é à la compilation

Page 53: De java à swift en 2 temps trois mouvements

ENUMÉRATION :: SWITCH AVANCÉ

public enum PeutEtre<T> { case QuelqueChose(value:T), Rien

public func get(_ valeurParDefaut:T) -> T { switch self { case .QuelqueChose(let v): return v case _: return valeurParDefaut } } }

Pattern Matching

Page 54: De java à swift en 2 temps trois mouvements

self ou ... Self

Page 55: De java à swift en 2 temps trois mouvements

self : Self

public class Personne { private let nom:String private var age:Int

⊞ public init(nom:String) { ... }

public func anniversaire() -> Self { self.age += 1 return self } }

Le type Self dénote le type de l'objet courant à savoir ... self

Page 56: De java à swift en 2 temps trois mouvements

DÉNOTATION DU TYPE COURANT

JAVA SWIFT

interface Copiable<Self extends Copiable<Self>> { Self copie(); }

protocol Copiable { func copie() -> Self }

"F-Bounded quanti�cation polymorphism"

Page 57: De java à swift en 2 temps trois mouvements

SELF :: COPIABLE

class Personne : Copiable { private let nom:String private var age:Int

func copie() -> Self { return type(of:self).init(nom:self.nom, age:self.age) }

required init(nom:String, age:Int) { self.nom = nom self.age = 0 } }

required force la dé�nition dans les sous-classes

Page 58: De java à swift en 2 temps trois mouvements

SELF :: INITIALISATION

class Personne { private let nom:String private var age:Int

required init(nom:String, age:Int) { self.nom = nom self.age = 0 }

class func new(nom:String) -> Self { return self.init(nom:nom, age:0) // self ≡ Personne } }

Cela me rappelle furieusement le new de Perl !

Page 59: De java à swift en 2 temps trois mouvements

UN TOUR D'HORIZON (TROP) RAPIDE !

Gestion des erreursStructure & MutationNotion de moduleSwift & Android via le NDK (Swift ⇒ C)etc ...

Page 60: De java à swift en 2 temps trois mouvements

PROSÉLYTISME !

Meetup !

Site o�cielA curated list of awesome iOS ecosystem

Page 61: De java à swift en 2 temps trois mouvements

MERCI