Pourquoi l'opérateur d'assignation affecte-t-il le côté gauche?


47

J'ai commencé à enseigner la programmation à un ami tout récemment (nous utilisons Python) et lorsque nous avons commencé à discuter de la création de variables et de l'opérateur d'affectation, elle a demandé pourquoi la valeur à droite est attribuée au nom à gauche et non l'inverse. .

Je n'y avais pas trop réfléchi auparavant, parce que cela me semblait naturel, mais elle a dit que la gauche à droite lui paraissait plus naturelle, car c'est ainsi que la plupart d'entre nous lisons les langues naturelles.

J'y ai pensé et j'ai conclu que cela rend le code beaucoup plus facile à lire, car les noms attribués (que le programmeur devra réutiliser) sont facilement visibles, alignés à gauche.

aligned = 2
on = 'foo' + 'bar' + 'foobar'
the = 5.0 / 2
left = 2 + 5

Par opposition à:

2 = aligned 
'foo' + 'bar' + 'foobar' = on
5.0 / 2 = the 
2 + 5 = right 

# What were the names again...?

Maintenant, je me demande s’il existe également d’autres raisons à cette norme. Y a-t-il une histoire derrière cela? Ou y a-t-il une raison technique pour laquelle c'est une bonne option (je ne connais pas beaucoup les compilateurs)? Et y a-t-il des langages de programmation qui assignent au côté droit?


15
R peut affecter le côté droit ( value -> variable).
Vous

Peut-être est-ce dû à de mauvais noms de variables? Que diriez-vous de 'numAligned is 2` et de' pouletsLeft is 2 + 5 '?
Job

18
Votre ami s'appelle-t-il ... Yoda?
Adrian

1
Si elle commence à écrire à ce sujet, je me demande ce qu’elle fera quand elle verra C ++ & co.
Blackear

3
Juste une note de côté: Khan Academy a quelques leçons sur Python pour les programmeurs débutants: khanacademy.org/#computer-science et Google en a pour plus avancées: code.google.com/edu/languages/google-python-class/set- up.html
lindon fox

Réponses:


56

Idem @paxdiablo. Les premiers langages de programmation ont été écrits par des mathématiciens - en réalité, ils l'ont tous été. En mathématiques, selon son propre principe - lire de gauche à droite - cela a du sens dans son fonctionnement.

x = 2y - 4.

En mathématiques, vous diriez ceci: Soit x égal à 2y -4.

Aussi, même en algèbre, vous le faites. Lorsque vous résolvez une équation pour une variable, vous isolez la variable que vous résolvez pour le côté gauche. c'est-à-dire que y = mx + b;

En outre, une fois que toute une famille de langues - telle que la famille C - a une certaine syntaxe, il est plus coûteux de la modifier.


19
@FarmBoy: en mathématiques, l'affectation et l'égalité SONT la même chose, puisqu'il n'y a pas de séquence dans une formule comme dans un ordinateur. (a est égal à b et en même temps b est égal à a)
Petruza

1
@FB sauf dans certains langages fonctionnels à assignation simple comme Erlang. Assignation et Assurer l'égalité sont les mêmes que dans les mathématiques
Peer Stritzinger

18
@Petruza Non, en mathématiques, assignation et égalité ne sont pas la même chose. Si je dis 'Soit x = 2y - 3', il est différent de 'Donc x = 2y - 3'. Je maths, typiquement le contexte les différencie. Comme le commentaire qui m'a contesté a été si unanimement reconnu, je mentionnerai que j'ai un doctorat. en mathématiques, j'en suis à peu près sûr.
Eric Wilson

2
Je ne connais aucune mathématique proche d'un doctorat. Ce que j'affirme, c'est qu'il n'y a pas d'ordre de séquentialité, il n'y a pas d'ordre d'exécution en mathématiques à la fois dans une cession ou dans une égalité, contrairement à la programmation, dans laquelle les deux côtés d'une cession peuvent être. différent à un moment donné, et ils finissent par être égaux à un autre moment. Mais en mathématiques, dans une tâche comme let a be...s'il n'y avait pas de temps, les deux côtés de la tâche sont égaux, la tâche est donc une égalité, il n'est donc pas étonnant que les deux utilisent le même signe:=
Petruza

5
@Petruzza - mais il y a une séquentialité. Les documents mathématiques sont écrits du début à la fin, comme tout autre document. Si j'affirme x = 1au chapitre un, mais x = 2au chapitre deux, ce n'est pas une contradiction terrible - chaque assertion ne s'applique que dans un certain contexte. La différence entre les programmes impératifs tient en partie à la suppression d’un obstacle (nous n’avons pas besoin de changer de contexte) et en partie à la mise en œuvre et à l’utilité.
Steve314

