Pourquoi un langage devrait-il préférer l'indentation aux marqueurs explicites pour les blocs?

11

J'apprends Haskell et je cherchais un outil d'indentation automatique. Je n'ai pas beaucoup regardé et j'ai appris que dans Haskell (comme dans Python), l'indentation signifie un bloc. Par conséquent, je suppose qu'il est impossible de créer un outil de mise en forme automatique, aussi puissant que dans d'autres langages de la famille C, qui utilise des marqueurs explicites, tels que {} (accolades) ou des begin endmots clés.

Cela ne me dérange pas un langage imposant l'indentation pour la lisibilité, mais je ne peux pas comprendre les avantages de l'application de l'indentation et de la présence d'un marqueur explicite, de sorte que les outils automatisés puissent comprendre ce qui appartient à quel bloc.

Si la préférence de l'indentation marquant un bloc est que le code soit meilleur, je ne comprends toujours pas l'avantage. Étant donné que les tabulations et les espaces sont représentés différemment dans différents éditeurs et différentes polices (les polices mono-espace par exemple sont plus ordonnées), il est impossible d'attendre du programmeur qu'il présente le code de manière décente. Un outil qui peut prendre en compte l'éditeur de texte actuel, serait beaucoup plus approprié pour formater correctement le code.

Pourquoi un concepteur de langage choisirait-il l'indentation plutôt que les marqueurs de bloc explicites?

Réintégrer Monica
la source
8
Pas une réponse, mais Haskell rend la sensibilité des espaces blancs beaucoup plus facultative que python. Vous pouvez utiliser des points-virgules pour la plupart des choses et envelopper les blocs entre accolades si vous le souhaitez. let x =1; y = 2; z = 3est complètement valide, tel quel do { putStrLn $ show x; putStrLn $ show y; putStrLn $ show z; }. Ceux-ci n'ont pas besoin d'être sur la même ligne.
KChaloux
8
"il est impossible de créer un outil de formatage automatique" - en fait, il n'y a pas besoin d'un tel outil de formatage automatique en Python en raison des règles d'indentation.
Doc Brown
13
Um, l'augmentation de l'indentation est un marqueur de bloc explicite.
Karl Bielefeldt
3
@ K.Gkinis: La meilleure source pour les motivations exactes derrière une décision de conception linguistique sont les concepteurs linguistiques eux-mêmes.
Robert Harvey
3
Cette question n'est pas réellement subjective. Il demande pourquoi certains concepteurs de langage ont choisi une certaine syntaxe. On peut y répondre. Si la question avait demandé quelle syntaxe était la meilleure , elle serait subjective.
JacquesB

Réponses:

13

Guido Von Rossum

Extrait d' une entrevue avec Guido Van Rossum , qui peut être vue en texte intégral sur books.google.com (c'est moi qui souligne):

