Home About us Products Services Contact us Bookmark
:: wikimiki.org ::
Ramasse-miettes

Ramasse-miettes

Un ramasse-miettes, ou récupérateur de mémoire, ou glaneur de cellules (en anglais garbage collector, abrégé en GC) est un sous-système informatique de gestion automatique de la mémoire. Il est responsable du recyclage de la mémoire préalablement allouée puis inutilisée. Lorsqu'un système dispose d'un ramasse-miette, ce dernier fait généralement partie de l'environnement d'exécution associé à un langage de programmation particulier. Le ramassage des miettes a été inventé par John McCarthy comme faisant partie du premier système Lisp.

Définition et fonctionnement

Le principe de base de la récupération automatique de la mémoire est simple :
- déterminer quels objets dans le programme ne peuvent pas être utilisés,
- récupérer le stockage utilisé par ces objets. Bien qu'en général il soit impossible de déterminer à l'avance à quel moment un objet ne sera plus utilisé, il est possible de le découvrir à l'exécution : un objet sur lequel le programme ne maintient plus de référence, donc devenu inaccessible, ne sera plus utilisé.

Principe d'accessibilité d'un objet

Les ramasse-miettes utilisent un critère d'accessibilité pour déterminer si un objet peut être potentiellement utilisé. Les principes sont :
- un ensemble distinct d'objets qui sont supposés atteignables, ce sont les racines. Dans un système typique ces objets sont les registres machine, la pile, le pointeur d'instruction, les variables globales. En d'autres termes tout ce qu'un programme peut atteindre directement.
- tout objet référencé depuis un objet atteignable est lui-même atteignable. Dit autrement : un objet atteignable peut être obtenu en suivant une chaîne de pointeurs ou de références. Bien évidemment, un tel algorithme est une approximation conservatrice de l'objectif idéal de destruction des valeurs ne servant plus : certaines valeurs peuvent fort bien être accessibles depuis les racines mais ne plus jamais être utilisées. Cet objectif idéal est cependant inaccessible algorithmiquement : déterminer quelles valeurs serviront dans le futur est équivalent au problème de l'arrêt. Cette approximation conservatrice est la raison de la possibilité de fuites de mémoire, c'est-à-dire de l'accumulation de blocs de mémoire qui ne seront jamais réutilisés, mais jamais libérés non plus. Par exemple, un programme peut conserver un pointeur sur une structure de donnée qui ne sera jamais réutilisée. Il est pour cette raison recommandé d'écraser les pointeurs vers des structures inutilisées, afin d'éviter de conserver des références inutiles.

Algorithme de base

L'algorithme du ramasse-miettes est dû à Schorr et Waite. Les ramasse-miettes effectuent des cycles de ramassage. Un cycle est démarré lorsque le récupérateur décide (ou est notifié) qu'il doit récupérer de l'espace de stockage. Un cycle est constitué des étapes suivantes :
- Créer des ensembles dit noir, gris et blanc. Initialement, l'ensemble noir est vide, l'ensemble gris contient les objets « racines » et éventuellement certains objets supplémentaires choisis en fonction de l'algorithme particulier employé, et l'ensemble blanc contient tout le reste. À tout moment dans l'exécution de l'algorithme, un objet ne peut être que dans un seul des trois ensembles. L'ensemble blanc peut être vu comme l'ensemble des objets dont nous essayons de récupérer l'espace mémoire ; au cours du cycle, l'algorithme ôtera des objets de l'ensemble blanc, y laissant les objets dont il peut réclamer l'espace mémoire.
- Choisir un objet de l'ensemble gris, déplacer cet objet vers l'ensemble noir, déplacer tous les objets blancs référencés directement par cet objet vers l'ensemble gris. Cette étape est répétée jusqu'à ce qu'il n'y ait plus d'objets dans l'ensemble gris.
- Quand il n'y a plus d'objets dans l'ensemble gris, alors tous les objets restant dans l'ensemble blanc ne sont pas atteignables, et l'espace mémoire qu'ils utilisent peut être réclamé. L'invariant des trois couleurs peut être traduit comme ceci : aucun objet noir ne pointe directement sur un objet blanc. Observons que l'algorithme ci-dessus préserve l'invariant des trois couleurs. La partition initiale n'a pas d'objet noir, de sorte que l'invariant est trivialement respecté. Par la suite, si un objet devient noir, tous ses fils directs (les objets qu'il référence) deviennent gris, ceci préservant l'invariant. Lorsque la dernière étape de l'algorithme est réalisée, parce que l'invariant est préservé, aucun des objets de l'ensemble noir ne pointe vers un objet de l'ensemble blanc (et il n'y a plus d'objet gris) ce qui signifie que les objets blancs résiduels sont inatteignables depuis les racines. Le système peut alors appeler leurs destructeurs et libérer leur espace mémoire. Certaines variantes de l'algorithme ne respectent pas l'invariant des trois couleurs, mais ils utilisent un principe différent par lequel toutes les propriétés importantes sont respectées.

Variantes

L'algorithme de base a plusieurs variantes.
- Les ramasse-miettes qui déplacent les objets en mémoire (qui changent leur adresse), dits stop and copy.
- Certains récupérateurs peuvent correctement identifier toutes les références à un objet : ils sont appelés des récupérateurs « exacts », par opposition avec des récupérateurs « conservateurs » ou « partiellement conservateurs ». Les ramasse-miettes « conservateurs » doivent présumer que n'importe quel suite de bits en mémoire est un pointeur si (lorsqu'ils sont interprétées comme un pointeur) il pointe sur un quelconque objet instancié. Ainsi, les récupérateurs conservateurs peuvent avoir des faux négatifs, où l'espace mémoire n'est pas réclamé à cause des faux pointeurs accidentels. En pratique ceci est rarement un gros inconvénient.
- Le ramasse-miettes peut s'exécuter en alternance ou en parallèle avec le reste du système ; les récupérateurs les plus simples suspendent l'exécution du système lorsqu'ils exécutent un cycle ; ils ne sont pas incrémentaux ; les récupérateurs incrémentaux entrelacent leur travail pour s'exécuter pendant les temps d'inactivité du reste du système. Certains récupérateurs incrémentaux peuvent s'exécuter complètement en parallèle dans un thread séparé ; ils peuvent en théorie s'exécuter sur un processeur différent, mais le coût de la mise en cohérence des caches rend cette approche moins pratique qu'il n'y paraît.

Classification des ramasse-miettes

Les récupérateurs peuvent être classés en considérant la façon dont ils implémentent les trois ensembles d'objets blancs, gris et noirs.

Marquage et nettoyage

Ou mark and sweep en anglais. Un ramasse-miettes de ce type maintient un bit (ou deux) associé à chaque objet pour indiquer s'il est blanc ou noir ; l'ensemble gris est maintenu soit comme une liste séparée ou en utilisant un autre bit. Un récupérateur copieur distingue les objets gris et noirs en les copiant vers d'autres zones mémoire (l'espace de copie) et souvent différencie les objets noirs des objets gris en bi-partitionnant l'espace de copie (dans le cas le plus simple en maintenant un unique pointeur qui indique la séparation entre les objets noirs et gris).

Récupérateur à générations

Ou generational GC en anglais. Toutes les données d'un programme n'ont pas la même durée de vie. Certaines sont éliminables très peu de temps après leur création (par exemple, une structure de donnée créée uniquement pour retourner une valeur d'une fonction, et démantelée dès que les données en ont été extraites). D'autres persistent pendant toute la durée d'exécution du programme (par exemple, des tables globales créées pendant l'initialisation). Un ramasse-miette traitant toutes ces données de la même façon n'est pas forcément des plus efficaces. Une solution serait de demander au programmeur d'étiqueter les données créées selon leur durée de vie probable. Cependant, cette solution serait lourde à utiliser ; par exemple, il est courant que les données soient créées dans des fonctions de bibliothèque (par exemple, une fonction créant une table de hachage), il faudrait leur fournir les durées de vie en paramètre. Une méthode moins invasive est le système des générations. Le ramasse-miette opère alors sur une hiérarchie de 2 ou plus générations, étagées de la plus « jeune » à la plus « âgée ». Les données nouvellement créées sont (en général) placées dans la génération la plus jeune. On ramasse assez fréquemment les miettes dans cette génération jeune ; les données encore présentes à l'issue de la destruction des données inaccessibles de cette génération sont placées dans la génération d'âge supérieur, et ainsi de suite. L'idée est que les données de plus courte durée de vie n'atteignent, pour la plupart, pas la génération supérieure (elle peuvent l'atteindre si elles viennent d'être allouées quand le ramassage de miettes les repère dans la génération jeune, mais c'est un cas rare). On utilise généralement 2 ou 3 générations, de tailles croissantes. Généralement, on n'utilise pas le même algorithme de ramasse-miette pour les diverses générations. Il est ainsi courant d'utiliser un algorithme non incrémental pour la génération la plus jeune : en raison de sa faible taille, le temps de ramasse-miette est faible et l'interruption momentanée de l'exécution de l'application n'est pas gênante, même pour une application interactive. Les générations plus anciennes sont plutôt ramassées avec des algorithmes incrémentaux. Le réglage des paramètres d'un ramasse-miettes à génération peut être délicat. Ainsi, la taille de la génération la plus jeune peut influencer de façon importante le temps de calcul (un surcoût de 25%, par exemple, pour une valeur mal choisie) : temps de ramasse-miette, impact sur la localité du cache... Par ailleurs, le meilleur choix dépend de l'application, du type de processeur et d'architecture mémoire.

Comptage de références

Une solution qui vient vite à l'esprit pour la libération automatique de zones de mémoire est d'associer à chacune un compteur donnant le nombre de références qui pointent sur elle. Ces compteurs doivent être mis à jour à chaque fois qu'une référence est créée, alterée ou détruite. Lorsque le compteur associé à une zone mémoire atteint zéro, la zone peut être libérée. Cette technique souffre d'un inconvénient certain lors de l'usage de structures cycliques : si une structure A pointe sur une structure B qui pointe sur A (ou, plus généralement, s'il existe un cycle dans le graphe des références), mais qu'aucun pointeur extérieur ne pointe ni sur A ni sur B, les structures A et B ne sont jamais libérées : leurs compteurs de références sont strictement supérieurs à zéro (et comme il est impossible que le programme accèdent à A ou B, ces compteurs ne peuvent jamais repasser à zéro). En raison de ces limites, certains considèrent que le comptage de références n'est pas une technique de récupération de mémoire à proprement parler ; ils restreignent le terme de récupération de mémoire à des techniques basées sur l'accessibilité. Le comptage de références souffre de certains problèmes sérieux, comme son coût élevé en temps de calcul et aussi en espace mémoire et, comme on l'a vu, l'impossibilité de gérer les références circulaires. D'un autre côté, il récupère les « miettes » plutôt vite, ce qui présente des avantages s'il y a des destructeurs à exécuter pour libérer les ressources rares autres (sockets...) que le tas (mémoire). Des systèmes hybrides utilisant le comptage de références pour obtenir la libération quasi immédiate des ressources, et appelant à l'occasion un récupérateur de type Mark and Sweep pour libérer les objets contenant des cycles de références, ont été proposés et parfois implémentés. Cela donne le meilleur des deux mondes, mais toujours au prix d'un coût élevé en termes de performances.

