Page d'accueil encyclopedie-enligne.com en page d'accueil
Liste Articles: [0-A] [A-C] [C-F] [F-J] [J-M] [M-P] [P-S] [S-Z] | Liste Catégories | Une page au hasard | Pages liées

Common Lisp



image:Langage_progr.png
Cet article fait partie de
la série Langages de programmation
Langages orientés objet
Ada 95 - C++ - C#
Common lisp object system
Delphi - Eiffel - Java - Nice
Langages impératifs
APL - ASP
Assembleur
BASIC - C - Pascal
Perl - PHP - Python
Langages fonctionnels
ML/OCaml - Lisp/Common Lisp
Forth - Logo - Scheme
Langages déclaratifs
Clips - Prolog
Voir aussi
Conception - Codage
Tests - Optimisations


Sommaire

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 plutôt une spécification à laquelle la plupart des implémentations Lisp se conforment. Il est fréquement 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 pour les variables.

Common Lisp est un langage de programmation multi-paradigmes qui :

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 pi 3.1415) ; value la variable « pi » à 3.1415

; Définit une fonction qui met un nombre au carré

(defun carre (x) (* x x))

; Exécution de la fonction

(carre 3) ; 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.

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. [1]

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 y a des exceptions, 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.

Structures de données

Séquences

Les séquences sont un type abstrait sur lequel un ensemble d'opérations (parcours, ajouts et retrait d'élément, etc.) est défini. Les types concrets dérivés de séquence incluent les listes, tableaux, vecteurs (et vecteurs de bits, chaînes).

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, appelés sont 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.

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.

Tables de hachage

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

Packages

Les Packages (paquets) sont des collections de symboles, utilisés principalement pour partitionner les parties d'un programme en espaces de noms. Un paquet peut exporter certains symboles, les marquant comme une partie d'une interface publique.

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.

Fonctions et fermetures lexicales

Fonctions

