1. John Siracusa
    1. Mountain Lion
      1. Introduction
      2. Achat et installation
      3. Changements d'interface (1)
      4. Changements d'interface (2)
      5. Changements d'interface (3)
      6. Applications (1)
      7. Applications (2)
      8. Applications (3)
      9. Applications (4)
      10. Applications (5)
      11. iCloud(1)
      12. iCloud(2)
      13. iCloud(3)
      14. Gatekeeper(1)
      15. Gatekeeper(2)
      16. Retina et HiDPI
      17. Fourre-tout (1)
      18. Fourre-tout (2)
      19. Fourre-tout (3)
      20. Fourre-tout (4)
      21. Fourre-tout (5)
      22. Fourre-tout (6)
      23. Recommandations
      24. Deux pères, un fils
    2. Lion
      1. Introduction
      2. Installation
      3. Revoir les fondamentaux
      4. Redimensionnement des fenêtres
      5. Et voici pour les cinglés
      6. La gestion des fenêtres
      7. Le modèle de document
      8. le modèle des processus
      9. Les éléments internes (1)
      10. Les éléments internes (2)
      11. ARC
      12. Le système de fichiers
      13. Ses modifications dans Lion
      14. Documents, résolution
      15. Le Finder
      16. Mail, Safari
      17. Fourre tout (1)
      18. Fourre tout (2)
      19. Recommendations
    3. Snow Leopard
      1. Introduction
      2. Le ticket d'entrée
      3. L'installation
      4. Nouvel aspect
      5. Détails internes
      6. Quick Time X
      7. Système de fichiers
      8. Faire plus avec plus
      9. LLVM et Clang
      10. Les blocs
      11. Concurrence
      12. Grand Central Dispatch
      13. Asynchronicité
      14. Open CL
      15. La différence...
      16. Quick Time Player
      17. Le Dock
      18. Le Finder
      19. Exchange
      20. Performances
      21. Fourre tout (1)
      22. Fourre tout (2)
      23. Le futur
    4. Leopard
      1. Introduction
      2. L'héritage
      3. Nouvel aspect 1
      4. Nouvel aspect 2
      5. Le noyau
      6. 64 bits
      7. FS Events
      8. Core animation
      9. Quartz GL
      10. Core UI
      11. Détails internes
      12. Le Finder
      13. Le Dock
      14. Time Machine
      15. Performances
      16. Pot pourri
      17. Demain
    5. Tiger
      1. Introduction
      2. Retour sur le passé
      3. Nouvel aspect de Tiger
      4. Mises à jour du noyau
      5. Le lancement
      6. Les méta-données
      7. Attributs étendus
      8. Listes de contrôle d'accès
      9. Spotlight 1
      10. Spotlight 2 : analyse et potentiel
      11. Types de fichiers
      12. Méta-données : la fin
      13. Quartz
      14. Quartz 2D Extreme
      15. Core Image
      16. La vidéo sous Tiger
      17. Dashboard
      18. Le Finder
      19. Les performances
      20. Pot pourri
      21. Conclusion
    6. Panther
      1. Introduction
      2. Les précédents
      3. L'installation
      4. Nouvel aspect
      5. Performances
      6. Changement rapide d'utilisateur
      7. Gestion des fenêtres
      8. Exposé
      9. Le Finder
      10. Performance du Finder
      11. Toujours le même
      12. Safari
      13. XCode
      14. Conclusion
    7. Jaguar
      1. Introduction
      2. Le nom
      3. L'installation
      4. Modifications d'Unix
      5. Dévelopeurs...
      6. Quoi de neuf
      7. Rendezvous
      8. Quartz Extrême
      9. Performance
      10. Compositions
      11. Le Finder
      12. Applications
      13. Sherlock
      14. Le portrait
    8. Puma
      1. Prelude
      2. Introduction
      3. Installation
      4. Réglages système
      5. Performance
      6. Redimensionnement des fenêtres
      7. Utilisation de la mémoire
      8. Diagnostics de mémoire
      9. L'environnement Classique
      10. L'interface Utilisateur
      11. Le Finder
      12. Extensions de fichiers
      13. Divers, conclusion
    9. Cheeta (Mac OS X 10.0)
      1. Qu'est ce que Mac OS X
      2. Installation
      3. Le démarrage
      4. Utilisation de la RAM
      5. Performance
      6. Performance des applications
      7. Stabilité
      8. L'interface utilisateur
      9. Le Finder
      10. Le navigateur du Finder
      11. Le Finder (divers)
      12. L'interface utilisateur
      13. Os X Classique
      14. Système de fichiers
      15. Unix
      16. Applications
      17. Conclusion
    10. Les débuts de MacOsX
      1. 1999 : OSX DP2
      2. 2000 : Quartz et Aqua/a>
      3. Fin de la lune de miel
      4. la première bêta publique
      5. 2001 : Mac OS X 10.0
      6. Un investissement
    11. Finder Spatial
      1. Introduction
      2. Interfaces spatiales
      3. Le Finder spatial
      4. Le concierge
      5. Un nouveau Finder
      6. Le browser
      7. Le browser spatial
      8. Finder et méta-données
      9. Les modèles
      10. Pensées finales