Langages dotés de ramasse-miettes


- Common Lisp, Scheme, Smalltalk, Caml, Haskell, Prolog, Oz
- interpréteurs de commandes et langages de scripts comme Bash, Csh, Korn shell, etc.
- Java, C#, Eiffel
- Perl, Javascript, Ruby
- Le langage de programmation Python utilise un mécanisme de comptage de références doublé depuis la version 2.2 d'un garbage collector pour la destruction des cycles.

Avantages et inconvénients des ramasse-miettes

Les langages utilisant un ramasse-miettes permettent d'écrire des programmes plus simples et plus sûrs. La mémoire étant gérée automatiquement par l'environnement d'exécution, le programmeur est libéré de cette tâche, source de nombreuses erreurs difficiles à débusquer. La gestion manuelle de la mémoire est l'une des sources les plus courantes d'erreur. Trois types principaux d'erreurs peuvent se produire :
- l'accès à une zone non allouée, ou qui a été libérée,
- la libération d'une zone déjà libérée,
- la non-libération de la mémoire inutilisée (fuites mémoire). L'utilisation d'outils et de méthodologie appropriés permet d'en réduire l'impact, tandis que l'utilisation d'un ramasse-miettes permet de les éliminer presque complétement – les fuites de mémoire restent possibles, bien que plus rares. Cette simplification du travail de programmation peut présenter quelques inconvénients, principalement au niveau des performances des programmes les utilisant. Des mesures montrent que dans certain cas l'implémentation d'un ramasse-miettes augmente les performances d'un programme, dans d'autre cas le contraire se produit. Le choix des paramètres du ramasse-miette peut aussi altérer ou améliorer significativement les performances d'un programme. Lorsque le ramasse-miette effectue de nombreuses opérations de copies en tâche de fond (cas de l'algorithme stop-and-copy), il tend à défragmenter la mémoire. Le ramasse-miettes peut ainsi se révéler plus rapide qu'un codage ad-hoc de l'allocation/désallocation. Les meilleures implémentations peuvent aussi optimiser l'utilisation des caches mémoires, accélérant ainsi l'accès aux données. À contrario, l'opération de collection est souvent coûteuse. Il est difficile de borner le temps d'exécution de la phase de collection des objets non atteignables. L'utilisation d'un ramasse-miettes standard peut donc rendre difficile l'écriture de programmes temps réel ; un ramasse-miettes spécialisé (temps-réel) doit être utilisé pour cela. Sans intervention du programmeur, un programme utilisant un ramasse-miettes a tendance à utiliser plus de mémoire qu'un programme où la gestion est manuelle (en admettant que, dans ce cas, il n'y a pas de fuites, d'erreur d'accès ou de libération). Toutefois, rien n'interdit d'employer des stratégies de pré-allocation des objets utilisés, dans des pools, lorsqu'on veut minimiser le taux d'allocation/désallocation. Dans ce cas, le ramasse-miettes fournit toujours le bénéfice d'une programmation sans erreur grave de gestion de la mémoire (une assurance). Bien que ce ne soit pas le but d'un ramasse-miettes son implémentation peut aussi faciliter l'implémentation de la persistance d'objet (certains algorithmes sont partagés).

Citations

« Il est dit que les programmeurs Lisp savent que la gestion de la mémoire est si importante qu'elle ne peut être laissée aux programmeurs, et que les programmeurs C savent que la gestion de la mémoire est si importante qu'elle ne peut être laissée au système » -- Bjarne Stroustrup peut-être tiré d'une source antérieure.

Voir aussi

Liens externes


- [http://www.dotnetguru.org/articles/GC/GC.html Les Ramasses-Miettes .NET et Java ]
- http://www.memorymanagement.org/ (textes en anglais)
- [http://www.cs.utexas.edu/users/oops/papers.html Publications du groupe OOPS de l'Université du Texas] (textes en anglais)
- [http://www.cs.kent.ac.uk/people/staff/rej/gc.html Resources sur les ramasses-miettes] (textes en anglais)

Références

H. Schorr, W.M. Waite, An Efficient Machine-Independent Procedure for Garbage Collection in Various List Structures. CACM Août 1967 Catégorie:Algorithmique ja:ガベージコレクション

Informatique

ko:컴퓨터 과학 ja:情報工学 simple:Computer science th:วิทยาการคอมพิวเตอร์ zh-cn:计算机科学 zh-tw:計算機科學 oc:informatica] Etymologiquement, Le terme informatique désigne l'automatisation du traitement de l'information par une machine (virtuelle ou physique). Dans son acception courante, l'informatique désigne de façon vague l'ensemble des sciences et techniques en rapport de près ou de loin avec l'information et l'ordinateur. Par exemple, l'informatique désigne aussi bien le matériel informatique que la conception et l'administration de la partie immatérielle d'un ordinateur : les logiciels. La traduction anglaise étymologique serait informatics, mais l' usage tant en français qu'en anglais fait qu'une meilleure traduction serait probablement computer science, bien que ce terme fasse peut-être référence de façon plus explicite à ce que l'on pourrait appeler informatique fondamentale ou informatique scientifique. En anglais les termes distincts suivants sont utilisés :
- L'informatique fondamentale (Computer Science), ce qui ressort de l' épistémologie procédurale, soit notamment de l'étude des algorithmes, et donc indirectement des logiciels et des ordinateurs.
- L'ingénierie informatique (Computer Engineering), ce qui ressort de la fabrication et de l'utilisation du matériel informatique.
- L'ingénierie logicielle (Software Engineering), ce qui ressort de la modélisation et du développement des logiciels; ceci comprend le traitement des données (Data Processing), ce qui est du domaine de la mise en pratique des traitements de données.
- L'évolution des techniques et des technologies reliées à l'informatique (Information Technology). Des professions aussi diverses que concepteur, développeur, responsable d'exploitation, ingénieur système, technicien de maintenance, matérielle ou logicielle, chercheur en informatique ou directeur d'un centre de calcul, relèvent du domaine de l'informatique. Néanmoins, le terme informaticien désigne le plus souvent ceux qui conçoivent, déploient et mettent en œuvre des solutions.

Étymologie

Le terme informatique a été créé en mars 1962 par Philippe Dreyfus à partir des mots «information» et «automatique». Il donna ce nom à l'entreprise qu'il venait de fonder, la Société d'Informatique Appliquée, sans breveter le mot informatique. En France, l'usage officiel du mot a été consacré par Charles de Gaulle qui, en Conseil des ministres, a tranché entre «informatique» et «ordinatique», et le mot fut choisi par l'Académie française en 1967 pour désigner cette nouvelle discipline. En juillet 1968, le ministre fédéral de la Recherche scientifique d'Allemagne, Gerhard Stoltenberg, prononça le mot informatik lors d'un discours officiel au sujet de la nécessité d'enseigner cette nouvelle discipline dans les universités de son pays, et c'est ce mot qui servit aussitôt à nommer certains cours dans les universités allemandes. Le mot informatica fit alors son apparition en Italie et en Espagne, de même quinformatics au Royaume-Uni. Pendant le même mois de mars 1962 Walter F. Bauer inaugura la société américaine Informatics Inc., qui elle breveta son nom et poursuivit toutes les universités qui utilisèrent ce nom pour décrire la nouvelle discipline, les forçant à se rabattre sur computer science, bien que les diplômés qu'elles formaient étaient pour la plupart des praticiens de l'informatique plutôt que des scientifiques au sens propre. L'Association for Computing Machinery, la plus grande association d'informaticiens au monde, approcha même Informatics Inc. afin de pouvoir utiliser le mot informatics pour remplacer l'expression computer machinery, mais l'entreprise déclina l'offre. La société Informatics Inc. cessa ses activités en 1985, achetée par Sterling Software.

Histoire

Voir l'article détaillé : Histoire de l'informatique

Les origines

Depuis des millénaires, l'Homme a créé et utilisé des outils l'aidant à calculer (abaque, boulier, etc.). Les premières machines mécaniques apparaissent entre le XVIIe et le . La première machine à calculer mécanique réalisant les quatre opérations aurait été celle de Wilhelm Schickard au , mise au point notamment pour aider Kepler à établir les tables rudolphines d'astronomie. En 1642, Blaise Pascal réalisa également une machine à calculer mécanique qui fut pour sa part commercialisée et dont neuf exemplaires existent dans des musées comme celui des Arts et métiers et dans des collections privées (IBM). La découverte tardive du mécanisme d'Antikhitère montre que les Grecs de l'Antiquité eux-mêmes avaient commencé à réaliser des mécanismes de calcul en dépit de leur réputation de mépris général pour la technique (démentie d'ailleurs par les travaux d'Archimède). Cependant, il faudra attendre la définition du concept de programmation (illustrée en premier par Joseph Marie Jacquard avec ses métiers à tisser à cartes perforées, suivi de Boole et Ada Lovelace pour ce qui est d'une théorie de la programmation des opérations mathématiques) pour disposer d'une base permettant d'enchaîner des opérations élémentaires de manière automatique.

L'informatique moderne

L'ère des ordinateurs modernes commença avec les développements de l'électronique pendant la Seconde Guerre mondiale, ouvrant la porte à la réalisation concrète de machines opérationnelles. Au même moment, le mathématicien Alan Turing théorise le premier ce qu'est un ordinateur, avec son concept de machine universelle de Turing. L'informatique est donc un domaine fraichement développé, même s'il trouve ses origines dans l'antiquité (avec la cryptographie) ou dans la machine à calculer de Blaise Pascal, au . Ce n'est qu'à la fin de la Seconde Guerre mondiale qu'elle a été reconnue comme une discipline à part entière et a développé des méthodes, puis une méthodologie qui lui étaient propres. Son image a été quelque temps
surfaite : parce que les premiers à programmer des ordinateurs avaient été des ingénieurs rompus à la technique des équations différentielles (les premiers ordinateurs, scientifiques, étaient beaucoup utilisés à cette fin), des programmeurs sans formation particulière, parfois d'ailleurs issus de la mécanographie, cherchaient volontiers à bénéficier eux aussi de ce label de rocket scientist afin de justifier des salaires rendus confortables par :
- le prix élevé des ordinateurs de l'époque (se chiffrant en ce qui serait des dizaines de millions d'euros aujourd'hui compte-tenu de l'inflation, il reléguait au second plan les considérations de parcimonie sur les salaires) ;
- l'aspect présenté comme
peu accessible de leur discipline et un mythe de difficulté mathématique entretenu autour. En fait, les premiers ordinateurs ne se programmaient pas de façon très différente de celle des calculatrices programmables utilisées aujourd'hui dans les lycées et collèges, et maîtrisées par des élèves de quatorze ans mais le domaine était nouveau et l'algorithmique nécéssite un certain degré de concentration associé, peut-être à tort, à la réflexion pure. L'émergence d'un aspect réellement scientifique dans la programmation elle-même (et non dans les seules applications scientifiques que l'on programme) ne se manifeste qu'avec la série The Art of Computer Programming de Donald Knuth, professeur à l'Université de Stanford, à la fin des années 1960, travail monumental encore inachevé en 2004. Les travaux d'Edsger Dijkstra, Niklaus Wirth et Christopher Strachey procèdent d'une approche également très systématique et elle aussi quantifiée. On demandait à Donald Knuth dans les années 1980 s'il valait mieux selon lui rattacher l'informatique (computer science) au génie électrique — ce qui est souvent le cas dans les universités américaines — ou à un département de mathématiques. Il répondit : «Je la classerais volontiers entre la plomberie et le dépannage automobile» pour souligner le côté encore artisanal de cette jeune science. Toutefois, la forte scientificité des trois premiers volumes de son encyclopédie suggère qu'il s'agit là plutôt d'une boutade de sa part. Au demeurant, la maîtrise de langages comme Haskell ou même APL demande un niveau d'abstraction tout de même plus proche de celui des mathématiques que des deux disciplines citées. La miniaturisation des composants et la réduction des coûts de production, associées à un besoin de plus en plus pressant de traitement des informations de toutes sortes (scientifiques, financières, commerciales...) a entraîné une diffusion de l'informatique dans toutes les couches de l'économie comme de la vie de tous les jours.

Approche fonctionnelle

Comme énoncé ci-dessus, l'informatique est le traitement automatisé de données par un appareil électronique : l'ordinateur ; les germanophones parlent de
elektronisch Daten Verarbeitung / EDV (« traitement électronique de données »), les anglophones dinformation technology / IT (« technologies de l'information »), c'est-à-dire :
- données ou informations : in fine, l'ordinateur manipule des nombres (d'où le terme anglais computer, littéralement « calculateur »), mais ces nombres peuvent représenter divers types d'informations :
  - des... nombres bien évidemment, dans le cas de calculs scientifiques (flottants) ou comptables (décimal, ou binaire entier)... ;
  - un texte, des lettres (caractères), que l'on peut mettre en forme avec un traitement de texte, imprimer, envoyer par courrier électronique... ;
  - du dessin vectoriel (CAO, logiciels d'illustration, et de typographie) ;
  - des images statiques (photographies) ou animées (vidéo), des hologrammes ;
  - des sons, enregistrés (technique du direct to disk) ou bien fabriqués par l'ordinateur (synthétiseur), que ce soient des bruitages, de la musique (cf. musique et informatique) ou de la parole ; :la conversion de ces informations en suite de nombres pose le problème du format des données, du codage et des formats normalisés (par exemple, représentations des nombres entiers ou à virgule flottante, format ASCII, Unicode, TeX ou RTF et polices PostScript ou TrueType pour les textes, formats bitmap, TIFF, JPEG, PNG, etc. pour les images fixes, formats QuickTime, MPEG pour les vidéos, interface MIDI pour la musique...).
- automatisé : l'utilisateur n'intervient pas, ou peu, dans le traitement des données ; le traitement est défini dans un programme qui se déroule tout seul, l'utilisateur se contente de fournir des paramètres de traitement ; le programme automatique se déroule selon un algorithme, l'établissement de ce programme est le domaine de la programmation.
- traitement : ces données sont :
  - créées :
    - nombres : acquisition automatique de données d'une expérience avec un ordinateur ;
    - texte : taper un texte au clavier ;
    - images : dessins réalisés à la souris ou sur une tablette graphique, synthèse d'image (pour présenter un projet – objet fictif en cours de conception –, imagerie médicale, dessin artistique – infographie –, film d'animation ou pixilation) ou numérisation d'une image existante (scanner, appareil photographique numérique) ou d'images animées (caméra numérique, webcam) ;
    - sons enregistrés (microphone) ou recréés à partir d'une partition virtuelle (synthétiseur) ou d'un texte (synthèse vocale).
  - analysées :
    - nombres : l'analyse des nombres relève du domaine concerné (mathématiques, physique, économie...) ;
    - texte : rechercher les occurrences de mots dans un texte pour en tirer des statistiques, aide à la correction orthographique et/ou grammaticale, et, plus généralement, traitement automatique des langues (TAL) ;
    - images : on peut vouloir identifier un objet (reconnaissance de forme, reconnaissance des caractères ou OCR), ou bien déterminer la surface couverte par une couleur (par exemple pour quantifier une surface recouverte) ;
    - sons : analyse spectrale, reconnaissance vocale.
  - modifiées :
    - nombres : calculs ;
    - texte : modification d'un texte existant, traduction automatique dans une autre langue (ou langage de programmation) ;
    - images : modification du contraste, de la luminosité, des couleurs, effets spéciaux ;
    - sons : application d'effets (réverbération, distorsion, ajustement de la hauteur) ; ::comme il existe, selon les programmes et les besoins, une grande variété de codages possibles pour représenter chaque type d'information, beaucoup de traitements consistent à convertir les données d'un format vers un autre...
  - archivées puis restituées :
    - les moyens et techniques d'archivage varient en fonction de la durée de conservation souhaitée et des quantités de données en jeu : mémoires électroniques, bandes magnétiques, disques magnétiques ou optiques ;
    - les moyens de restitution dépendent de la nature des données : écrans ou imprimantes pour le texte et les images, haut-parleurs ou instruments MIDI pour les sons...

Approche organisationnelle

L'informatique pour l'organisation est un élément d'un système de traitement d'information (les entrées peuvent être des formulaires papier par exemple) et d'automatisation. Depuis Henry Ford, l'automatisation des tâches ayant été identifiée comme un avantage concurrentiel, la question est : que peut-on automatiser ? Autant il est relativement facile d'automatiser des tâches manuelles, autant il est difficile d'automatiser le travail intellectuel et parfois créatif. L'approche de l'informatique dans une organisation commence donc par l'élucidation des processus, c'est-à-dire modéliser le métier. Après validation, la MOA (Maîtrise d'Ouvrage) fournit les spécifications fonctionnelles de (l'ouvrage) qui vont servir de référence dans la conception pour la MOE (Maîtrise d'œuvre). Cette conception sera alors effectuée dans le respect d'un Cycle de développement qui définit les rôles et responsabilités de chaque acteur. Ainsi, les échanges entre MOA et MOE ne se résument pas à la maîtrise des chantiers (tenue des délais et des coûts, et validation des livrables), la MOA et la MOE sont garantes (éventuellement responsables sur un plan juridique) de la cohérence des systèmes d'information, et de l'adéquation des solutions informatiques avec les problèmes utilisateurs finaux initialement constatés.

Matériel

Article détaillé : Matériel informatique On utilise également le terme anglais hardware (littéralement « quincaillerie ») pour désigner le matériel informatique. Il s'agit de tous les composants que l'on peut trouver dans : 1. Les ordinateurs et leurs périphériques : un ordinateur est un ensemble de circuits électroniques permettant de manipuler des données sous forme binaire, représentées par des variations de signal électrique. Il existe différents types d'ordinateurs : ordinateur 5150 datant de 1981, Système d'exploitation IBM-DOS 2.0]]
- Les micro-ordinateurs. De bureau ou portables. Ils sont composés d'une unité centrale : un boîtier contenant la carte mère, l'alimentation, des unités de stockage. On y ajoute une console : un écran et un clavier. Divers périphériques peuvent leur être ajoutés, une souris, une imprimante, un scanner..ect; scanner
- Les stations de travail. Des micro-ordinateurs particulièrement puissants et chers, utilisés uniquement pour des besoins professionnels pointus (conception assistée par ordinateur). Ce terme était particulièrement en vogue dans les années 1980-1990. Depuis les années 2000, il n'est guère possible de concevoir une station de travail plus puissante qu'un micro-ordinateur haut de gamme ;
- Les mainframes. Une armoire abrite l'unité centrale et l'alimentation, une ou plusieurs autres les périphériques de stockage (disque dur, sauvegarde) tandis que les moyens de communication et réseau (routeur, hubs, modem) sont dans la même pièce, mais dans des racks séparés. Une console d'administration (écran, clavier, imprimante) est généralement située dans ce même local ; administration]
- Les PDA (Personal Digital Assistant, encore appelés organiseurs). Ce sont des ordinateurs de poche proposant des fonctionnalités liées à l'organisation personnelle (agenda, calendrier, carnet d'adresse, etc.). Ils peuvent être reliés à Internet par différents moyens (réseau Wifi, Bluetooth, etc.).
- Et bien d'autres appareils. Dans le domaine de l'informatique embarquée : téléphone, électroménager, automobile, armements militaires, etc. Les cartes à puces, ou l'informatique industrielle.

