Les langages tels que C, Java et C ++ nécessitent tous des parenthèses autour d'une expression entière lorsqu'ils sont utilisés dans un if
fichier while
, ou switch
.
if (true) {
// Do something
}
par opposition à
if true {
// Do something
}
Cela me semble étrange car les parenthèses sont redondantes. Dans cet exemple, true
est une expression unique en elle-même. La parenthèse ne transforme pas sa signification de quelque manière que je sache. Pourquoi cette syntaxe étrange existe-t-elle et pourquoi est-elle si courante? Y a-t-il un avantage à cela dont je ne suis pas au courant?
THEN
).if
déclaration, elles créent simplement une déclaration composée.Réponses:
Il doit y avoir un moyen de dire où la condition se termine et où la branche commence. Il y a différentes façons de le faire.
Dans certaines langues, il n'y a pas conditionals du tout , par exemple dans Smalltalk, auto, novlangue, Io, Ioke, Seph et Fantaisie. Le branchement conditionnel est simplement implémenté comme une méthode normale comme toute autre méthode. La méthode est implémentée sur des objets booléens et est appelée sur un booléen. De cette façon, la condition est simplement le destinataire de la méthode et les deux branches sont deux arguments, par exemple dans Smalltalk:
Si vous êtes plus familier avec Java, cela équivaut à ce qui suit:
Dans la famille de langages Lisp, la situation est similaire: les conditionnelles sont juste des fonctions normales (en fait, des macros) et le premier argument est la condition, les deuxième et troisième arguments sont les branches, donc ce ne sont que des arguments de fonctions normales, et il y a rien de spécial n'est nécessaire pour les délimiter:
Certaines langues utilisent des mots clés comme délimiteurs, par exemple, Algol, Ada, BASIC, Pascal, Modula-2, Oberon, Oberon-2, Oberon actif, Component Pascal, Zonnon, Modula-3:
En Ruby, vous pouvez utiliser un mot clé ou un séparateur d'expression (point-virgule ou nouvelle ligne):
Go exige que les branches soient des blocs et n'autorise pas les expressions ou les déclarations, ce qui rend les accolades obligatoires. Par conséquent, les parenthèses ne sont pas obligatoires, mais vous pouvez les ajouter si vous le souhaitez. Perl6 et Rust sont similaires à cet égard:
Certaines langues utilisent d'autres caractères non alphanumériques pour délimiter la condition, par exemple Python:
La ligne du bas est: vous avez besoin d' un moyen de dire où la condition se termine et où la branche commence. Il y a beaucoup de façons de le faire, les parenthèses en sont une.
la source
Les parenthèses ne sont nécessaires que si vous utilisez des accolades.
Par exemple, devient ambigu sans eux.
la source
if
dans: code de base, assembleur, python, bash / zsh, tcl, batch, brainfuck ou machine. L'absence de parenthèses ne rendif
ambigu que si le langage a été conçu pour en dépendre.if Condition then ...
.{}
obligatoires et ne nécessite donc pas de parens autour de l'expression. Non seulement les parens ne sont pas obligatoires, mais si je me souviens bien, leur ajout causerait une erreur de compilation - ils sont interditsLes parenthèses dans une
if
instruction n'ont pas la même signification que les parenthèses utilisées dans une expression arithmétique. Les parenthèses dans une expression arithmétique sont utilisées pour regrouper des expressions. Les parenthèses dans uneif
instruction sont utilisées pour délimiter l'expression booléenne; c'est-à-dire différencier l'expression booléenne du reste de laif
déclaration.Dans une
if
instruction, les parenthèses n'exécutent pas de fonction de regroupement (même si, dans cetteif
instruction, vous pouvez toujours utiliser des parenthèses pour regrouper des expressions arithmétiques. L'ensemble de parenthèses externe sert alors à délimiter toute l'expression booléenne). Les rendre obligatoires simplifie le compilateur, car celui-ci peut compter sur ces parenthèses toujours présentes.la source
IF primary_expression statement
. Notez que ce dernier est également sans ambiguïté.primary_expression
ne peut pas être distingué d'un opérateur préfixe dans une expression-statement. Pour copier la réponse de Telastyn,if true ++ x;
. En outre, si des instructions vides existent, ellesif a & f;
peuvent être soit une instruction vide et binaire&
à l'intérieur de la condition, soit unaires&
au début de l'instruction. Mais quand on fait correspondre les parenthèses, il y a exactement un match pour l'ouverture (IDENTIFIER
,CONSTANT
,STRING_LITERAL
et'(' expression ')'
.Comme d'autres l'ont déjà partiellement souligné, cela est dû au fait que les expressions sont également des instructions valides. Dans le cas d'un bloc comportant une seule instruction, vous pouvez supprimer des accolades. Cela signifie que ce qui suit est ambigu:
Parce que cela pourrait être interprété comme:
au lieu de:
Un certain nombre de langages (par exemple, Python) vous permettent d’éviter les parenthèses mais ont toujours un marqueur de condition de fin:
Cependant, vous avez raison de dire que nous pourrions définir un langage dans lequel les parenthèses ne sont jamais obligatoires: un langage dans lequel une expression n'est pas une instruction valide n'aura pas ce problème.
Malheureusement, cela signifie que des choses comme:
ne seraient pas des déclarations valides, il vous faudrait donc introduire une syntaxe étrange pour pouvoir effectuer de telles actions sans créer d'expressions. Un moyen simple de faire cela est de simplement ajouter l'expression par un marqueur tel que
[statement]
:Maintenant l'ambiguïté disparaît puisqu'il faut écrire:
Mais comme vous pouvez le constater, je ne vois pas un tel langage être répandu, car placer la parenthèse autour d'une
if
-condition (ou d'une:
fin) est bien mieux que de placer un tel marqueur pour chaque expression.Remarque : l’utilisation d’un
[statement]
marqueur est la syntaxe la plus simple à laquelle je puisse penser. Cependant, vous pouvez avoir deux syntaxes complètement distinctes pour les expressions et les déclarations sans aucune ambiguïté et ne nécessitant pas un tel marqueur. Le problème est le suivant: le langage serait extrêmement étrange, car pour faire la même chose dans une expression ou dans une déclaration, il faudrait utiliser une syntaxe complètement différente.Par exemple, force est de penser que les instructions doivent obligatoirement utiliser des symboles unicode (au lieu d’
for
utiliser une variante des lettres unicodef
,o
etr
), les expressions devant être ASCII seulement.la source
discard
sa valeur dans Nim . Cependant, cela n'est fait que pour des raisons de sécurité, pas pour des raisons syntaxiques.?
simbol par exemple est une fonction après PP). Il n'y a pas;
. Bien sûr, il faut un marqueur pour la ligne suivante, mais cela est déconseillé. harbour.github.io/doc/clc53.html#if-cmd . Le compilateur est rapide et simple (créé avec Bison / Flex).if
,while
ecc sont limitées par rapport aux expressions génériques utilisées dans d'autres langues. Bien sûr: si vous avez plus de deux catégories syntaxiques (comme une déclaration, une expression, une expression logique, une expression de café, ...), vous pouvez échanger un peu de liberté.Il est courant que les langues de la famille C exigent ces parenthèses, mais elles ne sont pas universelles.
L' un des changements syntaxiques plus notables de Perl 6 est qu'ils ont modifié la grammaire afin que vous ne devez pas donner les parenthèses autour
if
,for
et les conditions de déclarations similaires. Donc, quelque chose comme ceci est parfaitement valable dans Perl 6:comme si
Cependant, comme ce ne sont que des expressions, vous pouvez les mettre entre parenthèses si vous le souhaitez. Dans ce cas, il s’agit simplement de grouper des expressions ordinaires au lieu d’une partie obligatoire de la syntaxe, telles qu’elles sont en C, C #, Java, etc.
Rust a une syntaxe similaire à Perl 6 dans ce département:
Il me semble qu'une caractéristique des langages plus modernes inspirés du C est de regarder de telles choses et de s'interroger sur leur suppression.
la source
if
ou en boucle avec BLOCK, les parens sont requis, par exemple, dansif ( $x == 4 ) { ... }
ouforeach my $foo ( @bar ) { ... }
. Lorsque la notation postfixée est utilisée, les parenthèses sont facultatives, comme dansreturn unless $foo;
ou++$x while s/foo/bar/g;
.Il y a un aspect que je suis surpris qu'aucune des réponses existantes n'ait apportée.
C, et de nombreux dérivés de C et ressemblances, présente une particularité en ce que la valeur d'une affectation est la valeur assignée. Une conséquence de ceci est qu'une affectation peut être utilisée lorsqu'une valeur est attendue.
Cela vous permet d'écrire des choses comme
ou
ou
(ce qui est implicitement traité comme
while (n < m && *p1++ = *p2++ != 0) { n++; }
parce que C considère que non-zéro est vrai; à propos, je pense que c'est à peu près strncpy () dans la bibliothèque standard C)ou même
et tout est valide. Toutes les combinaisons syntaxiquement valables ne sont pas nécessairement utiles (et les compilateurs modernes avertissent spécifiquement des assignations dans les conditions conditionnelles, parce que c'est une erreur courante), mais certaines d'entre elles sont réellement utiles.
L'analyse de telles déclarations serait probablement beaucoup plus difficile s'il n'existait pas de moyen non ambigu de déterminer le début et la fin de l'expression conditionnelle.
Les parenthèses étaient déjà utilisées pour délimiter les noms de fonction des arguments de fonction, alors je suppose qu’elles semblaient être un choix naturel, ainsi que de délimiter les mots-clés à partir des arguments de mots-clés.
Bien sûr, d'autres syntaxes pourraient être définies pour faire la même chose. Mais cela augmenterait la complexité, en particulier dans l’analyseur qui devrait alors traiter deux ensembles différents de syntaxe pour la même chose. À l'époque de la conception de C, la puissance de calcul (à la fois en termes de capacité de calcul, de mémoire de travail et de capacité de stockage) était extrêmement limitée; tout ce qui réduisait la complexité à un coût faible ou nul en lisibilité était presque certainement un changement bienvenu.
L'utilisation de parenthèses peut sembler un peu archaïque aujourd'hui, mais ce n'est pas comme si on donnait une connaissance familière du langage, cela nuirait à la lisibilité par rapport à une autre syntaxe capable d'exprimer les mêmes choses.
la source
La raison est principalement l'histoire.
Au moment de la rédaction du premier compilateur C, les ordinateurs ne disposaient que d’un nombre très limité de RAM, de CPU et de compilateurs. Ils étaient écrits «à la main» avec peu d’outils pour aider les rédacteurs du compilateur. Par conséquent, les règles complexes étaient coûteuses à implémenter dans un compilateur. C ++, C #, Java, etc. ont tous été conçus pour être faciles à apprendre pour les programmeurs C; par conséquent, aucune modification «inutile» n'a été effectuée.
Dans les langages 'c like', conditionals (
if, while, etc
) ne nécessitent pasblock
de code off explicite , vous pouvez simplement utiliser une instruction simple.ou vous pouvez combiner des déclarations dans un
compound statement
en les mettant dans{}
Nous aimons que le compilateur trouve l’erreur que nous faisons et donne un message d’erreur que nous pouvons comprendre.
la source
Java et C ++ ont tous deux été développés après que C soit devenu un langage de programmation très populaire. Lors de la conception de chacun de ces langages, il a été pris en compte qu’il serait intéressant pour les programmeurs C et de les encourager à utiliser le nouveau langage. (J'étais l'un des programmeurs C qu'ils ont réussi à séduire.) De plus, C ++ a été conçu pour être (presque) interchangeable avec le code C. Afin de soutenir ces objectifs, les deux C ++ et Java ont adopté une grande partie de la syntaxe de C, y compris les parenthèses autour des conditions de
if
,while
et desswitch
déclarations.D'où la raison pour laquelle toutes ces langues nécessitent des parenthèses autour des conditions de ces déclarations, c'est parce que C le fait, et la question est vraiment de savoir pourquoi C a besoin de ces parenthèses.
Les origines du langage C sont décrites dans cet article de Dennis Ritchie, l'un des principaux auteurs de son développement (certains pourraient même en être l' auteur principal). Comme indiqué dans cet article, C a été développé au début des années 1970 en tant que langage de programmation système pour ordinateurs avec un espace extrêmement limité dans la mémoire principale. Il était souhaitable de disposer d'un langage de niveau supérieur au langage d'assemblage, mais compte tenu des ressources disponibles, la facilité d'analyse du langage était également importante. Exiger les parenthèses rendrait l'identification du code conditionnel relativement facile.
On pourrait également en déduire que la capacité d'écrire des programmes en utilisant moins de caractères était considérée comme un avantage et que deux parenthèses prennent moins de place que le mot clé
THEN
utilisé à l'époque dans FORTRAN et d'autres langages de haut niveau; En fait, puisque les parenthèses pouvaient également remplacer les espaces comme délimiteurs de symboles,if(a==b)
quatre caractères entiers étaient-ils plus courts queIF a==b THEN
.En tout état de cause, il fallait trouver un équilibre entre la facilité avec laquelle les êtres humains seraient capables de lire, écrire et comprendre les programmes écrits en C, la facilité avec laquelle un compilateur pourrait analyser et compiler des programmes écrits en C et le nombre de kilo-octets (!) serait nécessaire à la fois pour la source du programme et le compilateur lui-même. Et entre parenthèses autour des conditions de
if
,while
, et desswitch
déclarations était comment les gens ont choisi de trouver cet équilibre dans la conception de C.Comme en témoignent plusieurs autres réponses, une fois les circonstances particulières dans lesquelles C a été développé, toutes sortes de formes de syntaxe alternatives ont été utilisées pour les conditionnelles de différents langages de programmation. Donc, entre parenthèses, il ne s’agit en réalité que d’une décision de conception prise par quelques personnes sous certaines contraintes à une certaine époque de l’histoire.
la source
Beaucoup de gens ici pensent que sans les parenthèses, la syntaxe serait ambiguë et impliquerait en silence qu'il s'agirait d'une situation mauvaise voire impossible.
En fait, les langues ont de nombreux moyens de gérer les ambiguïtés. La priorité des opérateurs n’est qu’un exemple de ce sujet.
Non, l'ambiguïté n'est pas la raison des parenthèses. Je suppose que l’on pourrait simplement créer une version de C qui n’exige pas de parenthèses autour de la condition (les rendant ainsi facultative) et qui crée toujours un code valide dans tous les cas. L’exemple de
if a ++ b;
pourrait être interprété comme équivalent àif (a) ++b;
ou àif (a++) b;
tout ce qui semble plus approprié.La question de savoir pourquoi Dennis Ritchie a choisi de rendre le () obligatoire (et donc de forger ce meme pour de nombreuses langues dérivées) est plutôt linguistique. J'imagine que l'idée d'indiquer clairement que la condition est une expression plutôt qu'un ordre était le père de la pensée.
Et en fait, C a été conçu pour être analysable à l’aide d’un analyseur en un seul passage. L'utilisation d'une syntaxe avec des parenthèses obligatoires autour de la condition prend en charge cet aspect.
la source
Les parenthèses entourant les
if
conditions ne sont pas obligatoires en Fortran, Cobol, PL / 1, Algol, Algo-68, Pascal, Modula, XPL, PL / M, MPL, ... ou dans toute autre langue comportant unthen
mot clé.then
sert à délimiter lecondition
de ce qui suitstatement
.La parenthèse fermante en C, etc. fonctionne comme
then
, et la première est formellement redondante.Les remarques ci-dessus s’appliquent aux langues analysées de manière traditionnelle.
la source