Les blocs




Dans Léopard des neiges, Apple a introduit une extension de langage C appelée les "blocs". Les blocs ajoutent des fermetures (closures) et des fonctions anonymes (anonymous functions) au C et à ses langages dérivés (C++, Objective C et Objective C++).

Ces caractéristiques sont disponibles dans les langages de programmation dynamique comme Lisp, Smalltalk, Perl, Python, Ruby, et même dans le modeste Javascript depuis longtemps (des décades, dans le cas de Lisp- un fait volontairement mis en avant par ses adeptes). Alors que les programmeurs de langages dynamiques considèrent des fermetures et les fonctions anonymes comme normales, ceux qui travaillent dans des langages compilés statiques comme C et ses dérivés les trouvent plutôt exotiques. Quant aux non programmeurs, il est vraisemblable qu'ils n'éprouvent aucun intérêt pour le sujet. Mais je vais quand même tenter de m'expliquer, car les blocs forment le fondement de quelques technologies intéressantes qui vont être abordées plus tard.

Peut-être que la façon la plus simple d'expliquer les blocs, c'est de dire qu'ils font des fonctions une autre forme de données. Les langages hérités de C ont déjà des pointeurs sur les fonctions, qui peuvent être passés comme des données, mais ceux-ci ne peuvent pointer que sur des fonctions qui ont été créées au moment de la compilation. La seule façon d'influencer le comportement d'une telle fonction, c'est de passer des arguments différents à la fonction, ou de définir des variables globales auxquelles on accède à partir de la fonction. Ces deux approches ont de gros désavantages.

Le passage d'arguments devient compliqué quand leur nombre et leur complexité s'accroît. Et puis, il se peut que vous ayez un contrôle limité sur les arguments qui vont être passés à votre fonction, comme dans le cas des fonctions de rappel (callbacks). Pour compenser, vous pouvez avoir à empaqueter tout ce dont vous avez besoin dans un objet contexte d'une forme ou d'une autre. Mais quand, comment, par qui les données du contexte vont-elle être utilisées peut être difficile à définir précisément. Souvent, une seconde fonction de rappel est nécessaire pour cela. C'est très pénible.

Quant à l'utilisation des variables globales, en plus du fait bien connu qu'elles sont anti-pattern, elles sont aussi non sécurisées vis à vis des threads. Les sécuriser exige des verrous ou une autre forme d'exclusion mutuelle pour empêcher de multiples invocations de la même fonction de se marcher sur les pieds. Et s'il y a quelque chose de pire que de naviguer dans la mer des APIs basées sur des fonctions de rappel, c'est de se colleter manuellement à des problèmes de sécurité des processus légers (threads).

Les blocs évitent tous ces problèmes en permettant à des amas de code fonctionnel -les blocs- d'être définis à l'exécution. C'est plus facile à comprendre avec un exemple. Je vais commencer en utilisant du Javascript, qui a une syntaxe un peu plus familière, mais les concepts sont les mêmes.
listing

J'ai créé une fonction appelée multiplier qui prend un seul argument, a, et le multiplie par une seconde valeur, b, qui est founie par l'utilisateur à l'exécution. Si l'utilisateur fournit le nombre 2, alors, un appel à multiplier(5) renvoie la valeur 10.
listing

Voici l'exemple ci-dessus réalisé avec des blocs en C :
listing