Le choix de l'indentation pour le regroupement n'était pas un concept nouveau en Python; J'ai hérité de ABC , mais cela s'est également produit en occam, une langue plus ancienne. Je ne sais pas si les auteurs d'ABC ont eu l'idée de l'occam, ou l'ont inventé indépendamment, ou s'il y avait un ancêtre commun. Bien sûr, j'aurais pu choisir de ne pas suivre l'exemple d'ABC, comme je l'ai fait dans d'autres domaines (par exemple, ABC a utilisé des majuscules pour les mots-clés de langue et les noms de procédure, une idée que je n'ai pas copiée), mais j'en étais venu à aimer la fonctionnalité assez peu en utilisant ABC, car il semblait supprimer un certain type de débat inutile courant chez les utilisateurs C à l'époque, sur l' endroit où placer les accolades .

Von Rossum s'est fortement inspiré de ABC , et même s'il n'avait pas à tout copier, l'utilisation de l'indentation a été conservée car elle pourrait être bénéfique pour éviter les guerres de religion.

J'étais également bien conscient que le code lisible utilise de toute façon volontairement l'indentation pour indiquer le regroupement, et j'avais rencontré des bogues subtils dans le code où l'indentation n'était pas d'accord avec le regroupement syntaxique en utilisant des accolades - le programmeur et tous les examinateurs avaient supposé que l'indentation correspondait au regroupement et donc pas remarqué le bug. Encore une fois, une longue session de débogage a enseigné une leçon précieuse.

Rossum a également été témoin de bogues en raison de l'incohérence entre le regroupement et le retrait, et apparemment, bien que se fier à l'indentation uniquement pour structurer le code serait plus sûr contre les erreurs de programmation 1 .

Donald E. Knuth et Peter J. Landin

Dans l'interview référencée, Guido mentionne l'idée de Don Knuth d'utiliser l'indentation. Ceci est détaillé dans The Knuth Indentation Quote rediscovered , qui cite la programmation structurée avec des instructions goto . Knuth fait également référence aux 700 prochains langages de programmation de Peter John Landin (voir la section Discussion sur l'indentation). Landin a conçu ISWIM qui ressemble à la première langue avec indentation au lieu de blocs de début / fin. Ces articles portent davantage sur la faisabilité de l'utilisation de l'indentation pour structurer des programmes plutôt que sur des arguments réels en faveur de le faire.


1. Je pense que c'est en fait un argument en faveur de la création de regroupements et de la mise en forme automatique, afin d'attraper et de récupérer des erreurs de programmation, qui ne manqueront pas de se produire. Si vous bousillez votre indentation en Python, la personne qui débogue votre code devra deviner laquelle est correcte:

if (test(x)):
  foo(x)
  bar(x)

Doit bartoujours être appelé ou seulement si le test réussit?

Les constructions de regroupement ajoutent un niveau de redondance qui vous aide à repérer une erreur lorsque vous indentez automatiquement votre code. En C, le code équivalent peut être mis en retrait automatiquement comme suit:

if (test(x))
  foo(x);
bar(x);

Si je voulais barêtre au même niveau que foo, alors l'indentation automatique basée sur la structure du code m'a permis de voir qu'il y a quelque chose qui ne peut pas être corrigé en ajoutant des accolades autour de fooet bar.

Dans Python: Mythes sur l'indentation , il y a un supposé mauvais exemple de C:

/*  Warning:  bogus C code!  */

if (some condition)
        if (another condition)
                do_something(fancy);
else
        this_sucks(badluck);

C'est le même cas que ci-dessus, dans Emacs, je sélectionne l'ensemble du bloc / fonction, j'appuie sur Tab, puis tout le code est réindenté. L'écart entre l'indentation humaine et la structure du code me dit que quelque chose ne va pas (cela et le commentaire précédent!).

En outre, le code intermédiaire où l'indentation est désactivée en C ne passe tout simplement pas par la branche principale, toutes les vérifications de style en place feraient crier GCC / Jenkins sur moi. J'ai récemment eu un problème similaire à celui décrit ci-dessus en Python, avec une déclaration désactivée par un niveau d'indentation. Parfois, j'ai du code en C qui va au-delà d'une accolade fermante, mais ensuite je frappe Tab et le code induit "à tort": c'est une chance de plus pour voir le bogue.

coredump
la source
3
"Pour éviter les guerres de religion ..." Je suis surpris que la vraie raison soit si banale.
Robert Harvey
1
@RobertHarvey: L'accent est mis sur cette phrase par coredump, pas par van Rossum. Ce n'est pas la raison principale si vous lisez la citation de van Rossum dans son contexte.
JacquesB
@JacquesB Veuillez me dire quel contexte manque dans la citation, afin que je puisse éditer la réponse.
coredump
4
Je ne reçois pas de commentaire personnel: si vous bousillez l'indentation en Python, alors vous avez un bug. Si vous bousiller des accolades en C, vous avez un bug. Si vous utilisez l'indentation automatique, c'est exactement la même chose dans les deux langues. Et si vous n'utilisez pas l'indentation automatique, le bogue peut être caché en C d'une manière qui n'est pas possible en Python.
JacquesB
2
@JacquesB parce que taper une accolade fermante est quelque chose que vous faites activement; ne pas mettre suffisamment en retrait est quelque chose que vous pouvez oublier de faire. Bien sûr, vous pouvez oublier de fermer une attelle au bon moment, mais vous devrez éventuellement le faire et avoir une autre chance d'y penser. Je suppose que le python fonctionne bien pour les débutants car il force l'attention sur l'indentation.
marstato
7

C'est très subjectif et la cause de nombreuses guerres de flammes. Pourtant:

Avoir des symboles délimitant des blocs et des indentations viole le principe DRY , car vous exprimez les mêmes informations de deux manières différentes. L'existence d'outils d'indentation automatisés est un symptôme de cette violation DRY: le fait que vous puissiez générer automatiquement l'indentation montre qu'il s'agit d'informations redondantes et que l'indentation et les symboles peuvent se désynchroniser, ce qui conduit à un code trompeur.

La FAQ Python Design and History le dit très clairement:

Pourquoi Python utilise-t-il l'indentation pour regrouper les instructions?

Guido van Rossum estime que l'utilisation de l'indentation pour le regroupement est extrêmement élégante et contribue beaucoup à la clarté du programme Python moyen. La plupart des gens apprennent à aimer cette fonctionnalité après un certain temps.

Puisqu'il n'y a pas de parenthèses de début / fin, il ne peut y avoir de désaccord entre le regroupement perçu par l'analyseur et le lecteur humain.

Il est vrai que vous ne pouvez pas créer un outil d'indentation automatique pour Python, mais c'est une bonne chose: cela signifie que vous n'avez pas de redondances dans la syntaxe que vous avez besoin d'outils automatisés pour réconcilier.

Les tabulations vs espaces est une préoccupation légitime en Python, et il est recommandé de ne jamais mélanger les tabulations et les espaces (pour l'indentation) dans la même base de code.

Python a hérité de l'indentation significative du langage prédécesseur (désormais obsolète) ABC. ABC est l'un des rares langages de programmation à avoir utilisé des tests d'utilisabilité pour diriger la conception. Ainsi, alors que les discussions sur la syntaxe se résument généralement à des opinions subjectives et à des préférences personnelles, le choix d'une indentation significative a en fait une base plus solide.

JacquesB
la source
6
La comptabilité à double entrée viole également DRY. La redondance est parfois une fonctionnalité.
coredump
3
@coredump: C'est vrai, mais c'est une redondance délibérément conçue. La plupart des langages de programmation, y compris Python, contiennent des redondances délibérément choisies - par exemple le passmot - clé qui pourrait être déduit automatiquement, mais le nécessitant d'être explicite permet de découvrir les erreurs. La redondance accidentelle d'avoir à la fois des symboles de début / fin (pour le compilateur) et l'indentation (pour le lecteur humain) semble causer plus d'erreurs qu'elle n'en attrape. C'est du moins le point de vue de van Rossum.
JacquesB
@coredump - Maintenant, je sais pourquoi je ne suis pas comptable.
JeffO
3
@coredump Vous manquez aussi COBOL PROCEDURE DIVISION.? Je ne peux jamais dire où DATA DIVISIONcommencent les fins et les procédures dans ces nouveaux langages.
msw
2
@coredump: "voir l'indentation contredit ce que j'avais en tête est suffisant pour éviter les erreurs" - exactement.
JacquesB
2

Les concepteurs de langage choisissent des espaces syntaxiquement significatifs parce qu'ils croient (ou du moins pensent que leurs utilisateurs potentiels croient) que les points-virgules et les accolades ajoutent du bruit lors de la lecture du code, ce qui nuit à la productivité. Une autre raison courante est que le style de codage incorrect / incohérent nuit à la lisibilité - en forçant un schéma d'indentation commun, le langage a une meilleure lisibilité globale. Cette dernière raison est moins importante maintenant que les IDE de mise en forme automatique sont plus courants, mais peuvent toujours s'appliquer.

Telastyn
la source
1
Je peux voir pourquoi on considérerait le point-virgule et le bruit des accolades. Mais n'est-il pas moins productif de devoir taper 4/8/12 fois l'espace? Et si vous en manquez un (car ils sont invisibles), vous avez des ennuis.
Rétablir Monica
5
C'est pourquoi vous utilisez des tabulations au lieu d'espaces, ou un IDE qui comprend comment convertir des tabulations en blocs à quatre espaces.
Robert Harvey
@ K.Gkinis: Les retraits ne sont pas invisibles. Seuls les espaces à la fin des lignes sont invisibles, mais cela n'est significatif dans aucune langue. Ce n'est que si vous mélangez les tabulations et les espaces que vous aurez des ennuis. Alors ne fais pas ça.
JacquesB
@JacquesB: le problème de la visibilité / invisibilité de l'indentation est qu'en tant qu'humain, vous ne pouvez souvent pas faire la différence entre les espaces et un onglet, alors que l'ordinateur le peut et le fait souvent. Ainsi, bien que l'indentation soit visible, la façon dont l'ordinateur interprète l'indentation peut être différente. C'est le vrai problème: quand l'ordinateur traite les personnages invisibles différemment des humains. Les humains mesurent l'indentation comme la distance sur un écran, les ordinateurs peuvent la mesurer comme un nombre littéral de caractères. c'est la partie invisible.
Bryan Oakley
@BryanOakley: Oui, c'est pourquoi vous ne devez pas mélanger les tabulations et les espaces en retrait.
JacquesB