Logiciel

Le logiciel désigne la partie à première vue immatérielle de l'informatique, l'organisation et le traitement de l'information : les programmes. On s'est en effet vite rendu compte que des machines techniquement très avancées pour leur époque, comme la Bull Gamma 60, restaient invendables tant qu'on n'avait pas de programmes à livrer pour les rendre immédiatement opérationnelles. IBM lança entre 1968 et 1973 une sorte d'ancêtre du logiciel libre avec son ordinateur 1130, politique qui assura à celui-ci par effet boule de neige un succès immédiat et planétaire, mais les conclusions d'un procès antitrust lui interdirent de distribuer bénévolement du logiciel. Le monde des mainframes classe les logiciels en catégories suivantes :
- systèmes d'exploitation ;
- bases de données, comme DB2, Ingres ou Oracle ;
- programmes de communication, comme NCP ou RSCS ;
- moniteurs de télétraitement ;
- systèmes transactionnels, comme CICS ;
- systèmes de temps partagé, utilisés pour le calcul ou le développement ;
- compilateurs traduisant les langages en instructions machine et appels système ;
- tout le reste entrait en une catégorie nommée Logiciels applicatifs. Plus simplement on distingue généralement trois types de logiciels (par ordre de proximité du matériel) :
- le firmware
- le système d'exploitation
- les logiciels et applications utilisateur (en anglais software) On classe aussi les logiciels en libre et propriétaire, bien que les deux soient parfois panachés à des degrés divers. Certains ont une fonction bureautique ou multimédia comme par exemple les jeux vidéo. Certains logiciels ont acquis des noms connus de tous. Le noyau du système d'exploitation crée le lien entre le matériel et le logiciel. Un logiciel, quand il est fourni sous sa forme binaire, serait utilisable uniquement avec un système d'exploitation donné (car il en utilise les services), et ne fonctionnerait que sur un matériel spécifique (car il en utilise le code d'instructions). Une conception plus récente, depuis le milieu de années 1980, consiste à distribuer les logiciels tous binaires confondus, et à les munir d'un système de licences par jetons ou tokens permettant l'usage de N copies simultanées du logiciel sur le réseau, tous matériels confondus. Cette approche est majoritaire dans le monde UNIX. À l'initiative de Richard Stallman et du GNU, à partir de 1985, une mouvance de programmeurs refuse cette logique propriétaire et ceux-ci se muent en concepteurs inventifs pour se lancer dans le développement d'outils et de bibliothèques système libres compatibles avec le système UNIX. C'est pourtant le projet indépendant Linux, initié par Linus Torvalds, basé sur les travaux et les outils du GNU, qui aboutira dans la création d'un système d'exploitation complet et libre. Une bonne partie des logiciels actuels fonctionnent dans un environnement graphique pour interagir avec l'utilisateur. La diversité des systèmes informatiques a fait apparaître une technique visant à combiner le meilleur de chacun de ces univers : l'émulateur. Il s'agit d'un logiciel permettant de simuler le comportement d'un autre système dans celui que l'on utilise,
- soit pour qu'une machine semble être une autre (voir IBM 1130),
- soit pour simuler le comportement d'un système d'exploitation (par exemple DOS ou Windows sous Linux). Le terme anglais est software, à l'origine un jeu de mot entre hardware (« quincaillerie », pour désigner le matériel) et l'opposition soft/hard (mou/dur), opposition entre le matériel (le dur) et l'immatériel (le mou). Les traductions françaises matériel et logiciel rendent parfaitement cette opposition et cette complémentarité. Le logiciel réalise normalement une fonction attendue de ses utilisateurs. Néanmoins, des effets secondaires (parfois nommés par contresens de traduction effets de bord) existent. Parfois même, certains logiciels sont destinés à nuire, comme les virus informatiques, nommés en anglais, par analogie avec software : malware (qu'on pourrait traduire par le néologisme nuisiciel, ou logiciel malveillant).

