Retrouvez cet article dans : Linux Magazine 82
Smalltalk est un langage, un environnement de développement, qui mérite à être connu. Avec un modèle objet simple, clair et cohérent, des mécanismes réflexifs sophistiqués (c’est-à -dire la possibilité pour le programme de modifier sa structure et son comportement lors de l’exécution) et des outils de développement évolués, il permet de se concentrer sur l’essentiel : écrire rapidement un code de qualité, facile à déboguer et à faire évoluer. Avec cet article, nous commençons par un tour d’horizon historique et quelques aspects syntaxiques du langage.
Une vision, un environnement et un langage
La genèse de Smalltalk commence au début des années 1970 sous l’influence de Simula [Sim], Sketchpad [Ske] et LISP. Le premier introduit l’idée d’« objets » – bien que le terme programmation objet fût introduit avec Smalltalk – comme nouvelle approche de programmation pour conceptualiser et résoudre des problèmes. Le deuxième inventa l’interface graphique pour manipuler et interagir avec des objets informatiques. Enfin de LISP, Smalltalk reprend son ramasse-miettes (garbage collector) et son interactivité (recompilation incrémentale). Ces aspects sont au cœur de Smalltalk, à la fois un langage à objet pur et un environnement graphique pour interagir avec les classes et les objets. Le tout constitue la base d’un environnement informatique non plus réservé aux spécialistes, mais accessible au plus grand nombre. C’était la vision de l’informatique personnelle et du Dynabook d’Alan Kay, dont les idées sont réalisées dans le 100$ PC récemment annoncé par le MIT.
Alan Kay est l’initiateur de Smalltalk et, au début des années 70, il rejoignit le centre de recherche Xerox Parc en Californie [Dea]. Avec d’autres dont Dan Ingalls et Adele Goldberg, l’équipe développa les concepts de programmation objet et d’interface graphique. Elle inventa et développa la souris, le système de fenêtrage moderne, l’utilisation d’interface à bitmap, les dispositifs de transferts de bits (BitBlt), le paradigme MVC de développement d’interface utilisateur, le byte-code.
Dans les années 70 et jusqu’aux débuts des années 80, plusieurs versions successives virent le jour : Smalltalk-72, Smalltalk-74, Smalltalk-76 et enfin Smalltalk-80. Ces versions furent développées sur des ordinateurs personnels Alto [Xerox]. L’intégration d’un environnement graphique au langage était pour Alan Kay essentiel. Il s’agissait d’un amplificateur d’idées pour l’utilisateur afin de lui permettre d’expérimenter librement avec l’environnement et d’en tirer le meilleur. D’autres aspects forts du langage sont le tout objet, l’uniformité du modèle, une capacité complète d’introspection – réflexivité du langage – et le paradigme de la compilation incrémentale qui décuple la vitesse de développement.

