Question

Scheme utilise un seul espace de noms pour toutes les variables, qu'elles soient liées à des fonctions ou à d'autres types de valeurs. Common Lisp sépare les deux, de sorte que l'identificateur "hello". peut faire référence à une fonction dans un contexte et à une chaîne dans un autre.

(Remarque 1: Cette question nécessite un exemple de ce qui précède; n'hésitez pas à la modifier et à en ajouter un, ou à envoyer un e-mail à l'auteur original et je le ferai.)

Cependant, dans certains contextes, tels que le transfert de fonctions en tant que paramètres à d'autres fonctions, le programmeur doit explicitement distinguer qu'il spécifie une variable de fonction plutôt qu'une variable non-fonction, en utilisant # ' , comme dans:

(sort (list '(9 A) '(3 B) '(4 C)) #'< :key #'first)

J’ai toujours considéré cela comme une verrue, mais j’ai récemment rencontré un argument indiquant qu'il s'agit en fait d'une fonctionnalité:

...le distinction importante réside en réalité dans la syntaxe des formes, pas dans la type d'objets. Sans rien connaître des valeurs d'exécution impliqué, il est clair que le premier élément d’une forme de fonction doit être une fonction. CL prend ce fait et en fait une partie de la langue, ainsi que des formes macro et spéciales qui peuvent aussi (et doivent) être déterminé statiquement. Donc ma question est: pourquoi voudriez-vous le les noms des fonctions et les noms des variables doivent être dans le même espace de noms, lorsque l’utilisation principale des noms de fonction doit apparaître nom de variable voudrait rarement apparaître?
Prenons le cas des noms de classe: pourquoi une classe nommée FOO devrait-elle empêcher l'utilisation de variables nommées FOO? La seule fois où je parlerais de la classe par le nom FOO est dans des contextes qui attendent un nom de classe. Si, sur les rares occasions dont j'ai besoin pour obtenir l'objet de classe qui est lié à la nom de classe FOO, il y a FIND-CLASS.

Cet argument me semble logique par expérience; Il existe un cas similaire dans Haskell avec des noms de champs, qui sont également des fonctions permettant d’accéder aux champs. C'est un peu gênant:

data Point = Point { x, y :: Double {- lots of other fields as well --} }
isOrigin p = (x p == 0) && (y p == 0)

Ceci est résolu par un peu de syntaxe supplémentaire, rendue particulièrement agréable par l'extension NamedFieldPuns :

isOrigin2 Point{x,y} = (x == 0) && (y == 0)

Alors, à la question, au-delà de la cohérence, quels sont les avantages et les inconvénients, à la fois pour Common Lisp vs. Scheme et en général, d’un seul espace de noms pour toutes les valeurs par rapport à des espaces distincts pour les fonctions et les valeurs non-fonctions?

Était-ce utile?

La solution

Les deux approches différentes ont des noms: Lisp-1 et Lisp-2. Un Lisp-1 a un seul espace de noms pour les variables et les fonctions (comme dans Scheme), tandis qu'un Lisp-2 a des espaces de nom distincts pour les variables et les fonctions (comme dans Common Lisp). Je le mentionne parce que vous n'êtes peut-être pas au courant de la terminologie puisque vous ne l'avez pas mentionnée dans votre question.

Wikipedia fait référence à ce débat :

  

Le fait qu'un espace de noms séparé pour les fonctions soit un avantage constitue une source de conflit dans la communauté Lisp. On parle généralement du débat Lisp-1 contre Lisp-2. Lisp-1 se réfère au modèle de Scheme et Lisp-2 se réfère au modèle de Common Lisp. Ces noms ont été inventés dans un article de 1988 de Richard P. Gabriel et Kent Pitman, qui compare minutieusement les deux approches.

L'article de Gabriel et Pitman intitulé Problèmes techniques liés à la séparation dans les cellules fonctionnelles et les cellules de valeur résout ce problème.

Autres conseils

En fait, comme indiqué dans le article de Richard Gabriel et Kent Pitman , le débat porte sur Lisp-5 contre Lisp-6, étant donné qu'il existe déjà plusieurs autres espaces de noms, les noms de types, les noms de balises, les noms de blocs et les noms de déclaration sont mentionnés dans le document. edit: cela semble être incorrect, comme le souligne Rainer dans le commentaire: Scheme semble en réalité être un Lisp-1. Cette erreur n’affecte toutefois guère ce qui suit.

Si un symbole indique quelque chose à exécuter ou à quoi faire référence, cela ressort toujours du contexte. Lancer des fonctions et des variables dans le même espace de noms est avant tout une restriction: le programmeur ne peut pas utiliser le même nom pour une chose et une action. Ce que Lisp-5 en retire, c'est simplement que l'on évite une surcharge syntaxique pour faire référence à quelque chose provenant d'un espace de noms différent de ce que le contexte actuel implique. modifier: il ne s'agit pas de la totalité de l'image, mais uniquement de la surface.

Je sais que les promoteurs de Lisp-5 aiment le fait que les fonctions sont des données et que cela s'exprime dans le noyau du langage. J'aime le fait que je puisse appeler une liste " liste " et une voiture " voiture " sans confondre mon compilateur, et les fonctions sont de toute façon un type de données fondamentalement spécial. edit: c’est mon point principal: les espaces de noms séparés ne sont pas du tout une verrue.

J'ai aussi aimé ce que Pascal Constanza devait faire dites à ce sujet.

J'ai rencontré une distinction similaire dans Python (espace de nom unifié) vs Ruby (espaces de nom distincts pour les méthodes vs non-méthodes). Dans ce contexte, je préfère l'approche de Python - par exemple, avec cette approche, si je veux faire une liste de choses, dont certaines sont des fonctions alors que d'autres ne le sont pas, je n'ai rien de différent à faire avec leurs noms. , en fonction de leur "fonctionnalité", par exemple. Des considérations similaires s'appliquent à tous les cas dans lesquels les objets de fonction doivent être regroupés plutôt qu'appelés (arguments et fonctions renvoyant des fonctions d'ordre supérieur, etc., etc.).

Les non-fonctions peuvent également être appelées (si leurs classes définissent __ call __ , dans le cas de Python - un cas particulier de "surcharge d'opérateur"), de sorte que la "distinction contextuelle" n'est pas nécessairement clair non plus.

Cependant, mon " lisp-oid " L’expérience est / était principalement liée à Scheme plutôt qu’à Common Lisp. Il est donc possible que je sois inconsciemment influencé par la familiarité avec l’espace de nommage uniforme qui découle de cette expérience.

Le nom d'une fonction dans Scheme est simplement une variable dont la fonction est la valeur. Que je fasse (définir x (y) (zy)) ou (let ((x (lambda (y) (zy)))) , je définis un Ainsi, l'idée selon laquelle "un nom de variable voudrait rarement apparaître ici" est un peu spécieuse en ce qui concerne Scheme.

Scheme est un langage fonctionnellement caractéristique, donc traiter les fonctions comme des données est l’un de ses principes. Faire en sorte que les fonctions soient un type à part, stocké comme toutes les autres données, est un moyen de poursuivre l’idée.

Le plus gros inconvénient que je constate, du moins pour Common Lisp, est la compréhensibilité. Nous pouvons tous convenir qu'il utilise différents espaces de noms pour les variables et les fonctions, mais combien en a-t-il? Dans PAIP, Norvig a montré qu’il avait "au moins sept". espaces de noms.

Lorsqu'un des livres classiques de la langue, écrit par un programmeur très respecté, ne peut même pas dire avec certitude dans un livre publié, je pense qu'il y a un problème. Je n'ai pas de problème avec plusieurs espaces de noms, mais j'aimerais que la langue soit, au moins, assez simple pour que quelqu'un puisse comprendre entièrement cet aspect.

Je suis habitué à utiliser le même symbole pour une variable et une fonction, mais dans les zones les plus obscures, j’utilise des noms différents par peur (la collision d’espaces de noms peut être très difficile à déboguer!), et cela devrait ne soit jamais le cas.

Il y a de bonnes choses dans les deux approches. Cependant, je trouve que, lorsque cela est important, je préfère avoir à la fois une fonction LIST et une liste LIST variable que d’avoir à épeler l’une de manière incorrecte.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top