Par comparaison avec le code Javascript, j'espère que vous pouvez vous rendre compte comment la version C fonctionne. Dans l'exemple en C, l'accent circonflexe est la clé de la syntaxe des blocs. C'est un peu vilain, mais c'est très proche du C, dans la mesure où on adopte la syntaxe C existante pour les pointeurs sur une fonction, avec un ^ qui remplace *, comme le montre l'exemple.

listing

Vous pouvez me croire, quand je vous dis que cette syntaxe est tout à fait cohérente pour des programmeurs C aguerris.

Et maintenant, est-ce que ça veut dire que C est soudain devenu dynamique, un langage de haut niveau comme JavaScript ou Lisp ? Pas vraiment. La distinction entre la pile et le tas, les règles qui régissent les variables automatiques et statiques, et autres choses sont encore là, avec leurs pleins effets. Et en plus, il y a maintenant un nouvel ensemble de règles pour définir comment les blocs interagissent avec. Il y a même un attribut new_block de type storage pour contrôler la visibilité et la durée de vie des valeurs utilisées dans les blocs.

Tout cela dit, les blocs représentent encore un gain énorme dans C. Grâce aux blocs, les APIs sympathiques dont on a depuis longtemps profité dans les langages dynamiques sont maintenant disponibles pour les langages dérivés du C. Par exemple, supposons que vous vouliez appliquer une certaine opération à chaque ligne d'un fichier. Pour le faire, un langage de bas niveau comme le C a besoin du code classique pour ouvrir et lire le fichier, gérer les erreurs, lire chaque ligne dans une mémoire tampon, et tout nettoyer à la fin.
listing

La partie en rouge est une représentation simplifiée de ce que vous voulez faire pour chaque ligne. Le reste est le code standard nécessaire. Si vous avez à faire des opérations variées sur les lignes de nombreux fichiers, ce code standard devient lassant.

Ce que vous aimeriez faire, c'est l'incorporer dans une fonction que vous pourriez appeler. Mais alors, vous êtes confronté(e) à la difficulté d'exprimer les opérations que vous voudriez faire sur chaque ligne des fichiers. Au milieu de chaque bloc standard, beaucoup de lignes de code, peut-être pour exprimer les opérations à faire. Ce code peut être amené à utiliser ou modifier des variables locales qui sont modifiées par programme, si bien que des pointeurs à des fonctions ne marchent pas. Que faire ?

Grâce aux blocs, vous pouvez définir une fonction qui prend un nom de fichier et un bloc comme arguments. Cela vous cache tout le code sans intérêt.

listing

Ce qui reste est une expression beaucoup plus claire de ce que vous voulez faire, avec moins de bruit autour. L'argument après le nom de fichier est un bloc littéral, qui prend comme argument une ligne de texte.

Même quand le volume du code standard est faible, le gain en simplicité et en clarté sont encore appréciables. Voyez cette boucle, la plus simple possible, qui s'exécute un nombre de fois déterminé. En C, même cette construction de base offre un grand nombre de risques de bogues. Faisons dix fois do_something() :
listing

Mince, j'ai fait une petite faute, là non ? Ça arrive aux meilleurs d'entre nous. Mais pourquoi ce code serait-il plus compliqué que la phrase qui sert à le décrire ? Répéter quelque chose 10 fois ! Je n'ai pas voulu le faire 11 fois ! Les blocs peuvent aider, si on fait un peu l'effort de définir une fonction plus claire :
listing

On peut alors supprimer la bogue pour de bon :
listing

Et souvenez-vous, l'argument du bloc pour repeat() peut contenir exactement le même type de code, copié et collé, littéralement, que celui qui serait apparu dans une boucle for...

Toutes ces possibilités, et plus, ont été utilisées par les langages dynamiques : map, reduce collect, etc... Bienvenue, programmeurs en C, dans un ordre plus haut.

Apple a appris la leçon par cœur, en rajoutant plus de 100 nouvelles APIs qui utilisent les blocs dans Léopard des neiges. Beaucoup de ces APIs ne seraient pas possibles sans les blocs, et toutes sont plus élégantes et plus concises qu'elles ne l'auraient été autrement.

Apple a l'intention de proposer les blocs comme extension à un ou plusieurs des langages basés sur le C, bien qu'il ne soit pas bien facile de savoir, quel organisme de standard peut être réceptif à ce genre de proposition. Pour le moment, les blocs sont supportés par les quatre compilateurs d'Apple dans Mac OS X.