26

BASIC, l’un des premiers langages informatiques avait la forme "appropriée" de:

10 LET AREA = HEIGHT * WIDTH

qui correspond à la mentalité mathématique consistant à spécifier une variable, telle que "Soit H la hauteur de l'objet".

COBOLétait également similaire avec sa COMPUTEdéclaration. Comme pour de nombreuses façons de faire, il s’agissait peut-être simplement d’une décision arbitraire adoptée dans de nombreuses langues.


7
Je suppose que cette forme est plus naturelle lorsque les lignes de programme sont considérées comme des "instructions" et non comme des "opérations". Comme dans, I declare that X must equal THISau lieu de la plus linéaireEvaluate THIS and store it in X
voithos

Attendez, BASIC était un langage informatique 'précoce'?
Alex Feinman

2
@ Alex Étant donné que cela remonte aux années 1960, je dirais que c'est assez tôt.
Ben Richards

1
D'autre part, en COBOL, vous pouvez écrire MULTIPLY HEIGHT BY WIDTH GIVING AREA, de sorte que la variable qui obtient le résultat se trouve tout à fait à droite de l'instruction.
user281377

25

En fait, il existe un langage de programmation qui assigne sur le côté droit: TI-BASIC ! Non seulement cela, mais il n'utilise pas non plus '=' en tant qu'opérateur d'affectation, mais utilise plutôt une flèche appelée opérateur "STO".

exemples:

5→A
(A + 3)→B
(A - B)→C

Dans l'exemple ci-dessus, trois variables sont déclarées et reçoivent des valeurs. A serait 5, B serait 8 et C serait -3. La première déclaration / assignation peut être lue 'stocker 5 en tant que A'.

Quant à savoir pourquoi TI-BASIC utilise un tel système pour les affectations, je l’attribue à l’être, car c’est un langage de programmation pour une calculatrice. L'opérateur "STO" sur les calculatrices TI était le plus souvent utilisé dans les opérations normales de calculatrice après le calcul d' un nombre. S'il s'agissait d'un numéro que l'utilisateur souhaitait mémoriser, il appuierait sur le bouton "STO" et le calculateur l'inviterait à entrer un nom (enclenchant automatiquement le verrou alpha pour que les frappes au clavier produisent des lettres au lieu de chiffres):

Sin(7 + Cos(3))
                    -.26979276
Ans→{variable name}
                    -.26979276

et l'utilisateur peut nommer la variable comme bon leur semble. Avoir à activer le verrou alpha, taper le nom, puis appuyer sur "STO", et appuyer sur la touche "Ans" aurait été beaucoup trop fastidieux pour des opérations normales. Toutes les fonctions de la calculatrice étant disponibles dans TI-BASIC, aucun autre opérateur d'affectation n'a été ajouté car "STO" effectuait la même tâche, même à l'inverse de la plupart des autres langues.

(Anecdote: TI-BASIC a été l’une des premières langues que j’ai apprise. J’ai donc eu l’impression d’attribuer la valeur LEFT à la gauche, ce qui était inhabituel et «à l’arrière»!


+1 j'ai totalement oublié ça! TI Basic était aussi ma première langue, mais je ne me souviens pas de ce détail.
Barjak

En réalité, l'opérateur de la STO est plus proche du fonctionnement de la machine et du fonctionnement de n'importe quelle langue. La valeur est d'abord calculée puis stockée en mémoire.
Kratz

15

Heuristique 1: lorsque vous concevez un langage, vous devez choisir le plus commun, le plus intuitif, sinon vous obtiendrez Perl +.

Maintenant, comment est-ce plus naturel (du moins pour un anglophone)? Regardons comment nous écrivons / disons des choses en anglais:

Steven a maintenant 10 ans (contrairement à Steven, il a maintenant 10 ans). Je pèse plus de 190 livres (au lieu de plus de 190 livres).

Dans du code:

steven = 10
i > 190

Ce qui suit semble aussi plus naturel:

"Si Marie a 18 ans, elle peut avoir un bonbon". "Si j'ai moins de 21 ans, je demanderai à mon frère de tequila".

if (mary == 18) { ... }
if (i < 21) { ... }

que:

"Si Marie a 18 ans ..." "Si 21 ans est plus grande que mon âge ..."

Maintenant le code:

if (18 == mary) { ... }
if (21 > i) { ... }

Notez que cela n’est naturel ni pour les programmeurs ni pour les anglophones. Les phrases ressemblent à du yoda, et le code est surnommé yoda-conditions. Celles-ci pourraient être utiles en C ++, mais je suis sûr que la plupart des gens seront d’accord: si un compilateur pouvait faire le gros du travail et alléger le besoin de conditions yoda, la vie serait un peu plus facile.

Bien sûr, on peut s'habituer à n'importe quoi. Par exemple, le numéro 81 est écrit comme suit:

Quatre-vingt un (anglais) Quatre-vingt et un (espagnol) Un et quatre-vingt (allemand).

Enfin, il y en a 4! = 24 façons valables de dire "pomme verte se trouve sur la table" en russe - l'ordre (ou presque) n'a pas d'importance, sauf que "on" doit être associé à "table". Ainsi, si vous parlez russe (par exemple), vous ne voudrez peut-être pas écrire a = 10ou 10 = aque les deux semblent également naturels.

Bien que la linguistique soit un sujet fascinant, je ne l'ai jamais étudié formellement et ne connais pas beaucoup de langues. J'espère cependant avoir fourni suffisamment de contre-exemples.


4
... et en français, 81 est dit "quatre fois vingt et un" ... :)
Martin Sojka