En Common Lisp, les fonctions sont un type de donnée. Par exemple, il est possible d'écrire des fonctions qui prennent d'autres fonctions en argument, et retournent des fonctions (on les nomme fonctions d'ordre supérieur, ou de première classe). Cela rend possible d'écrire des opérateurs très généraux.

Exemple

Par exemple, la fonction sort (tri) prend un opérateur de comparaison en argument. Elle peut être utilisée non seulement pour trier n'importe quel type de données, mais également pour trier des structures de données selon une clef.

(sort (list 5 2 6 3 1 4) #'>)

Retourne (6 5 4 3 2 1), en utilisant la fonction > comme opérateur de comparaison

(sort `((9 a) (3 b) (4 c)) #'(lambda (x y) (< (car x) (car y))))

Retourne ((3 b) (4 c) (9 a)), i.e. la liste triée sur le premier élément

Espaces de noms

Common Lisp est a un espace de nom respectivement pour les fonctions et pour les variables (à la différence de, par exemple, Scheme, qui est dit "Lisp-1"). Lisp-2 (ou plus) présente l'avantage qu'aucun nom de variable ne peut masquer un nom de fonction : on peut nommer une variable cons ou même if sans problème. Toutefois, pour faire référence à une fonction en tant que variable, on doit utiliser la fonction (function ...) ou la notation équivalente #' comme dans les exemples ci-dessus.

Outre les fonctions et les variables, il y a un espace de noms distinct pour les couples d'opérateurs block/return-from et tagbody/go.

Ajoutons pour finir que l'espace de nom des fonctions est en réalité partagé entre les fonctions proprement dites et les différentes sortes de macro.

Evaluation

Le modèle d'évaluation est simple : lorsque l'évaluateur rencontre une expression (F A1 A2 ... An), le symbole F peut représenter l'un de ces items :

  1. Un opérateur spécial (comme if)
  2. Une macro
  3. Une fonction, c’est-à-dire le nom d'une fonction définie par (defun ...) ou une fonction anonyme, toujours dénotée par (lambda ...)

Si F est une fonction, les paramètres sont évalués successivement de droite à gauche et la fonction est invoquée avec les valeurs calculées des paramètres.

Capture lexicale

Une fermeture lexicale est une fonction dont les variables libres capturent les liaisons de l'environnement lexical dans lequel elles sont définie. Cela permet de construire des fonctions ayant un état interne (en C on utiliserait le mot-clef static pour obtenir l'état interne, mais la capture lexicale n'est pas possible). On peut construire des objets simples à partir de fermetures, par exemple une fabrique de compteurs :

(defun fabriquer-compteur () ; fabriquer-compteur renvoie une fonction qui incrémente et affiche sa valeur interne
 (let ((valeur 0)) ; dans l'environnement de la fabrique, on crée la valeur du compteur
 (lambda () ; le nouveau compteur lui-même
 (incf valeur) ; ici, la référence à "valeur" capture sa définition dans la fabrique
 valeur)))

Autres types

Les autres types de données de Common Lisp comprennent :

Common Lisp incorpore également une boîte à outils pour la programmation orientée objet, le Common Lisp Object System, ou CLOS. Il est donc possible d'ajouter une infinité de types.

Macros

Une macro en Lisp ressemble superficiellement à une fonction. Toutefois, plutôt que de représenter une fonction qui est évaluée, elle représente une transformation du texte du programme contenu dans l'appel à la macro.

Les macros permettent au programmeur Lisp de créer de nouvelles formes syntaxiques dans le langage. Par exemple, cette macro fournit la forme de boucle until (boucler... jusqu'à), qui est familière dans un langage comme Perl :

(defmacro until (test &rest body)
 `(do ()
 (,test)
 ,@body))

Exemple :

(until (= (random 10) 0) 
 (write-line "Hello"))

Les macros ne sont pas évaluées à l'exécution comme les fonctions. On parle de macro-expansion, qui a lieu au moment de la compilation du code source. On peut toutefois les considérer comme des fonctions qui acceptent et retournent des arbres de syntaxe abstraits (les s-expressions), mais contrôlent l'évaluation de leurs paramètres. Comme les fonctions, elles peuvent utiliser l'ensemble du langage Common Lisp (et bibliothèques tierces) pour effectuer leur travail de transformation, contrairement aux macros du langage C qui ne permettent que des substitutions de chaînes de caractères au niveau du source, sans accès à l'ensemble du langage C lui-même.

Capture de variable

Les macros Common Lisp sont capables de capture de variable, une situation où des symboles situés dans le corps de la macro-expansion coincident avec des symboles du contexte apelant. Pour cette raison elles sont parfois apelées macro « non hygiéniques », par comparaison avec le système de « macro hygiéniques » de Scheme, qui garantit la séparation entre ces ensembles de symboles.

La capture de variable est parfois un effet désiré ; lorsque ce n'est pas le cas, elle doit être évité par l'emploi de gensyms, ou symboles dont l'unicité est garantie.

Implémentations

Common Lisp est défini par une spécification (comme Ada et C) plutôt que par une seule implémentation (comme Perl ou Python). Il y a de nombreuses implémentations, et le standard décrit les points sur lesquels elles peuvent être divergentes pour de bonnes raisons.

De plus, les implémentations sont généralement fournies avec différents ensembles de « paquets » de bibliothèques, qui fournissent des fonctionnalités non couvertes par le standard. Certaines de ces fonctionnalités ont été introduites par la suite dans le standard, comme CLOS et la forme LOOP ; d'autres restent propres à ces implémentations. De nombreuses commodités pour le programmeur moderne -- comme l'accès aux réseaux TCP/IP -- restent hors du standard, mais sont fournies par les différentes implémentations avec parfois des différences mineures. Un processus nommé CLRFI (Common Lisp Request For Improvement), similaire aux SRFI de Scheme, a pour objectif de faire converger les fonctionalités utiles laissées hors du standard ANSI de 1995.

Selon une erreur répandue, les implémentations de Common Lisp sont toutes des interpréteurs. En fait, la compilation fait partie de la spécification du langage. La plupart des implémentations de Common Lisp compilent les fonctions vers du code machine. D'autres compilent vers du code objet, ce qui réduit la vitesse mais améliore la portabilité.

Certaines implémentations en environnement UNIX, comme CLISP, peuvent être utilisées comme des interpréteurs de scripts (ou même comme shell).


Liste des implémentations

Les implémentations librement redistribuables incluent :

Il y a également des implémentations commerciales disponibles chez Franz, Xanalys, Digitool, Corman and Scieneer.

Liens externes

Bibliographie en ligne

Voir aussi



This site support the Wikimedia Foundation. This Article originally from Wikipedia. All text is available under the terms of the GNU Free Documentation License Page HistoryOriginal ArticleWikipedia