Fig. 1 : Alto III avec Smalltalk-76. On reconnaît le navigateur de classes au centre.
Bien que datant du début des années 80, Smalltalk-80 – que nous appellerons dorénavant Smalltalk – reste un langage d’actualité par la modernité de ses concepts (pureté, uniformité du modèle, simplicité, puissance d’extensions) et l’avance technologique qu’il avait en 1980. En fait, Smalltalk sans son environnement graphique ne serait plus vraiment Smalltalk, car alors on perdrait les outils graphiques de développement (navigateurs de classes, workspace, débogueur...) et de compilation incrémentale ou de déboguage/recompilation à la volée d’une application en fonctionnement.
Une émanation du laboratoire XeroxParc, ParcPlace, commercialisa un Smalltalk professionnel, maintenant nommé VisualWorks [VW]. D’autres sociétés développèrent leur propre Smalltalk (Dolphin Smalltalk, VisualAge Smalltalk d’IBM avec lequel VisualAge Java était développé). En 1996, la propagation de Smalltalk dans les entreprises américaines était de 60% par an. La déferlante Java qui convertit une partie des programmeurs C et C++ ralentit considérablement la croissance du langage. Mais depuis les années 2002, Smalltalk revient au premier plan : par exemple, des sociétés telles que AMD, JPMorgan, UPS, Les Mutuelles du Mans... l’utilisent pour des applications très sensibles : chez AMD toute la chaîne de production de gravure de leurs microprocesseurs est développée en Smalltalk ! C’est une application qui ne peut être arrêtée et où il est nécessaire de modifier le code à l’exécution. Pour les personnes qui apprécient de connaître d’où vient une idée, il faut savoir que les frameworks de tests unitaires tels que JUnit proviennent de SUnit, l’idée des « Design Patterns » (Schémas de conception), la notion de « frameworks » (cadres applicatifs), la méthodologie XP (eXtreme Programming), le modèle MVC (Modèle-Vue-Contrôleur), les refactorings, ont d’abord été développés en Smalltalk.
En 1996, une partie de l’équipe d’Alan Kay alors chez Apple, développa une version libre de Smalltalk, nommée « Squeak » [Squ] [SquFr]. Cette implantation de Smalltalk intègre en outre des fonctions graphiques et multimédias relativement importantes. Il est développé par une communauté très active. GNUSmalltalk [Gnu] est une autre implantation libre de Smalltalk, celui-ci est spécifiquement destiné à l’écriture de scripts, il est également activement développé et offre des possibilités de développement d’interfaces graphiques avec le toolkit TK. Finalement Smalltalk/X est une autre implantation de Smalltalk gratuite [StX]. VisualWorks est aussi disponible gratuitement pour toute application non commerciale.
Dans cet article et dans la série qui suivra nous utilisons Squeak, le Smalltalk open source multimédia. Les explications données sont applicables à toutes les implantations disponibles.
La philosophie de Smalltalk
Smalltalk a une approche qui, encore aujourd’hui, est très novatrice sur bien des aspects. Il nous semble donc opportun d’énumérer certains d’entre eux pour déjà mieux se familiariser avec ces principes souvent radicaux :
- Une abstraction forte par rapport au matériel (hardware). Ceci est réalisé en utilisant une machine virtuelle interprétant le byte-code Smalltalk et un environnement utilisateur entièrement défini en Smalltalk (i. e. en byte-code). Le premier, la machine virtuelle – VM – est un exécutable dépendant de la plate-forme matérielle, celui-ci interprète le byte-code Smalltalk ou le traduit en langage machine (pour les machines virtuelles ayant un traducteur tardif (Just in Time Translator) comme VisualWorks ou ST/X). Le deuxième, l’environnement, est le fichier image – appelé Image – qui est exécuté par la VM. L’image est indépendante de la plate-forme hardware. Elle peut être vu comme un instantané mémoire où l’on aurait gelé tous les objets manipulés par l’utilisateur (à l’image de la fonctionnalité de mise en veille des ordinateurs portables). Le source de l’image est présent dans un troisième fichier, le Source, celui-ci est accessible depuis l’environnement et il peut être modifié, les modifications sont enregistrées dans un quatrième fichier, le Change qui fonctionne comme un enregistreur de toutes les actions faites par l’utilisateur. Il est quasiment impossible (sauf corruption du disque) de perdre du code avec Smalltalk.
- Le tout objet, l’ensemble des composants du système sont des objets. Les opérateurs (multiplications, additions...) sont alors des méthodes qui opèrent sur des instances de classes de nombres, de chaînes de caractères ou de tout autre objet. De même les structures de contrôle sont des messages envoyés sur des instances de classe de Boolean. Quelques conséquences immédiates : (1) une très grande uniformité (facilité de compréhension du code source, si on ajoute à cela le choix de l’héritage simple, et d’un seul type d’accès aux attributs et messages) ; (2) une possibilité totale de surcharger les opérateurs et blocs de contrôle de l’ensemble des classes (puisque ce sont en fait des méthodes).
- Une syntaxe minimale. On a l’habitude de dire que sa définition tient sur une carte postale. La simplicité est une règle de conception très souvent adoptée en Smalltalk.
- Compilation incrémentale. Elle permet de recompiler – en byte-code – une classe ou même uniquement une méthode lorsque celle-ci a été modifiée. En cours de développement, ce mécanisme permet de modifier/recompiler une partie du code source de l’application sans avoir à la quitter. Ainsi le contexte lié au débogage n’est pas perdu et les bogues sont supprimés très rapidement. De même la compilation incrémentale est présente dans le débogueur : celui-ci permet non seulement de repérer les erreurs mais aussi de les corriger au vol. Ainsi dans une session type, une erreur – ou un signal – qui fait apparaître le débogueur, permet au programmeur de corriger la méthode problématique et de poursuivre le test de l’application sans aucune interruption brutale. La compilation incrémentale est le mode naturel de développement de Smalltalk.
- Réflexivité du langage. D’une part, Smalltalk est écrit en Smalltalk (la machine virtuelle, le parsing, la compilation en byte-code) et il est capable d’observer ses structures de données depuis le langage de la même façon que l’on interagit avec les objets habituels : par exemple, pour obtenir la liste des instances d’une classe
Rectangle. D’autre part, il est capable de modifier son comportement et sa sémantique : par exemple détection automatique d’erreurs d’accès à des attributs et modification du code source pour ajouter automatiquement, à la volée, les accesseurs correspondants. La réflexivité est naturelle en Smalltalk et les programmeurs l’emploient très souvent. - Outils de développement de haut niveau. Ceux-ci sont non seulement graphiques – et conviviaux – mais aussi de très haut niveau, car ils tirent parti de la réflexivité du langage. C’est en effet elle qui permet d’avoir de tels outils : le navigateur de classes pour l’édition, la compilation, l’organisation des classes et méthodes, la navigation dans les hiérarchies, etc. ; l’inspecteur pour étudier les attributs de tout objet ; le chercheur de méthodes (method finder) capable de trouver les méthodes répondant à un comportement donné (par exemple (
2 . 3 . 8) donnera la méthode puissance d’un nombre), etc. - Le ramasse-miettes (garbage collector). C’est un système automatique de collecte des objets inutilisés. Tant qu’une référence vers un objet existe, celui-ci reste en mémoire. Lorsqu’un objet n’est plus référencé – par exemple en affectant
nilà la seule variable référençant l’objet – son espace mémoire est réclamé par le ramasse-miettes.
Le modèle objet de Smalltalk
Le modèle objet de Smalltalk est simple et uniforme. Il est décrit par un ensemble de 7 règles :
- Règle 1 – Tout est un objet.
- Règle 2 – Un objet est instance d’une classe.
- Règle 3 – Une classe définit la structure (variables d’instance) des instances et spécifie les méthodes qui seront exécutées en réponse aux messages envoyés aux instances de la classe. Les variables d’instance sont privées à l’objet lui-même et toutes les méthodes sont publiques.
- Règle 4 – Une classe peut hériter d’une autre classe par héritage simple (encore le choix de la simplicité !).
- Règle 5 – Les objets communiquent entre eux par des échanges de messages. Lorsqu’un objet reçoit un message, la méthode correspondante de sa classe est recherchée, si elle n’existe pas, la recherche est étendue à sa super-classe.
- Règle 6 – Toutes les classes appartiennent au même arbre d’héritage. La classe
Objectest la racine de cet arbre. - Règle 7 – Les classes sont des instances de classes appelées méta-classes.
C’est tout ! Smalltalk inclut des méthodes anonymes ou plus communément appelées « lambda expressions », « fermetures lexicales » en LISP ou « blocs » dans le jargon Smalltalk. Ces blocs permettent d’exprimer simplement des itérateurs et des conditions de manière élégante [Book].
Quelques exemples
Avec Smalltalk tout commence avec l’espace de travail (workspace). C’est un peu comme le terminal virtuel du Linuxien bidouilleur. Il permet de tester en direct des fragments de code. Il est par exemple très pratique pour tester le comportement d’un objet que l’on ne connaît pas encore bien. Donc dès que son environnement Smalltalk (ici Squeak) est lancé, on commence par ouvrir un worskspace (espace de travail) : depuis le menu du monde (clic sur le fond), choisir open->workspace ou plus rapidement le raccourci [Alt]+[k]. Pour une version francisée de Squeak, consulter [SquFr]. Dans la suite, nous vous proposons d’expérimenter quelques exemples. Pour exécuter ces fragments de code, sélectionnez-les avec la souris et faites [Alt]+[d] (do-it) ou [Alt]+[p] (print-it) pour, en plus, afficher la valeur retournée par le bout de code. Il est aussi possible d’exécuter à partir de do it ou print it du menu contextuel (bouton milieu).