1
@ Martin, je pense que le danois est très similaire.
un CVn

7
@ Martin C'est vraiment bizarre, parce que quatre fois vingt et un, c'est 84.
Peter Olson

6
@ Peter: vous vous êtes trompé de parenthèse, c'est(four times twenty) one
SingleNegationElimination

4
@Job: En lisant votre "Si Mary a 18 ans, c'est ...", on m'a inévitablement rappelé à Yoda: "Quand vous atteignez l'âge de neuf cents ans, regardez aussi bien que vous ne le ferez pas, hum?" dans Le Retour du Jedi :-)
joriki

11

Cela a commencé avec FORTRAN dans les années 1950. Où FORTRAN était une abréviation de FORmula TRANslation - les formules en question étant de simples équations algébriques qui, par convention, sont toujours assignées à gauche.

De son côté, son COBOL presque contemporain était censé être de type anglais et assigné à droite (la plupart du temps!).

MOVE 1 TO COUNTER.
ADD +1 TO LINE-CNT.
MULTIPLY QTY BY PRICE GIVING ITEM-PRICE.

Je pense que c’est le meilleur exemple ici, car il illustre parfaitement un contexte dans une langue où il est lisible par un anglophone courant mais dont les tâches sont appropriées. Je dis que c'est important à cause du grand nombre de personnes qui disent qu'en anglais, il ne lire que de gauche à droite pour que la tâche ait un sens, ce qui est tout à fait faux.
Joshua Hedges

5

Eh bien, comme @ diceguyd30 l'a fait remarquer, il y a les deux notations.

  • <Identifier> = <Value>signifie "que l' identifiant soit une valeur ". Ou pour développer cela: Définissez (ou redéfinissez) la variable Identifier to Value .
  • <Value> -> <Identifier>signifie "stocker la valeur à l' identificateur ". Ou pour développer cela: Mettez Value à l'emplacement désigné par Identifier .

Bien sûr, en règle générale, l' identificateur peut être une valeur L quelconque.

La première approche respecte le concept abstrait de variables, la seconde approche davantage le stockage réel.

Notez que la première approche est également courante dans les langues, sans affectation. Notez également que la définition des variables et l' affectation sont relativement proches par <Type> <Identifier> = <Value>rapport <Identifier> = <Value>.


3

Comme cela a déjà été mentionné, pratiquement tous les premiers langages informatiques fonctionnaient de cette façon. Par exemple, FORTRAN, qui est arrivé bien des années avant BASIC.

En fait, il est très logique d’avoir la variable assignée à gauche de l’expression d’affectation. Dans certaines langues, vous pouvez avoir plusieurs routines surchargées différentes avec SAME NAME, renvoyant différents types de résultats. En laissant le compilateur voir d’abord le type de la variable affectée, il sait quelle routine surchargée appeler ou quelle distribution implicite générer lors de la conversion (par exemple) d’un entier en un flottant. C'est une explication un peu simpliste, mais j'espère que vous aurez l'idée.


2
Je comprends votre explication, mais le compilateur ne pourrait-il pas regarder en avant jusqu’à la fin de la déclaration?
voithos

