Post on 23-Jan-2018
DE JAVA À SWIFT EN 2 TEMPS
TROIS MOUVEMENTS
3 novembre 2016 ( )Didier Plaindoux @dplaindoux
Computer scientist Freelance
λ
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
DÉVELOPPER AVEC SWIFT
XCode
CLion
Vi, Emacs
EXÉCUTER SWIFT
iOS, OSX
Version 14.04+
(Docker)
IBM Cloud (LinuxOne)
LANGAGE INSPIRÉ PAR ...
Objective-C C#
Orienté Objet
Haskell OCaml
Fonctionnel
Ruby Python
Expressivité
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; } }
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 } }
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 } }
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 } }
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 } }
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 } }
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 } }
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 } }
SURVOL DU LANGAGE
DONNÉES, TYPES INITIAUX ETC.
Le Fonctionnel
Les Objets
VARIABLES OU CONSTANTES
JAVA SWIFT
int age
final String nom
var age:Int
let nom:String
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.
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 !
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"
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é}
Données, Types initiaux etc.
LE FONCTIONNEL
Les Objets
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
FONCTION
func Nom(Parametres) -> Type Resultat { Corps De La Fonction }
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
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)
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)
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
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)
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
CLOSURE :: SYNTHÈSE DE TYPE
let multiplier = { a,b in a * b }
error ambiguous use of operator '*'
Int ? Float ? Double ? ...
CLOSURE :: SYNTHÈSE DE TYPE !
let multiplier : (Int,Int) -> Int = { a,b in a * b }
Spéci�cation vs. Mise en oeuvre
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 !
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 }
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
Données, Types initiaux etcs.
Le Fonctionnel
LES OBJETS
LES OBJETS
Ecole Scandinave
Simula, C++, Objective-C, Ei�el, Java, C# ... Swift
Abstraction de donnée ↔ Classe ↔ Type
Repose sur un Typage Statique
PARADIGME OBJET
JAVA SWIFT
Interface Protocole
Classe Classe
∅ Structure
Enumération Enumération
PROTOCOLE
Base de connaissancesExtension de Protocoles
PROTOCOLE :: BASE DE CONNAISSANCES
public protocol Monde { func vivants() -> [Personne] func recherche(nom:String) -> Personne? }
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
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
CLASSE
Etat interneBase de connaissancesHéritage simpleMise en oeuvre de Protocoles
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)
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)
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 {...} }
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
STRUCTURE
Etat interneBase de connaissancesMise en oeuvre de Protocoles
STRUCTURE :: INITIALISATION
public struct Personne { let nom:String var age:Int }
Méthode init implicite. Redé�nition possible.
Personne(nom:"John Doe", age:42)
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
ENUMÉRATION
Spéci�cation de formesEtat interneBase de connaissancesMise en oeuvre de Protocoles
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
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
self ou ... Self
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
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"
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
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 !
UN TOUR D'HORIZON (TROP) RAPIDE !
Gestion des erreursStructure & MutationNotion de moduleSwift & Android via le NDK (Swift ⇒ C)etc ...
PROSÉLYTISME !
Meetup !
Site o�cielA curated list of awesome iOS ecosystem
MERCI