Ajouter un commentaire

Swift 5.5 améliore la programmation concurrente

Par:
fredericmazue

jeu, 23/09/2021 - 13:37

Apple a publié la version 5.5 de son langage de programmation Swift. Il s'agit d'une version majeure, qu'Apple qualifie même de 'massive'. Cette version apporte par exemple une meilleure interopérabilité avec Objective-C, les collections de paquets... Mais ce qui distingue surtout Swift 5.5 sont ses apports en ce qui concerne la programmation concurrente, au centre de laquelle se trouvent désormais les mots-clés async et await, qui ne sont pas sans rappeler ceux de C#.

Avec les versions précédentes du langage, une séquence d'opérations asynchrones simples nécessitait souvent des fermetures profondément imbriquées. Voici un exemple de code donné par Apple pour illustrer cela :

func processImageData1(completionBlock: (_ result: Image) -> Void) {
    loadWebResource("dataprofile.txt") { dataResource in
        loadWebResource("imagedata.dat") { imageResource in
            decodeImage(dataResource, imageResource) { imageTmp in
                dewarpAndCleanupImage(imageTmp) { imageResult in
                    completionBlock(imageResult)
                }
            }
        }
    }
}

processImageData1 { image in
    display(image)
}

Apple décrit un tel code comme une 'pyramide condamnée' (pyramid of doom). Cette pyramide condamnée rend difficile la lecture et le suivi de l'exécution du code. De plus, devoir utiliser une pile de fermetures entraîne de nombreux effets de second ordre qui sont décrit dans la proposition SE-0296 justifiant l'arrivée de async / await.

Les fonctions asynchrones, appelées async / wait, permettent d'écrire du code asynchrone comme s'il s'agissait d'un code synchrone linéaire. Cela résout immédiatement bon nombre des problèmes évoqués ci-dessus en permettant aux programmeurs d'utiliser pleinement les mêmes constructions de langage que celles disponibles pour le code synchrone. L'utilisation d'async/wait préserve également naturellement la structure sémantique du code, fournissant les informations nécessaires à au moins trois améliorations transversales du langage : (1) meilleures performances pour le code asynchrone ; (2) de meilleurs outils pour fournir une expérience plus cohérente lors du débogage, du profilage et de l'exploration du code ; et (3) une base pour les futures fonctionnalités de simultanéité telles que la priorité et l'annulation des tâches. 

Le mot-clé async déclare une fonction comme asynchrone, et l’appel est effectué via le mot-clé await. Voici un exemple de code tiré de SE-0296 donné par Apple :

func loadWebResource(_ path: String) async throws -> Resource
func decodeImage(_ r1: Resource, _ r2: Resource) async throws -> Image
func dewarpAndCleanupImage(_ i : Image) async throws -> Image

func processImageData() async throws -> Image {
  let dataResource  = try await loadWebResource("dataprofile.txt")
  let imageResource = try await loadWebResource("imagedata.dat")
  let imageTmp      = try await decodeImage(dataResource, imageResource)
  let imageResult   = try await dewarpAndCleanupImage(imageTmp)
  return imageResult
}

Les apports de Swift, vraiment conséquents, ne s'arrêtent pas à cela en ce qui concerne la programmation concurrente. Arrivent également AsyncSequence, la concurrence structurée, AsyncStream et AsyncThrowingStream, de nouveaux types qui remplissent un rôle similaire aux continuations, comblant le fossé entre le comportement asynchrone non basé sur async / await et le monde de async / await, les déclarations async let, qui différent de let en ce que l'expression d'initialisation est évaluée dans une tâche enfant distincte, exécutée simultanément, etc.

La note de version de Swift 5.5 est ici.

Filtered HTML

Plain text

CAPTCHA
Cette question permet de vérifier que vous n'êtes pas un robot spammeur :-)
 X   X   QQQ    L     EEEE  FFFF 
X X Q Q L E F
X Q Q L EEE FFF
X X Q QQ L E F
X X QQQQ LLLL EEEE F
Q