Pourquoi Clojure a-t-il des «mots-clés» en plus des «symboles»?

J’ai une connaissance passagère des autres Lisps (particulièrement Scheme) depuis le début. Récemment, j’ai lu sur Clojure . Je vois qu’il a à la fois des “symboles” et des “mots-clés”. Symboles que je connais, mais pas avec des mots-clés.

Est-ce que d’autres Lisps ont des mots-clés? Comment les mots-clés sont-ils différents des symboles autres que ceux ayant une notation différente (par exemple: les deux-points)?

Voici la documentation de Clojure pour les mots-clés et les symboles.

Les mots-clés sont des identifiants symboliques qui se évaluent. Ils fournissent des tests d’égalité très rapides …

Les symboles sont des identifiants normalement utilisés pour faire référence à autre chose. Ils peuvent être utilisés dans des formulaires de programme pour faire référence à des parameters de fonction, laisser des liaisons, des noms de classe et des vars globaux …

Les mots-clés sont généralement utilisés comme des “chaînes constantes” légères, par exemple pour les clés d’un hachage ou les valeurs d’expédition d’une méthode multiple. Les symboles sont généralement utilisés pour nommer les variables et les fonctions et il est moins courant de les manipuler en tant qu’objects directement, sauf dans les macros et autres. Mais rien ne vous empêche d’utiliser un symbole partout où vous utilisez un mot-clé (si cela ne vous dérange pas de les citer tout le temps).

La façon la plus simple de voir la différence est de lire Keyword.java et Symbol.java dans la source Clojure. Il existe quelques différences de mise en œuvre évidentes. Par exemple, un symbole dans Clojure peut avoir des métadonnées et un mot-clé ne peut pas.

Outre la syntaxe à un seul point, vous pouvez utiliser un double-point pour créer un mot-clé qualifié par un espace de noms.

 user> :foo :foo user> ::foo :user/foo 

Common Lisp a des mots-clés, tout comme Ruby et d’autres langages. Ils sont légèrement différents dans ces langues bien sûr. Quelques différences entre les mots-clés Common Lisp et les mots-clés Clojure:

  1. Les mots-clés dans Clojure ne sont pas des symboles.

     user> (symbol? :foo) false 
  2. Les mots-clés n’appartiennent à aucun espace de noms sauf si vous les qualifiez spécifiquement:

     user> (namespace :foo) nil user> (namespace ::foo) "user" 

(Merci Rainer Joswig de m’avoir donné des idées de choses à regarder.)

Common Lisp a des symboles de mots-clés.

Les mots-clés sont aussi des symboles.

 (symbolp ':foo) -> T 

Qu’est-ce qui rend les mots-clés spéciaux:

  • : foo est analysé par le lecteur Common Lisp en tant que mot-clé symbol :: foo
  • les mots-clés se évaluent eux-mêmes:: foo ->: foo
  • le package de base des symboles de mots-clés est le package KEYWORD: mot-clé: foo ->: foo
  • les mots clés sont exportés à partir du package KEYWORD
  • les mots-clés sont des constantes, il n’est pas permis d’atsortingbuer une valeur différente

Sinon, les mots-clés sont des symboles ordinaires. Les mots-clés peuvent donc nommer des fonctions ou avoir des listes de propriétés.

Rappelez-vous: dans Common Lisp, les symboles appartiennent à un paquet. Cela peut être écrit comme:

  • foo, quand le symbole est accessible dans le paquet en cours
  • foo: bar, quand le symbole FOO est exporté du paquet BAR
  • foo :: bar, quand le symbole FOO est dans le paquet BAR

Pour les symboles de mots-clés, cela signifie que: foo, keyword: foo et keyword :: foo sont tous du même symbole. Ainsi, les deux dernières notations ne sont généralement pas utilisées.

Donc: foo est juste analysé pour être dans le package KEYWORD, en supposant que donner aucun nom de package avant le nom du symbole signifie par défaut le package KEYWORD.

Les mots-clés sont des symboles qui s’auto-évaluent, vous n’avez donc pas à vous souvenir de les citer.

Pour les mots-clés, les valeurs de hachage sont calculées et mises en cache lors de la création du mot-clé. Lorsque vous recherchez un mot clé en tant que clé de hachage, il renvoie simplement la valeur hachée précalculée. Pour les chaînes et les symboles, le hachage est recalculé à chaque recherche.

La raison pour laquelle les mêmes mots-clés nommés sont toujours identiques, ils contiennent leurs propres valeurs de hachage. Comme la recherche dans les cartes et les ensembles est faite à partir de clés de hachage, cela permet une meilleure efficacité de recherche en cas de nombreuses recherches, et non dans la recherche elle-même.

: les mots-clés sont également traités spécialement par de nombreuses collections, permettant une syntaxe très pratique.

 (:user-id (get-users-map)) 

est le même que

 ((get-users-map) :user-id) 

cela rend les choses un peu plus flexibles