La création des logiciels

Un projet informatique s'inscrit dans un cycle de développement qui définit les grandes étapes de la réalisation (planification), de la manière dont on passe d'une étape à l'autre (modèle incrémental, en V, en spirale, etc.). Pour les petits projets (ou les petites équipes de développement), cette réflexion est souvent négligée (on se répartit les modules et chacun développe dans son coin). Ceci est une cause fréquente d'erreurs (bogues) et de non-conformité (le produit final n'est pas conforme aux attentes de l'utilisateur). Mais même les énormes projets, avec beaucoup de moyens, sont victimes de cette négligence ; ainsi, l'échec du premier vol d'Ariane 5 fut dû à un problème de logiciel, etc. Un projet peut alors intégrer une approche de la qualité et de la sûreté de fonctionnement des systèmes informatiques afin de contrôler autant que possible le produit final. Un projet comprend les étapes suivantes :
- l'établissement d'un cahier des charges qui définit les spécifications auxquelles devra répondre le logiciel ;
- la définition de l'environnement d'exécution  (architecture informatique) :
  - type(s) d'ordinateur sur lequel le logiciel doit fonctionner (station de calcul, ordinateur de bureau, ordinateur portable, assistant personnel, téléphone portable, guichet automatique de banque, ordinateur embarqué dans un véhicule ;
  - type et version du(des) système(s) d'exploitation sous-jacent ;
  - périphériques nécessaires à l'enregistrement des données et à la restitution des résultats (capacité de stockage, mémoire vive, possibilités graphiques...) ;
  - nature des connexions réseau entre les composants (niveau de confidentialité et de fiabilité, performances, protocoles de communication...) ;
- la conception de l'application et de ses constituants, et notamment de l'interactivité entre les modules développés : structure des données partagées, traitement des erreurs générées par un autre module... : c'est le domaine du génie logiciel ;
- la mise en place d'une stratégie de développement :
  - répartition des tâches entre les développeurs ou les équipes de développement, qui vont assurer le codage et les tests ;
- le plan de test du logiciel, pour s'assurer qu'il remplit bien la mission pour laquelle il a été écrit, dans toutes les conditions d'utilisation qu'il pourra normalement rencontrer, mais aussi dans des cas limites. Après chacune de ces phases, on peut avoir une étape de recette, où le client va valider les choix et les propositions du maître d'œuvre. La phase de programmation consiste à décrire le comportement du logiciel à l'aide d'un langage de programmation. Un compilateur sert alors à transformer ce code écrit dans un langage informatique compréhensible par un humain en un code compréhensible par la machine, le résultat est un exécutable. On peut également, pour certains langages de programmation, utiliser un interpréteur qui exécute un code au fur et à mesure de sa lecture, sans nécessairement créer d'exécutable. Enfin, un intermédiaire consiste à compiler le code écrit vers du bytecode. Il s'agit également d'un format binaire, compréhensible seulement par une machine, mais il est destiné à être exécuté sur une machine virtuelle, un programme qui émule les principales composantes d'une machine réelle. Le principal avantage par rapport au code machine est une portabilité théoriquement accrue (il « suffit » d'implanter la machine virtuelle pour une architecture donnée pour que tous les programmes en bytecode puissent y être exécutés), portabilité qui a fait, après sa lenteur, la réputation de Java. Il convient de noter que ces trois modes d'exécution ne sont nullement incompatibles. Par exemple, OCaml dispose à la fois d'un interpréteur, d'un compilateur vers du bytecode, et d'un compilateur vers du code natif pour une grande variété de processeurs. Une fois écrit (et compilé si nécessaire), le code devient un logiciel. Pour des projets de grande amplitude, nécessitant la collaboration de beaucoup de programmeurs, voire de plusieurs équipes, on a souvent recours à une méthodologie commune (par exemple MERISE) pour la conception et à un atelier de génie logiciel (AGL) pour la réalisation. Au cours de la programmation et avant la livraison du produit final, le programme est testé afin de vérifier qu'il fonctionne bien (y compris dans des cas d'utilisation en mode dégradé) et qu'il est conforme aux attentes de l'utilisateur final. Les tests intermédiaires permettent de s'assurer que chaque module de code réalise correctement une fonction : ce sont les tests unitaires. Les tests finals qui vérifient le bon enchaînement des modules et des traitements sont des tests d'intégration. Pour certaines applications demandant un haut niveau de sûreté de fonctionnement, les tests sont précédés d'une étape de vérification, où des logiciels spécialisés effectuent (généralement sur le code source, mais parfois aussi sur le code compilé) un certain nombre d'analyses pour vérifier partiellement le bon fonctionnement du programme. Il n'est toutefois pas possible (et des théorèmes mathématiques montrent pourquoi), de garantir la parfaite correction de tout logiciel par ce moyen et la phase de test reste donc nécessaire. Elle se complète aussi, lorsqu'il s'agit d'une évolution d'une application existante, de nombreux tests automatisés de non-régression. Statistiques : la création d'un logiciel est une tâche ardue ; environ 31 % des projets informatiques sont abandonnés avant d'être terminés, plus de 50 % des projets coûtent le double du coût initialement estimé et seulement 15 % des projets finissent dans les temps et selon le budget défini. Les besoins de seule maintenance de l'existant peuvent prendre jusqu'à 50 % des effectifs d'une équipe chargée d'un logiciel (or, c'est là une fonction pénible, ingrate, peu valorisante et qui rebute et démotive les bons programmeurs).

Traitement de l'information

L'information, pour être traitée, doit être :
- représentée par un codage :
  - on utilise un système de numération binaire, où l'élément unitaire informationnel est le bit (contraction de l'anglais binary digit : chiffre binaire). Les bits sont généralement regroupés par huit, pour constituer des octets (ou bytes). Un octet peut être représenté par la séquence des bits qui le constituent (par exemple : 00101110) ou par une paire de valeurs hexadécimales (pour le même exemple : 2E), plus compact. Le choix du binaire ne résulte pas de la mystique, mais tout simplement d'utiliser de simples circuits de commutation, qui ont de très larges tolérances et par conséquent de faibles coûts ;
  - on représente la structuration de l'information pour permettre des échanges entre composants logiciels et entre composants matériels. Pour cela, on définit des langages et des formalismes de représentation.