Cela pourrait rendre le lexer plus simple dans les langages actuels, mais combien de langages de programmation ont même pris en charge des méthodes nommées, sans parler des surcharges de méthodes, lorsque ce type de syntaxe était nouveau?
un CVn

2
Bonjour @voithos. Oui, le compilateur pourrait regarder vers l'avenir, mais cela aurait probablement été un niveau de complexité inacceptable au début de l'écriture du compilateur - qui était souvent un assembleur codé à la main! Je pense que mettre la variable assignée à gauche est un choix pragmatique: c'est plus facile à analyser pour l'homme et la machine.
Dave Jewell

Je pense que ce serait trivial pour une cession à assigner à la droite. Lorsqu'une expression comme 3 + 4 == 6 + 7, les deux côtés sont évalués avant l'opérateur, car le langage est défini de manière récursive. L'élément de langage 'variable = expression' pourrait facilement être remplacé par 'expression = variable'. Que cela cause ou non des situations ambiguës dépend du reste de la langue.
Kratz

@Kratz - C'est certainement vrai pour les compilateurs maintenant, mais il y a peut-être eu un problème mineur pour de très vieux langages interprétés fonctionnant avec une source à jeton. OTOH, qui aurait pu préférer variable à droite plutôt que variable à gauche.
Steve314

3

Cela pourrait être un vestige des premiers algorithmes d'analyse. Rappelez-vous que l'analyse syntaxique de LR n'a été inventée qu'en 1965 et qu'il est fort possible que les analyseurs syntaxiques de LL aient eu des problèmes (dans les limites de temps et d'espace des machines à l'époque) qui tournent à l'inverse. Considérer:

identifier = function();
function();

Les deux sont clairement distingués du deuxième jeton. D'autre part,

function() = identifier;
function();

Pas drôle. Cela empire lorsque vous commencez à imbriquer des expressions d'affectation.

function(prev_identifier = expression) = identifier;
function(prev_identifier = expression);

Bien sûr, plus facile à comprendre pour des machines signifie également plus facile à comprendre pour des humains. Un autre exemple simple consisterait à rechercher l’initialisation d’un identifiant donné.

identifier1 = expressionOfAnArbitraryLength;
identifier2 = expressionOfAReallyReallyReallyArbitraryLength;
identifier3 = expression;
identifier4 = AlongLineExpressionWithAFunctionCallWithAssignment(
    identifier = expr);

Facile, il suffit de regarder le côté gauche. Côté droit, d'autre part

expressionOfAnArbitraryLength = identifier1;
expressionOfAReallyReallyReallyArbitraryLength = identifier2;
expression = identifier3;
AlongLineExpressionWithAFunctionCallWithAssignment(expr = identifier
    ) = identifier4;

Surtout quand vous ne pouvez pas grepperforer les cartes, il est beaucoup plus difficile de trouver l'identifiant que vous voulez.


Précisément le point auquel j'avais pensé, oui.
voithos

2

Les langues d'assemblage ont la destination dans l'opcode de gauche. Les langues de niveau supérieur ont tendance à suivre les conventions des langues précédentes.

Lorsque vous voyez =(ou :=pour les dialectes pascal), vous pouvez les prononcer ainsi is assigned the value, alors la nature de gauche à droite aura un sens (car nous lisons également de gauche à droite dans la plupart des langues). Comme les langages de programmation étaient principalement développés par des gens qui lisaient de gauche à droite, les conventions restaient en place.

C'est un type de dépendance au chemin . Je suppose que si la programmation informatique a été inventée par des personnes parlant l'hébreu ou l'arabe (ou une autre langue de droite à gauche), je suppose que nous placerions la destination à droite.


Oui, mais je soupçonne que le texte dans les éditeurs serait également aligné à droite ...
voithos

8
Vous ne pouvez pas généraliser comme ça à propos des langages d'assemblage. Ils varient quant à l'emplacement de l'opérande de destination.
Rapidement maintenant

