48 votes

Parenthèses Lisp

Pourquoi les Lispers formatent-ils leur code comme indiqué dans l'exemple 1 et non comme indiqué dans l'exemple 2 ? Pour moi (et je suppose, pour la plupart des autres personnes venant d'horizons de programmation différents de Lisp), le formatage montré dans l'exemple 2 serait plus facile à lire. Y a-t-il une raison particulière pour laquelle les Lispers préfèrent le style de l'échantillon 1 ?

Echantillon 1

(defun factorial (n)
  (if (<= n 1)
    1
    (* n (factorial (- n 1)))))

Echantillon 2

(defun factorial (n)
  (if (<= n 1)
    1
    (* n (factorial (- n 1)))
  )
)

9 votes

Avez-vous essayé le style 2 sur une fonction non triviale ? :-)

38voto

Pontus Gagge Points 12950

Les environnements IDE LISP ont tendance à équilibrer automatiquement les parenthèses et à gérer les retraits en fonction du niveau d'imbrication. L'échantillon 2 n'apporte aucun avantage dans ces situations.

Dans l'héritage C/FORTRAN/Pascal, vous avez tendance à mettre l'accent sur le séquençage plutôt que sur l'imbrication (les arbres d'analyse du code sont moins profonds et plus larges). La fin de la portée est un événement plus significatif dans votre code : par conséquent, l'accent a été et est toujours, dans une certaine mesure, plus important.

25voto

Rainer Joswig Points 62532

Pour les utilisateurs expérimentés de Lisp, le niveau d'imbrication est plus important que la recherche de parenthèses fermantes. Le fait de placer les parenthèses fermantes sur leurs propres lignes n'aide pas vraiment à déterminer les niveaux d'imbrication.

L'idée de base est que les parenthèses entourent directement leur contenu.

(a)

et non

(a
)

Voici ce qui suit :

(defun foo (bar)
  (foo (bar (baz
              ...
             )
         ...
        )
    ...
   )
 )

vs.

(defun foo (bar)
  (foo (bar (baz ...) ...) ...))

L'une des idées de base lors de l'édition de texte Lisp est que vous pouvez sélectionner une liste en (double-) cliquant sur les parenthèses (ou en utilisant une commande clavier lorsque le curseur se trouve à l'intérieur de l'expression ou sur les parenthèses). Vous pouvez ensuite couper/copier l'expression et la coller à un autre endroit dans une autre fonction. L'étape suivante consiste à sélectionner l'autre fonction et réindenter la fonction. C'est fait. Il n'est pas nécessaire de supprimer ou d'introduire de nouvelles lignes pour les parenthèses fermantes. Il suffit de coller et de réindenter. Cela s'intègre parfaitement. Sinon, soit vous perdriez du temps à formater le code, soit vous devriez le reformater avec un outil d'édition (pour que les parenthèses fermantes soient sur leurs propres lignes). La plupart du temps, cela créerait un travail supplémentaire et gênerait le déplacement du code.

Il y a une occasion où les lispers expérimentés écrivent parfois les parenthèses fermantes sur leur propre ligne :

(defvar *persons*
   (list (make-person "fred")
         (make-person "jane")
         (make-person "susan")
         ))

Il indique ici que de nouvelles personnes peuvent être ajoutées. Placez le curseur juste avant la deuxième parenthèse fermante sur la dernière ligne, appuyez sur c-o (ouvrir la ligne), ajoutez la clause et indentez les parenthèses pour qu'elles soient à nouveau alignées. Cela évite d'avoir à trouver les bonnes parenthèses et à appuyer sur la touche retour, lorsque toutes les parenthèses sont fermées sur une ligne.

0 votes

+1, bien que j'aie tendance à utiliser un blanc au lieu d'une nouvelle ligne pour cela.

0 votes

(defvar personnes (liste (faire-personne "fred") (faire-personne "jane") (faire-personne "susan") ))) #manque la fermeture "

0 votes

@Taylor Bioniks : changé. Merci !

16voto

Eli Bendersky Points 82298

Parce qu'il n'est pas nécessaire d'aligner les parenthèses fermantes. Cela n'ajoute rien sémantiquement. Pour savoir combien en fermer, la plupart des Lispers utilisent un bon éditeur, comme Emacs, qui fait correspondre les parens aux parens fermantes et rend donc la tâche triviale.

En Python, il n'y a pas de parenthèses de fermeture ou de end mots-clés du tout, et les pythonistes vivent très bien.

1 votes

Python n'est pas seulement bon. Le code complexe est difficile à lire précisément à cause de ce problème.

1 votes

+1 pour avoir signalé l'IDE ! un bon vieil Emacs avec paredit et un mode arc-en-ciel bien configuré rend la tâche vraiment triviale

9voto

liwp Points 3473

Après un certain temps avec Lisp, vous ne remarquez plus les parenthèses, donc votre exemple deux se présente comme ayant un tas d'espaces blancs inutiles à la fin. Plus précisément, la plupart des lispers utilisent un éditeur qui est conscient des parenthèses et se charge de fermer les formes correctement, de sorte que vous, en tant que développeur, n'avez pas besoin de faire correspondre les parenthèses ouvrantes et fermantes comme vous le faites en C, par exemple.

Quant à savoir si le dernier formulaire doit être

(* n (factorial (- n 1)))

ou

(* n
   (factorial (- n 1)))

c'est surtout une question de préférence personnelle et de quantité de choses qui se passent dans le code (dans ce cas, je préfère la première solution parce qu'il y a si peu de choses qui se passent dans le code).

5voto

Michael Brown Points 1639

Outre le fait que la plupart des IDE Lisp utilisent la correspondance des parens, la quantité d'espace que vous utiliseriez pour écrire un programme raisonnable serait ridicule ! Vous auriez le syndrome du canal carpien à cause de tous les défilements. Un programme de 1 000 lignes serait proche d'un million de lignes de code si vous mettiez toutes les parenthèses fermantes sur leur propre ligne. Cela peut sembler plus joli et plus facile à lire dans un petit programme, mais cette idée ne serait pas du tout évolutive.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X