- stockée dans des systèmes permanents (mémoires dites de masse) ou non (mémoires dites volatiles).

Échanges de données : protocoles et normes

Les protocoles définissent une manière de procéder, notamment pour codifier la façon dont deux entités communiquent (modules ou couches logicielles, périphériques, etc.). On parle notamment de protocole de communication lorsqu'on veut définir des mécanismes de contrôle sur la manière dont l'échange d'information est réalisé. Un protocole peut ainsi définir :
- un langage de description d'instructions et de données graphiques (exemple : AGP) ;
- un standard de commandes et de flux d'information pour une mémoire de masse (exemples : SCSI, FireWire, IDE, Serial ATA) ;
- des échanges entre le processeur et des cartes d'extension (exemples : PCI, PCI Express, ISA) ;
- des modalités de transfert d'information entre périphériques (exemple : USB) ou sur un réseau TCP/IP, Internet, ATM, X.25) ;
- des commandes entre un client et un serveur (exemples : POP3, IMAP, HTTP, FTP …) ;
- des échanges de données informatisés spécifiques (exemples : EDI, EAI, X.400, X.500). Certains protocoles sont définis par des normes pour permettre l'interopérabilité des matériels ou de logiciels les mettant en œuvre. D'autres normes définissent, toujours dans le domaine de l'échanges de données :
- des langages de représentation d'information sans pour autant définir la manière dont cette information peut être échangée (exemples : ASN.1, XML) ;
- des architectures de réseaux (exemples : Modèle OSI, Wifi, Ethernet, Token-Ring).

Stockage des données

En matière de stockage d'information, on distingue le dispositif permettant de l'enregistrer physiquement (périphériques et composants) de la manière dont on structure et représente l'information pour faciliter son traitement.

Mémoire de masse

:Fichier de cartes perforées :Bande magnétique :Disque amovible magnétique (Disquette) :Disque magnéto-optique :Disque dur (disque magnétique embarquant le mécanisme, l'électronique et les têtes de lecture) :Disque optique amovible (CD-ROM, CD-R, CD-RW mais aussi DVD-ROM, DVD-R, DVD-RW, DVD+R, DVD+R DL, DVD+RW, DVD-RAM, GD-ROM, HD-DVD, Blu-ray) :Mémoire électronique non volatile (Mémoire flash, clé USB)

Mémoire volatile

:RAM

Organisation des données en vue du stockage

:Formats (extensions) de fichiers :Système de fichiers :Base de données :Annuaire

Approches scientifiques

:L'informatique n'est pas plus la science de l'ordinateur que l'astronomie n'est celle du télescope. :: -- Edsger Dijkstra
En dehors des aspects industriels et technologiques décrits jusqu'ici, l'informatique est une discipline scientifique à part entière. :Algorithmique :Algèbre de Boole :Calculabilité :Géométrie algorithmique :Lambda-calcul :Logique :Model checking :Théorie de l'information :Théorie des graphes :Théorie de la complexité :Théorie de la calculabilité :Théorie des automates finis

Applications

:Bio-informatique :Calcul parallèle :Cryptographie :Exploration de données (data mining) :Informatique grand système (mainframe) :Informatique de gestion :Informatique industrielle :Informatique décisionnelle :Imagerie Informatique :Intelligence artificielle :Interface homme-machine :Micro-informatique :Traitement du signal :Hypermédias :Informatique musicale

Annexes


- Informathèque
- Abréviations en informatique
- Dictionnaire informatique
- Informatique alternative
- Liste des articles d'informatique
- Personnes célèbres en informatique
- Revues informatiques sur papier
- Sécurité informatique
- Sites d'informations sur internet
- Terminologie de la distribution informatique
- Réseaux de neurones
- Musique et informatique
- Ordinateur quantique
- Hello_world
- Visual Information Exploration
-


Mémoire vive

La mémoire vive, aussi appelée RAM (acronyme anglais de Random Access Memory, soit mémoire à accès aléatoire), est un type de mémoire informatique à accès aléatoire (par oppostion à séquentiel) et en lecture-écriture (par opposition à la lecture seule). On l'appelle aussi mémoire volatile pour signifier que toutes les données sont perdues à l'extinction de l'alimentation électrique. Il s'agit typiquement de la mémoire électronique qui contient les données en cours de traitement dans un ordinateur.

Terminologie

La mémoire vive (RAM) est généralement opposée à la mémoire morte (ROM) : Il est possible de lire et écrire de la mémoire vive alors qu'il est uniquement possible de lire de la mémoire morte. En revanche, la mémoire morte conserve les données lorsque l'alimentation électrique est coupée. La mémoire morte n'est donc pas volatile. Il existe aussi un type intermédiaire de mémoire électronique à accès aléatoire, accessible en lecture et écriture comme la RAM, mais non volatile comme la ROM : la NVRAM. Littéralement, le terme RAM implique la possibilité d'un accès aléatoire aux données, par opposition à un accès séquentiel, comme celui d'une bande magnétique. En ce sens, ROM et NVRAM sont aussi de la RAM, mais cette interprétation littérale porte à confusion avec l'usage courant qui oppose RAM et ROM. Rarement, on utilise le sigle RWM (pour Read Write Memory, soit mémoire en lecture écriture) pour désigner de la RAM en mettant l'accent sur la possibilité d'écriture plutôt que l'accès aléatoire.

Technologie

bande magnétique VAX 8600 (circa 1986).]] 1986 La mémoire informatique est un composant qui fut d'abord magnétique (tores de ferrite), puis devint électronique dans les années 1970, et qui permet de stocker et relire des informations binaires. Son rôle est notamment de stocker les données qui vont être traitées par l'unité centrale (ou le microprocesseur) ; elle n'a rien de commun en temps d'accès (quelques dizaines ou centaines de nanosecondes) avec le disque dur (quelques millisecondes, soit dix mille à cent mille fois plus). La RAM a la particularité de pouvoir être accédée en lecture et en écriture. Une activation électronique appropriée permet si besoin de verrouiller temporairement en écriture des blocs physiques donnés. L'adressage d'une mémoire (traduction de tensions électriques sur des fils en adresse mémoire) se fait par un mécanisme nommé le chip select. Il est très facile de munir un microprocesseur d'une mémoire non contiguë (par exemple de 0 à 4095, puis un trou, puis de la mémoire entre 16384 et 32767), ce qui facilite beaucoup la détection d'erreurs d'adressage éventuelles. Les informations peuvent être organisées en mots de 8, 16 ou 32 bits voir plus. Certaines machines anciennes avaient des mots de taille plus exotique, comme par exemple 60 bits pour le Control Data 6600, 36 bits pour l'IBM 7030 « Stretch » ou le DEC PDP-10 et 12 bits pour la plupart des premiers mini-ordinateurs de DEC, les appareils d'instrumentation travaillant au mieux sur 12 bits à l'époque. Mais :
- dans les mémoires à parité, un neuvième bit (dit de contrôle de parité) existe de façon invisible,
- dans les mémoires à correction automatique d'erreur sur 1 bit et détection sur plus d'un bit (ECC), ces bits invisibles sont parfois au nombre de six ou plus,
- chaque mot des mémoires des serveurs modernes dits non-stop ou 24x365 dispose en plus des bits de correction de bits de remplacement qui prennent la relève du ou des bits défaillants à mesure du vieillissement de la mémoire : une défaillance de 10-11 chaque année se traduit en effet par plus d'un bit défaillant par an sur une mémoire de 128 Go. Les fabricants recommandent souvent d'utiliser de l'ECC à partir d'1 Go de RAM.

Divers types de mémoire vive