2
@quickly_now: right; En fait, la plupart des langages-machines primitifs (pas même les assembleurs selon les normes actuelles) n'avaient même pas de destination, car il n'y avait généralement qu'un ou deux accumulateurs à usage général. la plupart des opérations impliquaient l'accumulateur en tant que destination, à l'exception des opcodes «magasin», qui spécifiaient uniquement l'adresse de la mémoire et non la source (qui était l'accumulateur). Je ne pense vraiment pas que cela ait eu une influence sur la syntaxe d'attribution des langages de type ALGOL.
Javier

3
@Tangurena - Certaines langues d'assembleur ont la destimation à gauche. Pas de l'opcode (c'est le code de l'objet assemblé), mais à gauche de la liste des arguments pour l'instruction mnemonic. Cependant, d'autres ont la destination sur la droite. Dans 68000 assembler, vous écrivez mov.b #255, d0, par exemple, où d0est le registre à affecter. Les assembleurs plus âgés n'ont qu'un seul argument par instruction. Dans le 6502 LDA #255(accumulateur de charge), vous pouvez affirmer que le Aest situé à gauche, mais également à gauche dans STA wherever(accumulateur stocké).
Steve314

2
Et même l'Intel 4004 (l'ancêtre ultime 4 bits de la famille 8086, avec les séparateurs 8008 et 8080 entre les deux) a été développé après une affectation dans des langages de haut niveau. Si vous supposez que la série 8086 est représentative de ce que les assembleurs ont fait dans les années 50 et antérieures, je doute fort que ce soit le cas.
Steve314

2

Pour ce que ça vaut la peine, la plupart des déclarations contenues dans COBOL lire de gauche à droite, de sorte que les deux opérandes ont été nommés en premier lieu , et la destination dernière, comme: multiply salary by rate giving tax.

Cependant, je ne suggérerai pas à votre élève de préférer COBOL, de peur que je ne sois (à juste titre) accusé de faire un commentaire aussi bas, grossier et sans goût! :-)


1

elle a dit que la gauche à droite lui semblait plus naturelle, car c'est ainsi que la plupart d'entre nous lisons les langues naturelles.

Je pense que c'est une erreur. D'une part, vous pouvez dire "attribuer 10 à x" ou "déplacer 10 à x". D'autre part, vous pouvez dire "régler x sur 10" ou "x devient 10".

En d'autres termes, selon votre choix de verbe, la variable assignée à peut être ou ne pas être le sujet, et peut être ou ne pas être à gauche. Donc, "ce qui est naturel" dépend entièrement de votre choix habituel de libellé pour représenter une cession.


0

En pseudo-code, l'opérateur d'affectation est très souvent écrit à droite. Par exemple

2*sqrt(x)/(3+y) -> z

Dans les calculatrices Casio, même dans les variantes non programmables, la variable d’affectation est également affichée à droite

A+2B → C

En Forth, la variable est également à droite

expression variable !

En x86, la syntaxe d'Intel a la destination à gauche, mais la syntaxe GAS inverse l'ordre, ce qui crée de la confusion chez de nombreuses personnes, en particulier pour les instructions relatives à l'ordre des paramètres telles que la soustraction ou les comparaisons. Ces instructions sont les mêmes dans 2 dialectes différents

mov rax, rbx    ; Intel syntax
movq %rbx, %rax ; GAS syntax

Ils déplacent tous les deux la valeur de rbx vers rax. Je ne connais aucune autre langue d'assemblage que je connaisse écrivant la destination à droite, comme GAS.

Certaines plates-formes mettent l'expression à gauche et la variable à droite:

MOVE expression TO variable      COBOL
expression → variable            TI-BASIC, Casio BASIC
expression -> variable           BETA, R
put expression into variable     LiveCode

https://en.wikipedia.org/wiki/Assignment_%28computer_science%29#Notation

La plupart des langues attribuent la valeur à gauche, l'une des raisons étant qu'il est facile d'aligner les opérateurs, de lire et de reconnaître la variable plus facilement, car les positions des opérateurs d'assignation et des variables ne varieront pas énormément dans les lignes et sont plus faciles à lire. "que la variable soit une valeur".

Cependant, certaines personnes préfèrent dire "déplacer la valeur x vers y" et écrire la variable à droite.


-1

Je pense que cela suit une façon logique de penser.
Il doit d'abord y avoir une boîte (variable), puis un objet (valeur) à l'intérieur.
Vous ne mettez pas l'objet en l'air et ne placez pas ensuite une boîte autour.


2
oui vous faites. dans la plupart des langues, le côté droit est évalué avant le côté gauche.
Javier

3
C'est un type de "conduite sur le côté droit de la route". Cela semble logique, mais seulement parce que c’est comme vous l’avez toujours fait. Tous les pays supérieurs conduisent à gauche.
James Anderson

1
@JamesAnderson pays supérieurs? : o
nawfal

Vous avez raison, ce n’est que logique pour un système d’écriture de gauche à droite comme l’alphabet latin, qui, je suppose, est utilisé par presque tous les langages de programmation, sinon tous.
Petruza
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.