Fig. 2 : Un workspace. Un fragment de code qui, exécuté avec [Alt]+[d], a créé une loupe rectangulaire.
Création d’un objet
pi := -1 arcCos. «la variable pi référence une instance d’un Float»
En sélectionnant pi et par un [Alt]+[i], nous appelons un inspecteur d’objet. Notez la forme de l’envoi du message arcCos à l’objet -1. Sélectionnez l’expression suivante et exécutez-la.
monEtoile := StarMorph new. «la variable monEtoile référence une instance d’un StarMorph»
Premier envoi de messages
Les exemples précédents contiennent déjà des exemples d’envoi de messages, poursuivez en suivant les exemples ci-dessous.
monEtoile openInWorld. «Envoi du message unaire openInWorld à monEtoile qui a pour effet d’afficher l’étoile» monPoint := 50@10. «Envoi du message binaire @ à l’objet 50 avec comme argument 10, le résultat de ce message est une instance de Point, affectée à monPoint»
Ouvrez un inspecteur d’objet sur la variable monPoint. Vous pouvez observer les attributs x et y de l’objet.

Fig. 3 : Un inspecteur ouvert sur une instance de Point
monEtoile position: 100@100. «Envoi du message à mot-clé position: à monEtoile avec comme argument le point 100@100 « monEtoile color: Color orange.
Dans ce dernier exemple, il y a deux messages. Exécuté en premier, le message (de classe) unaire orange envoyé à la classe Color retourne une instance de cette classe définissant la couleur orange. Le deuxième message à mot-clé, color:, est envoyé à monEtoile et avec comme argument le résultat du message précédent. Vous pouvez sélectionner toutes les instructions pour exécuter d’un coup le script et obtenir une étoile de couleur orange.
Structure de contrôle
pi > 3 ifTrue: [Beeper beep]. «Beep si pi effectivement plus grand que 3»
pi > 3 est un message binaire > envoyé à pi avec comme argument 3. Ce message retourne un objet booléen. Ce booléen reçoit ensuite le message ifTrue: avec comme argument le bloc de code [Beeper beep]. Ce dernier bloc de code est exécuté si le receveur du message, pi > 3, retourne un boolean de valeur true. Il est ainsi possible de créer, depuis le langage lui-même, d’autres structures de contrôle. Il suffit pour cela de définir de nouvelles méthodes dans la classe Boolean. Notez cependant que ce besoin est rare car les structures de contrôle de Smalltalk sont riches et par défaut optimisées par le compilateur, donc avantageuses en coût à l’exécution.
Itérateurs
#(1 2 3) collect: [:x | x * x]. «Un print-it retourne la collection #(1 4 9)»
#(1 2 3) définit un tableau, une collection statique d’objets, ici des nombres. Le message à mot-clé collect: est un itérateur sur la collection, avec comme argument le bloc de code. Ce bloc de code est en fait une fonction anonyme avec comme argument x qui prend les différentes valeurs de la collection. Le caractère | dans le bloc sépare la déclaration de l’argument et le code du bloc qui est exécuté à chaque itération et dont le résultat est collationné. Cette collection est retournée à la fin de l’itération.
#(100 200 300 400) do: [:i | monEtoile copy position: i@i ; openInWorld]. «crée une série de copies de monEtoile»
Ce dernier exemple reprend différents éléments des exemples précédents. Le caractère ; permet d’envoyer en cascade des messages à un même receveur, ici l’instance retournée par le message unaire monEtoile copy.
Les articles à venir
Notre présentation de Smalltalk s’achève ici, nous avons découvert l’historique du langage ainsi que quelques éléments de sa conception objet et de sa syntaxe. Nous espérons avoir aiguisé votre curiosité pour la suite. Même si vous n’envisagez pas de programmer en Smalltalk dans le futur, sa connaissance permet de mieux appréhender les mécanismes fondamentaux de la programmation par objet et par la même de devenir plus productif avec d’autres langages de programmation comme C++, Java ou Python. Dans les prochains articles, nous vous ferons découvrir la syntaxe et le modèle objet plus précisément, Seaside un époustouflant framework pour développer des applications web dynamiques [Sea], les outils de développement et la programmation incrémentale, la réflexivité du langage, la machine virtuelle et plein d’autres surprises. En attendant, vous pouvez déjà consulter les quelques références proposées.
Références :
- [Sim] Simula l’ancêtre des langages objet, http://fr.wikipedia.org/wiki/Simula
- [Ske] L’ancêtre des CAD, http://en.wikipedia.org/wiki/Sketchpad
- [Xerox] Le premier ordinateur personnel avec interface graphique, http://en.wikipedia.org/wiki/Xerox_Alto
- [Squ] Site de référence de Squeak http://www.squeak.org,
- [SquFr] Site francophone de Squeak, http://community.ofset.org/wiki/squeak
- [Gnu] GNU Smalltalk, http://www.gnu.org/software/smalltalk/smalltalk.html
- [StX] Un Smalltalk multiplateforme gratuity, http://www.exept.de/
- [Dea] Michael A. Hiltzik, Dealers of Lightning :Xerox PARC and the Dawn of the Computer Age.
- [Sea] Seaside, un framework pour développer des applications web dynamiques, http://www.seaside.st/
- [Book] Recueil de livres gratuits sur Smalltalk, http://www.listic.univ-savoie.fr/~ducasse/FreeBooks.html
Retrouvez cet article dans : Linux Magazine 82