Une memoire dynamique (DRAM) ne conserve ses informations que si elle est « rafraîchie » régulièrement, c'est-à-dire si un signal lui est transmis de manière régulière (toutes les x millisecondes) afin de remettre au bon niveau les charges électriques représentant l'information, et qui sinon s'affaibliraient progressivement jusqu'à disparaître. Pourquoi compte-tenu de ces contraintes de rafraîchissement et de consommation utiliser quand même de la DRAM ? Parce qu'elle est à la fois bon marché et rapide. En 2004, on trouve des barrettes de 32, 64, 128, 256, 512, 1024, 2048 et rarement 4096 Mo au catalogue des constructeurs - et donc dans les magasins de matériel informatique. On distingue sur les machines actuelles (2004) les types de mémoire RAM :
- SDRAM (Synchronous Dynamic RAM) pour les machines de la génération Pentium II, Pentium III
On distingue la SDRAM 66, 100 et 133 (fréquence d'accès en MHz).
- RDRAM (Rambus Dynamic RAM). Pour les machines de génération Pentium III et 4. Développées par la société RAMBUS, elles souffrent notamment d'un prix beaucoup plus élevé que les autres types de mémoires et de brevets trop restrictifs de la part de cette société.
- DDR-SDRAM (Double Data Rate-SDRAM). Pour les machines de génération Pentium III et 4.
On distingue les DDR PC1600, PC2100, PC2700, PC3200 etc. Le numéro représente la quantité théorique maximale de transfert d'information en Mégabits (il faut diviser par 8 pour avoir leur fréquence réelle de fonctionnement).
- DDR2-SDRAM (Double Data Rate 2-SDRAM). Pour les machines de génération Pentium 4 et plus.
On distingue les DDR2 533 et DDR2 667. Le numéro représente la vitesse maximum d'accès. Certains constructeurs privilégient encore la technique d'appellation basée sur la quantitée de données théoriquement transportables (PC4300, PC4500, etc), mais la plupart semblent retourner à la vitesse réelle de fonctionnement afin de distinguer plus clairement la DDR2 de la génération précédente.
- XDRRAM (XDimm Rambus RAM). Technologie basée sur la technologie Flexio développée par Rambus.
Elle permet d'envisager des débits théoriques de 6,4Go/s à 12,8Go/s en rafale. Il existe aussi des mémoires Flash. Ce sont des mémoires NVRAM effaçables électriquement (EEPROM), qui par conséquent gardent la mémoire sans être alimentée. On les utilise dans les appareils mobiles (appareils photo, téléphones portables etc.). Les utilisateurs de PDA auront déjà remarqué que leur temps d'accès, même en lecture seule, est pour le moment bien plus lente que celui de la mémoire dynamique.

Constructeurs de mémoire

Constructeurs de puces mémoire :
- Cypress
- Elpida
- Hynix
- IDT
- Infineon
- Micron, 2 plus grand fabricant (mars 2002), elle fournit notamment la mémoire pour les consoles de jeux Xbox
- Nanya
- Samsung
- Winbond Constructeurs de barettes de mémoire :
- Corsair
- Crucial
- Geil
- Kingston
- OCZ
- Samsung
- Twinmos
- DaneElec
- ProMos

Voir aussi


- Glossaire informatique
- [http://www.linternaute.com/hightech/maquestion/hardware/barette_ram.shtml Guide d'installation d'une barette de RAM] Catégorie:Mémoire informatique ja:Random Access Memory ko:램 simple:Random access memory th:แรม

Allocation de mémoire

Les algorithmes sous-jacents à tout programme informatique consomment essentiellement deux ressources : du temps et de l'espace. En machine, l'espace peut être la mémoire vive volatile ou la mémoire de masse persistante. Cet article discute de l'allocation de mémoire vive. Trois stratégies d'allocation peuvent être employées : allocation statique, allocation dynamique sur la pile, et allocation dynamique sur le tas. L'allocation statique est principalement le fait des langages de programmation compilés. Les langages interprétés ne peuvent, par définition, qu'allouer la mémoire à la demande, lors de l'exécution. A chacune des stratégies correspond une région mémoire du programme, ou segment. Ces segments sont nommés text (statique), stack (pile) et heap (tas). L'opération symétrique de l'allocation est couramment appelée libération de la mémoire (on peut parler également de désallocation ou de restitution).

Les trois modes d'allocation

Allocation statique

Allouer statiquement de la mémoire pour un programme signifie :
- prévoir l'espace mémoire nécessaire avant l'exécution du programme, en spécifiant la quantité nécessaire dans le code source,
- réserver cet espace au moment de la compilation, dans le fichier binaire produit,
- au chargement du programme en mémoire, juste avant l'exécution, l'espace réservé devient alors accessible. Lors de l'exécution, aucune allocation n'a lieu. L'avantage de l'allocation statique se situe essentiellement au niveau des performances, puisqu'on évite les coûts de l'allocation dynamique à l'exécution : la mémoire statique est immédiatement utilisable. Sur les systèmes d'exploitation communs, la mémoire allouée statiquement est placée dans le segment text, le segment data ou le segment bss du programme, selon le destin de cette zone mémoire ( reservée , initialisée , read only... ).

Allocation sur la pile

L'exécution d'un programme est généralement structurée autour d'une pile contenant les cadres d'appels à des fonctions (ou procédures) du langage de programmation source. Schématiquement, les variable lexicales, c'est à dire les variables définies dans la portée textuelle d'une fonction, sont donc allouée lors de l'entrée dans la fonction, et désallouées automatiquement lors de la sortie (du retour) de la fonction. Un segment mémoire, dit segment de pile, est utilisé pour ces allocation/désallocations. Aucun mot clef n'est nécessaire dans le code source d'un langage supportant la notion de variable lexicale : celles-ci sont allouées et libérées selon la discipline de pile par définition. Certains langages, comme C ou C++, parlent de variables locales ou automatiques au lieu de variables lexicales, mais il s'agit de la même chose.

Allocation sur le tas

La plupart des programmes ayant des besoins en mémoire dépendant de l'usage qu'on en fait, il est nécessaire de pouvoir, à des moments arbitraires de l'exécution, demander au système l'allocation de nouvelles zones de mémoire, et de pouvoir restituer au système ces zones (désallouer la mémoire). Dans ce cas, l'allocation et la libération de la mémoire sont sous la responsabilité du programmeur. Les fuites de mémoire, ainsi que d'autres erreurs fréquentes dans les programmes à gestion manuelle de la mémoire, ont leur source dans les erreurs d'allocation mémoire sur le tas. Classiquement, les fonctions de la libc malloc et free, les primitives du langage c++ new et delete permettent, respectivement, d'allouer et désallouer la mémoire sur le tas. Les langages de programmation dotés de ramasse-miettes utilisent, mais de façon transparente pour le programmeur, l'allocation sur la pile et les primitives alloc/free. Dans ce dernier cas, le ramasse-miette permet d'éviter les erreurs liées à l'allocation sur le tas, à l'exception de certaines fuites de mémoire...

Comparaison

L'allocation statique est la méthode la plus sûre dans le sens où :
- la quantité consommée est constante et complètement connue avant l'exécution,
- elle est généralement accessible exclusivement en lecture seule (non modifiable). C'est toutefois une méthode très inflexible et insuffisante pour les programmes dont les besoins peuvent varier de façon imprévisible : pour un programme ayant des besoins potentiels de mémoire importants, l'allocation statique conduirait à un gaspillage. Elle est finalement essentiellement utilisée pour stocker des constantes ou des valeurs calculées et disponibles au moment de la compilation. L'allocation sur la pile représente un bon compromis :
- la quantité consommée est proportionnelle aux paramètres d'entrées du programme, qui déterminent la profondeur de la pile et donc la quantité allouée ; elle peut être connue avant l'exécution par une analyse de la complexité algorithmique,
- il n'y a pas de fuite de mémoire, du fait de la libération implicite (respectant la discipline de pile). L'allocation sur la pile doit être choisie en priorité lorsque les besoins mémoires sont connus à l'avance et sont proportionnels à certains paramètres d'entrée du programme. L'allocation et la libération consécutives, selon une discipline de pile, de grosses quantités de mémoire peuvent toutefois poser des problèmes de performance et de lisibilité du source (explosion du nombre de paramètres passés aux fonctions) ; ces problèmes sont à mettre dans la balance contre l'assurance d'une libération correcte des ressources mémoire. L'allocation sur le tas, puisqu'elle permet le contrôle complètement arbitraire de l'allocation et de la libération, offre le plus de possibilités. Les ressources allouées manuellement ont cependant une durée de vie indéfinie, c'est à dire que le programmeur a la responsabilité de la libération (et doit éviter de tomber dans les pièges de la double libération, etc.). La mémoire allouée sur le tas peut également être référencée par des variables globales (de préférence confinées dans un espace de nom), ce qui peut aider à délester un groupe de fonctions de paramètres communs. En pratique, on préfèrera le mode d'allocation le plus simple. La plupart du temps, l'allocation sur la pile est suffisante. On n'utilise l'allocation sur le tas qu'en dernier recours, pour manipuler des structures de données complexes et/ou dont l'évolution ne suit pas la discipline de pile. Dans les langages à ramasse-miettes, le choix du mode d'allocation est réalisé par le compilateur, en fonction d'une analyse des patterns d'utilisation des variables dans le code source. catégorie:développement logiciel

John McCarthy

McCarthy, John McCarthy, John John McCarthy est le principal pionnier de l'intelligence artificielle avec Marvin Minsky, et il incarne le courant mettant l'accent sur la logique symbolique. Il est également l'inventeur en 1958 du langage Lisp. À la fin des années 50, il a créé avec Fernando Cobarto la technique du temps partagé, qui permet à plusieurs utilisateurs d'employer simultanément un même ordinateur.

Lien externe


- [http://www-formal.stanford.edu/jmc/ Page professionelle] ja:ジョン・マッカーシー

Lisp

Catégorie:Langage fonctionnel Catégorie:Intelligence artificielle

Introduction

Lisp est la plus ancienne famille de langages impératifs et fonctionnels. Développé initialement en tant que modèle pratique pour représenter des programmes (par contraste avec la notion théorique de Machine de Turing), il est devenu dans les années 70 et 80 le langage de choix pour la recherche en Intelligence Artificielle. Les langages Lisp sont aujourd'hui utilisés dans de nombreux domaines, de la programmation Web à la finance, et dans les cursus de formation en Informatique. Le terme Lisp a été forgé à partir de l'anglais « list processing ». Tous les dialectes de Lisp partagent les mêmes opérateurs de manipulation de listes chaînées simples. Lisp se distingue en outre par une syntaxe simple en notation préfixée, son typage dynamique des données, le support pour la programmation fonctionnelle, sa gestion automatique de la mémoire et la faculté de manipuler le code source en tant que structure de données. Les langages Lisp sont reconnaissables immédiatement à leur apparence. Le code source des programmes est écrit en utilisant la même syntaxe que celle des listes - la syntaxe parenthésée des s-expressions. Chaque sous-expression d'un programme (ou structure de données) est délimitée par des parenthèses. Cela simplifie grandement l'analyse syntaxique des programmes Lisp et rend simple la Méta-programmation -- la création de programmes qui créent d'autres programmes. Si l'on excepte le langage machine et le langage d'assemblage (ou plus communément « assembleur »), Lisp est le deuxième langage le plus ancien (juste après Fortran) parmi les langages qui se sont largement diffusés. Lisp a beaucoup évolué depuis le début des années 1960 et a ainsi donné naissance à de nombreux dialectes.

Histoire

Le langage Lisp fut inventé par John McCarthy en 1958 alors qu'il était au Massachusetts Institute of Technology. Il publia un article intitulé « Recursive Functions of Symbolic Expressions and Their Computation by Machine, Part I » (soit « Fonctions Récursives d'expressions symboliques et leur évaluation par une Machine, partie I ») dans la revue CACM en 1960 ; la partie II ne fut jamais publiée. Le premier interpréteur fonctionnait sur un ordinateur IBM 704 et deux instructions de cette machine devinrent les deux opérations primitives de Lisp pour décomposer les listes :
- car (Contents of Address register) : le premier élément de la liste
- cdr (Contents of Decrement register) : le reste de la liste Dans son article, John McCarthy introduit deux syntaxes: les S-expressions (expressions symboliques, parfois appelées « sexp ») et les M-expressions (meta expressions, pour exprimer les fonctions manipulant des S-expressions). Les M-expressions n'ont jamais été très appréciées et la plupart des Lisps de nos jours utilisent des S-expressions pour les programmes comme pour les données. C'est la syntaxe des S-expressions qui fait que certains reprochent à Lisp d'être « plein de parenthèses », mais c'est aussi une des sources de la puissance et de la souplesse du langage. Probablement en raison de son expressivité et de sa flexibilité, Lisp eut beaucoup de succès dans la communauté de l'intelligence artificielle. Dans les années 1970, on créa des ordinateurs spécialisés dans l'exécution de programmes Lisp : les machines Lisp. Durant les années 1980 et 1990, on fit de grands efforts pour unifier les nombreux dialectes de Lisp qui étaient apparus. Le résultat fut appelé Common Lisp et en 1994, l'ANSI publia « ANSI X3.226-1994 Information Technology Programming Language Common Lisp », standardisant ainsi le langage. À ce moment, Lisp était bien moins florissant qu'à sa grande époque.

Syntaxe

Les listes sont délimitées par des parenthèses et leurs éléments sont séparés par des espaces : (1 2 « foo »). Un programme Lisp est un arbre de syntaxe composé avec des listes. Cette utilisation des parenthèses donne lieu à une moquerie sur le nom de LISP : « Lots of Irritating and Silly Parentheses ». Lisp est un langage orienté expression : il ne fait pas de distinction entre « expressions » et « statements » (instructions) comme le font de nombreux langage (par exemple Pascal) ; tout est expression et retourne une valeur ou un ensemble de valeurs. La plupart des expressions Lisp sont des applications de fonction. Ce que d'autres langages écrivent
 f(a,b,c) 
Lisp l'écrit
 (f a b c) 
Ainsi une somme ne se note pas
 1+2+3+4 
ni
somme(1,2,3,4)
mais
(+ 1 2 3 4)
On utilise la même notation préfixée pour les « formes spéciales » et les « macros » : le premier élément dans la liste, dans ces cas, détermine comment les éléments suivants seront traités. Une expression peut être une application de fonction, une forme spéciale ou une application de macro suivant la nature du premier élément.

Exemples

Les programmes suivants ne sont pas typiques des vrais programmes Lisp. Ils sont typiques de la présentation que l'on fait de Lisp dans les cours d'informatique. La factorielle est un grand classique :
(defun factorial (n)
  « Calcule la factorielle de l'entier n. »
  (if (<= n 1)
    1
    (
- n (factorial (- n 1)))))
On peut aussi écrire plus efficacement (voir récursion terminale) :
(defun factorial (n &optional (acc 1))
  « Compute the factorial of the integer n. »
  (if (<= n 1)
    acc
    (factorial (- n 1) (
- acc n))))
Un autre exemple typique est cette fonction qui renverse une liste (notez bien que Lisp a une fonction intégrée reverse à cet effet) :
(defun reverse (l &optional (acc '()))
  « renverse la liste l »
  (if (null l)
    acc
    (reverse (cdr l) (cons (car l) acc))))

Lisp et les Objets

Divers systèmes à objets ont été construits à partir de Lisp, notamment :
- Flavors, conçu au MIT
- Le Common Lisp Object System (CLOS), un descendant de Flavors CLOS offre de l'héritage multiple, la sélection multiple et un puissant système de combinaison de méthodes. Common Lisp (dont CLOS fait partie) fut le premier langage orienté-objet standardisé.

Citation

Grégory Chaitin sur Lisp : «Malheureusement, alors que les langages de programmation gagnent en sophistication, ils sont de plus en plus le reflet de la complexité de la société humaine et du monde immense des applications logicielles. Ainsi, ils deviennent d'énormes boîtes à outils, comme des garages et des greniers chargés de plus de trente ans d'histoire ! A contrario, LISP est un langage de programmation d'une grande beauté mathématique ; il ressemble plus à un scalpel de chirurgien ou à diamant affuté qu'à un garage à deux places encombrés de bricolages, où il ne reste plus de place pour une voiture. LISP a un petit nombre de concepts élémentaires puissants, et tout le reste est construit au-dessus de ça, ce qui correspond à la façon de travailler des mathématiciens ; c'est à ça que ressemblent les théories mathématiques. Ces théories, les bonnes théories, consistent à définir quelques nouveaux concepts clefs, et à partir de là le feu d'artifice commence : elles révèlent de nouvelles allées, elles ouvrent la porte à des mondes radicalement nouveaux. LISP est comme ça aussi ; il est plus proches des maths que la plupart des langages de programmation. Du moins si vous éliminez les parties utiles qui ont été ajoutées, les ajouts qui ont fait de LISP un outil pratique. Ce qui reste si vous faites cela, c'est le LISP original, le cœur conceptuel de LISP, un cœur qui est un joyau de beauté mathématique et de beauté intellectuelle austère.» Aujourd'hui, certains diraient que Scheme est le dérivé de Lisp atteignant à la beauté décrite par Chaitin ; et il est certain que Common Lisp, le descendant en ligne droite des grandes cuvées des dialectes passés de LISP (Maclisp, Interlisp, Zetalisp) penche plus du côté de la boîte à outils géante, bien qu'ayant conservé intact son cœur conceptuel. G. Chaitin a utilisé ce Lisp idéalisé pour ses recherches : [http://www.cs.auckland.ac.nz/CDMTCS/chaitin/lisp.html Elegant LISP Programs].

Généalogie et Variantes


- LISP (la version originale de John McCarthy lorsqu'il était au MIT)
- MACLisp (lié au projet MACSYMA du MIT - et sans lien avec l'Apple Macintosh), descendant direct de LISP
- ZetaLisp successeur de MACLisp, il fonctionna sur des machines LISP, descendant direct de MACLisp
- InterLisp, né BBN Lisp, qui servit à développer les premières interfaces utilisateurs graphiques,
- LeLisp, version française du célèbre langage, développée à l'INRIA, et commercialisé ensuite par Ilog
- EuLisp, un « Lisp Européen »
- ELISP (Emacs Lisp), version simplifiée utilisée pour programmer l'éditeur de texte Emacs
- AutoLISP, un LISP utilisé dans AutoCAD pour la programmation.
- Scheme, un LISP simplifié
- Nyquist, un LISP utilisé pour travailler avec des sons.

Liens externes


- [http://www.algo.be/clr.html Lisp : présentation et ressources], en français
- [http://www.cadxp.com/forumXForum-100.htm AutoLisp : forum de discussion], en français ja:LISP ko:리스프

Thread

Les processus légers (en anglais, thread), également appelé fil d'exécution, sont similaires aux processus en cela qu'ils représentent tous deux l'exécution d'un ensemble d'instructions du langage machine d'un processeur. Du point de vue de l'utilisateur ces exécutions semblent se dérouler en parallèle. Toutefois là où chaque processus possède sa propre mémoire virtuelle, les processus légers appartenant au même processus père partagent une même partie de sa mémoire virtuelle.

Utilisation

Comme utilisation typique de processus légers on peut citer une interface graphique d'un programme où les interactions de l'utilisateur avec le processus, par l'intermédiaire des périphériques d'entrée, sont gérées par un processus léger, tandis que les calculs lourds (en terme de temps de calcul) sont gérés par un ou plusieurs autres processus légers. Cette technique de conception de logiciel est avantageuse dans ce cas, car l'utilisateur peut continuer d'interagir avec le programme même lorsque celui-ci sera en train d'exécuter une tâche. Une application pratique se retrouve dans les traitements de texte où la correction orthographique est exécutée tout en permettant à l'utilisateur de continuer à entrer son texte. L'utilisation des processus légers permet donc de rendre l'utilisation d'une application plus fluide, car il n'y a plus de blocage durant les phases de traitements intense.

Processus légers et multitâche

Les processus légers se distinguent du multitâche plus classique par le fait que deux processus sont typiquement indépendants et peuvent interagir uniquement à travers une API fournie par le système telle que IPC. D'un autre côté les processus légers partagent une information sur l'état du processus, des zones de mémoires ainsi que d'autres ressources. Sur certains systèmes la commutation de contexte entre deux processus légers est moins coûteuse que la commutation de contexte entre deux processus. On peut y voir un avantage de la programmation utilisant des threads multiples ou bien une faiblesse des dits système d'exploitation concernant la commutation de contexte entre deux processus.

Avantages et inconvénients

Dans certains cas les programmes utilisant des processus légers sont plus rapides que des programmes architecturés plus classiquement, en particulier sur les machines comportant plusieurs processeurs. Hormis le problème du coût de la commutation de contexte, qui dépend en grande partie du système d'exploitation utilisé, le principal surcoût à l'utilisation de processus multiples provient de la communication entre processus séparés. En effet le partage de certaines ressources entre processus légers permet une communication plus efficace entre les différents thread d'un processus. Là où deux processus séparés doivent utiliser un mécanisme fourni par le système pour communiquer, les processus légers partagent tout ou partie de l'état du processus. D'un autre côté la programmation utilisant des processus légers est plus difficile, l'accès à certaines ressources partagées doit être restreint par le programme lui-même, pour éviter que tout ou partie de l'état d'un processus ne devienne temporairement inconsistant, tandis qu'un autre processus léger va avoir besoin de consulter cette portion de l'état du processus. Il est donc obligatoire de mettre en place des mécanismes de synchronisation (à l'aide de sémaphore par exemple). La complexité des programmes utilisant des processus légers est aussi nettement plus grande que celle des programmes déférant le travail à faire à plusieurs processus plus simples. Cette complexité accrue, lorsqu'elle est mal gérée lors de la phase de conception ou d'implémentation d'un programme, peut conduire à de multiples problèmes.

Support des processus légers

Les systèmes d'exploitation implémentent généralement les processus légers soit par le multitâche coopératif, soit par le multitâche préemptif, bien que la première méthode soit de plus en plus souvent considérée comme obsolète. Certains langages de programmation, tel que Java intègrent un support pour les processus légers dans le langage, tandis que la plupart des autres langages ne le permettent que par des extensions du langage considéré ou par l'intermédiaire de bibliothèques. En programmation orientée objet on parle de classe réentrante lorsque des instances distinctes de cette classe peuvent exister simultanément dans différents processus légers.

Confusion possible

Il ne faut pas confondre la technologie Hyperthreading incluse dans certains processeurs Intel avec les processus légers. Cette technologie permet en effet aussi bien l'exécution simultanée de processus distincts que de processus légers. Toute machine comportant des processeurs multiples (SMP) ou des processeurs intégrant l'HyperThreading permettra l'exécution plus rapide de programmes utilisant des processus légers aussi bien que des processus multiples.

Lien externe


- [http://www.labo-linux.org/index.php?page=articles&id=15 La programmation multitâches et communication inter-processus] Catégorie:Système d'exploitation Catégorie:Programmation concurrente ko:스레드 ja:スレッド (コンピュータプログラミング)

Common Lisp

ko:커먼 리스프 Common Lisp est un langage fonctionnel impur de la famille Lisp.

Citation

« Common Lisp, la force d'une boule de glaise, est le patriarche bien vivant de la famille Lisp. L'Ingénieur lui a donné forme, et non le Chercheur en quête de clarté conceptuelle. Mais en dépit de son applicabilité pratique, CL offre des plaisirs hélas inconnus de la programmation mainstream. » [http://www.schnada.de/hylin/tao.html Le Tao de la Récursion]

Introduction

Common Lisp est un dialecte de Lisp standardisé par l'ANSI X3.226-1994. Développé pour standardiser les variantes divergentes de Lisp qui l'ont précédé, ce n'est pas une implémentation mais une spécification à laquelle les implémentations Lisp essayent de se conformer. Il est fréquemment abrégé en CL. Common Lisp est un langage de programmation à usage général, a contrario de dialectes de Lisp comme Emacs Lisp et AutoLisp, qui sont des langages d'extension embarqués dans des produits particuliers. Contrairement à de nombreux Lisp plus anciens, mais comme Scheme, Common Lisp utilise la portée lexicale par défaut pour les variables. Common Lisp est un langage de programmation multi-paradigmes qui :
- Accepte des techniques de programmation impérative, fonctionnelle et orientée objet (CLOS).
- Est typé dynamiquement, mais avec des déclarations de type optionnelles qui peuvent améliorer l'efficacité et la sûreté,
- Dispose d'un système de gestion d'exceptions puissant, nommé Condition System (système de gestion de conditions),
- Est syntaxiquement extensible à travers des fonctionalités comme les macros et les macro de lecture.

Syntaxe

Common Lisp est un Lisp ; il utilise des s-expressions pour dénoter à la fois le code et les structures de données. Les appels de fonction et de macros sont écrits en tant que listes, avec le nom de la fonction en première place, comme dans ces exemples : (+ 2 2) ; ajoute 2 et 2, renvoie 4 (setf e 2.7182817) ; assigne 2.7182817 à la variable e (defun carre (x) (
- x x)) ; définit une fonction qui met un nombre au carré (carre 3) ; exécution de la fonction : retourne 9

Types de données

Common Lisp a une pléthore de types de données, plus qu'aucun autre langage.

Types scalaires

Nombres

Les types numériques incluent les entiers, les rationnels, les nombres à virgule flottante et les nombres complexes. Common Lisp utilise des Grands Nombres (en: bignums) pour représenter des valeurs numériques de taille et de précision arbitraires. Le type rationnel représente les fractions de façon exacte, une facilité absente de la plupart des langages. Common Lisp convertit automatiquement les valeurs numériques entre ces types de façon apropriée. Voici la tour numérique, c'est à dire la hiérarchie des types numériques de Common Lisp : complex ratio fixnum / / / number <--+-real--+-rational--+-integer--+-bignum \ \ \ (1) signed-byte---unsigned-byte---bit \ float--+-short-float \-single-float \-double-float \-long-float (1) integer et signed-byte sont des spécifications de types disjointes ; toutefois, les domaines sont identiques. A titre d'exemple, l'expression (+ (sqrt -2) (/ 6 4)) retourne #C(3/2 1.4142135) c'est à dire un nombre complexe dont la partie imaginaire est le flottant 1.4142135 et la partie réelle est le rationel 3/2.

Caractères

Le type Common Lisp caractère n'est pas limité aux caractères ASCII ; cela n'est pas surprenant car Lisp est plus ancien que l'ASCII. Certaines implémentations modernes supportent les caractères Unicode. [http://www.cliki.net/Unicode%20Support]

Symboles

Le type symbole est commun aux langages Lisp, mais largement inconnu en-dehors. Un symbole est un objet nommé, unique. Les symboles en Lisp sont similaires aux identifieurs de variables dans d'autres langages, en ce qu'ils peuvent être utilisés comme variables pour stocker des valeurs ; toutefois, ils sont plus généraux et peuvent être utilisés pour eux-mêmes également. Normalement, lorsqu'un symbole est évalué, sa valeur en tant que variable est retournée. Il existe des exceptions à ces règles, qui sont les mots-clefs (comme :foo ou :bar), et les valeurs booléennes qui sont représentées par les symboles réservés T et NIL. Exemples : foo ;; -> La variable FOO n'a pas de valeur. (function foo) ;; -> La fonction FOO n'est pas définie. L'opérateur QUOTE protège les symboles de l'évaluation (lorsqu'on veut utiliser un symbole pour lui-même) : (quote foo) ;; -> FOO 'foo ;; -> FOO On peut demander si un symbole est lié à une valeur ou une fonction : (boundp 'foo) ;; -> NIL (pas de valeur liée) (fboundp 'foo) ;; -> NIL (aucune fonction nommée FOO n'existe) Association symbole-valeur : (defparameter foo 77) ;; -> FOO foo ;; -> 77 Association symbole-fonction : (defun foo (bar) (1+ bar)) ;; -> FOO Appel de la fonction FOO avec la valeur FOO (illustre le fait qu'un symbole dispose de slots séparés pour les valeurs et les fonctions) : (foo foo) ;; -> 78 (boundp 'foo) ;; -> T (fboundp 'foo) ;; -> T (function foo) ;; -> #

Structures de données

Séquences

Les séquences sont un type abstrait représentant une collection ordonnée d'éléments. Les types concrets dérivés de séquence sont les listes et les vecteurs (y compris les vecteurs de bits et chaînes de caractères). De nombreuses fonctions sont disponibles pour les séquences.

Paires, Listes

Comme dans tout autre Lisp, les listes en Common Lisp sont composées de conses (pluriel), parfois appelés cellules cons ou paires. Un cons est une structure de données de deux éléments de type T, appelés son car et son cdr. Une liste est une chaîne de conses liés, où le cdr de chaque cons pointe sur l'élément suivant, et le dernier cdr pointe sur la valeur NIL. Les conses peuvent être facilement utilisés pour implémenter des arbres ou toute structures de données complexe ; bien que dans ce dernier cas il soit recommandé d'utiliser des structures ou des classes. L'arbre (1 (2/7 3.14) A "foo") est représenté par la chaîne de CONS suivante : 300px Il peut être construit de différentes façons, nous en citons deux : (list 1 (list 2/7 3.14) 'a "foo") (cons 1 (cons (cons 2/7 (cons 3.14 NIL)) (cons 'a (cons "foo" NIL))))

Tableaux

Common Lisp supporte les tableaux de dimensions arbitraires, et peut aussi redimensionner dynamiquement les tableaux. Des tableaux multidimensionnels peuvent être utilisés pour les mathématiques des matrices. Seuls les tableaux à une dimension (nommés vecteurs) sont un sous-type de séquence. Les tableaux peuvent être spécialisés par le type des éléments qu'ils contiennent. En particulier, les vecteurs de bits et les vecteurs de caractères (chaînes) sont fournis en standard par le langage. Exemple de création d'un tableau à trois dimensions (4 x 2 x 3) et initialisé : (make-array '(4 2 3) :initial-contents '(((a b c) (1 2 3)) ((d e f) (3 1 2)) ((g h i) (2 3 1)) ((j k l) (0 0 0)))) ... cela retourne : #3A(((A B C) (1 2 3)) ((D E F) (3 1 2)) ((G H I) (2 3 1)) ((J K L) (0 0 0)))

Tables de hachage

Les Tables de hachage stockent des associations entre objets. N'importe quel type d'objet peut être utilisé comme clef ou valeur. Les tables de hachage, comme les tableaux, sont automatiquement redimensionnées si nécessaire.

Paquetages

Les paquetages (packages) sont des collections de symboles, utilisés principalement pour partitionner un programme en espaces de noms. Un paquetage peut exporter certains symboles, les marquant comme une partie d'une interface publique. Les variables et méthodes dites privées des langages à objets classiques (principe de l'encapsulation) sont obtenues en Lisp en les déclarant dans un espace de nom, sans les exporter.

Structures

Les Structures, similaires au structs du C et aux records (enregistrements) du Pascal, représentent des structures de données de complexité arbitraire, avec un nombre quelconque et tout type de champs (appelés slots). Les structures supportent une forme limitée d'héritage. Pour les besoins de la programmation orientée objet, on se reportera à CLOS.

Classes et Objets

Common Lisp a été le premier langage à objets standardisé (en 1995, par l'ANSI). La partie du langage traitant des objets se nomme CLOS pour Common Lisp Object System. CLOS est généralement considéré comme le système à objets le plus général et le plus complet, en ce sens que les autres langages à objets peuvent être décrits dans les termes de CLOS, mais pas l'inverse. Les caractéristiques saillantes de CLOS sont les suivantes :
- c'est un système à classes (il existe en effet des systèmes à prototypes)
- les classes elles-mêmes sont des objets, ou instances de méta-classes (des classes de classes)
- il dispose d'un protocole à méta-objets (ou MOP pour Meta Object Protocol), lié à l'existence des méta-classes, et permettant de modifier la sémantique et le comportement du système,
- il permet l'héritage multiple entre classes,
- il offre la sélection multiple des méthodes, c’est-à-dire la sélection à l'exécution d'une méthode en fonction du type du tuple de ses paramètres obligatoires (et non pas d'un receveur privilégié comme dans les langages à sélection simple, qui sont la très grande majorité)
- il permet la combinaison de méthodes, c’est-à-dire la définition de méthodes auxiliaires s'exécutant avant et/ou après une méthode particulière. CLOS permet également de définir des méta-classes et des classes, de changer la classe d'un objet, à l'exécution. Le système de conditions de Common Lisp utilise CLOS pour définir les types des conditions pouvant survenir à l'exécution.

Fonctions et fermetures lexicales

Fonctions

En Common Lisp, les fonctions sont un type de donnée. Par exemple,