Lisp, abréviation de "LISt Processing", est une famille de langages de programmation qui partagent une syntaxe distinctive basée sur des parenthèses, principalement centrée sur la manipulation de symboles et de listes. C'est l'un des langages de programmation de haut niveau les plus anciens, inventé à la fin des années 1950, et il a évolué de manière significative au fil des décennies. Lisp est particulièrement connu pour ses fonctionnalités puissantes telles que le typage dynamique, la collecte des ordures et les fonctions de première classe, ce qui le rend adapté à la recherche en IA, au calcul symbolique et au prototypage rapide.
Lisp a été créé par John McCarthy en 1958 comme une notation mathématique pour les programmes informatiques et comme un moyen pratique de mettre en œuvre l'IA. Le langage a été dérivé du calcul des lambda, un système formel en logique mathématique et en informatique. La première implémentation a été réalisée sur l'IBM 704, et peu après, de nombreux dialectes ont émergé, chacun ajoutant ses propres fonctionnalités et complexités.
Plusieurs dialectes notables de Lisp ont émergé au fil du temps, notamment Common Lisp et Scheme. Common Lisp a été standardisé dans les années 1980 pour unifier divers dialectes, tandis que Scheme, qui met l'accent sur la programmation fonctionnelle et le minimalisme, a gagné en popularité dans le milieu académique. Les influences de Lisp peuvent être observées dans de nombreux langages de programmation modernes, en particulier ceux qui supportent des paradigmes de programmation fonctionnelle, tels que Clojure, Racket, et même des langages comme Python et Ruby.
Aujourd'hui, Lisp n'est pas parmi les langages de programmation les plus populaires, mais il reste influent, notamment dans la recherche, l'IA et l'éducation. La communauté développe activement de nouveaux dialectes comme Clojure, qui s'exécute sur la Java Virtual Machine (JVM) et se concentre sur la programmation concurrente.
Lisp utilise une syntaxe unique avec des parenthèses pour désigner des expressions, le code étant représenté sous forme d'expressions symboliques (S-expressions). Par exemple :
(+ 1 2)
Cette expression représente l'addition de 1 et 2.
Les fonctions en Lisp peuvent être passées comme arguments, retournées par d'autres fonctions et assignées à des variables :
(defun square (x) (* x x))
(mapcar #'square '(1 2 3 4)) ; retourne (1 4 9 16)
Lisp est dynamiquement typé, permettant aux variables de contenir des valeurs de n'importe quel type de données sans déclaration préalable :
(setq x 10) ; x est maintenant un nombre
(setq x "hello") ; x est maintenant une chaîne
Lisp dispose de puissants systèmes de macros qui permettent aux développeurs de créer des constructions syntaxiques personnalisées :
(defmacro when (condition &body body)
`(if ,condition
(progn ,@body))
)
Les formes if
et cond
facilitent le contrôle de flux en Lisp :
(if (> x 0)
(print "Positif")
(print "Non positif"))
Lisp traite les listes comme des structures de données fondamentales :
(setq my-list '(1 2 3 4))
(car my-list) ; retourne 1
(cdr my-list) ; retourne (2 3 4)
Les fonctions sont définies à l'aide de la construction defun
:
(defun factorial (n)
(if (= n 0)
1
(* n (factorial (- n 1)))))
Common Lisp inclut un système orienté objet connu sous le nom de Common Lisp Object System (CLOS) :
(defclass person ()
((name :initarg :name :accessor person-name)
(age :initarg :age :accessor person-age)))
(defmethod say-hello ((p person))
(format t "Bonjour, je m'appelle ~A et j'ai ~A ans."
(person-name p) (person-age p)))
Lisp fournit un mécanisme sophistiqué de gestion des erreurs utilisant handler-case
:
(handler-case
(/ 1 0)
(division-by-zero () (print "Erreur : division par zéro !")))
Les continuations sont supportées dans certains dialectes, permettant au programme de sauvegarder et de restaurer des états d'exécution :
(call-with-current-continuation
(lambda (k)
(k 10)))
Plusieurs environnements de développement intégrés (IDE) et compilateurs sont dédiés à la programmation Lisp. Les choix populaires incluent :
Pour construire un projet Lisp, vous créez généralement un fichier avec une extension ".lisp" ou ".lsp". En utilisant SBCL, un flux de travail typique peut impliquer le chargement de votre projet depuis le REPL :
(load "my-project.lisp")
Pour les projets utilisant Quicklisp, un gestionnaire de bibliothèques, les dépendances peuvent être facilement gérées et chargées.
Lisp est particulièrement connu pour ses applications en intelligence artificielle, en calcul symbolique et dans le milieu académique, mais il trouve également des usages dans :
Lisp est souvent comparé à :
La traduction de Lisp vers d'autres langages se fait souvent à l'aide d'outils de traduction source-à-source. Par exemple, les outils suivants existent :
Chacun de ces outils fournit des correspondances spécifiques garantissant que les fonctionnalités de base de Lisp peuvent être efficacement représentées dans les langages cibles. Pour des traductions plus complexes, un refactoring manuel peut être nécessaire, en particulier pour le code fortement optimisé par des macros.