Perché le scorciatoie come x + = y sono considerate buone pratiche?


305

Non ho idea di come si chiamino questi, ma li vedo sempre. L'implementazione di Python è simile a:

x += 5come una notazione abbreviata per x = x + 5.

Ma perché questa è considerata una buona pratica? L'ho incontrato in quasi tutti i libri o tutorial di programmazione che ho letto per Python, C, R e così via. Capisco che è conveniente, risparmiando tre sequenze di tasti inclusi gli spazi. Ma sembrano sempre farmi inciampare quando leggo il codice e, almeno secondo me, lo rendono meno leggibile, non di più.

Mi sto perdendo qualche motivo chiaro e ovvio che questi vengono utilizzati in tutto il luogo?


@EricLippert: C # lo gestisce allo stesso modo della risposta principale descritta? In realtà è più efficiente dire il CLR x += 5rispetto a x = x + 5? O è davvero solo zucchero sintattico come suggerisci?
carne

24
@blesh: Che piccoli dettagli su come si esprime un'aggiunta nel codice sorgente hanno un impatto sull'efficienza del codice eseguibile risultante potrebbe essere stato il caso nel 1970; non è certo ora. I compilatori di ottimizzazione sono buoni e hai preoccupazioni più grandi di un nanosecondo qui o là. L'idea che l'operatore + = sia stato sviluppato "venti anni fa" è ovviamente falsa; il compianto Dennis Richie sviluppò la C dal 1969 al 1973 ai Bell Labs.
Eric Lippert,


5
La maggior parte dei programmatori funzionali considererà questa cattiva pratica.
Pete Kirkham,

Risposte:


598

Non è una scorciatoia.

Il +=simbolo apparve nel linguaggio C negli anni '70 e, con l'idea C di "assemblatore intelligente", corrisponde a una modalità di istruzione e indirizzo chiaramente diversa:

Cose come " i=i+1", "i+=1"e" ++i", sebbene a livello astratto producano lo stesso effetto, corrispondono a basso livello a un diverso modo di lavorare del processore.

In particolare quelle tre espressioni, supponendo che la ivariabile risieda nell'indirizzo di memoria memorizzato in un registro CPU (chiamiamolo D- pensiamolo come un "puntatore a int") e l' ALU del processore accetta un parametro e restituisce un risultato in un "accumulatore" (chiamiamolo A - pensaci come un int).

Con questi vincoli (molto comuni in tutti i microprocessori di quel periodo), molto probabilmente la traduzione sarà

;i = i+1;
MOV A,(D); //Move in A the content of the memory whose address is in D
ADD A, 1;  //The addition of an inlined constant
MOV (D) A; //Move the result back to i (this is the '=' of the expression)

;i+=1;
ADD (D),1; //Add an inlined constant to a memory address stored value

;++i;
INC (D); //Just "tick" a memory located counter

Il primo modo di farlo è non ottimale, ma è più generale quando si opera con variabili anziché costanti ( ADD A, Bo ADD A, (D+x)) o quando si traducono espressioni più complesse (tutte si riducono in un'operazione a bassa priorità in uno stack, chiamano la priorità alta, pop e ripetere fino a quando tutti gli argomenti sono stati eliminati).

Il secondo è più tipico di "macchina a stati": non stiamo più "valutando un'espressione", ma "gestendo un valore": usiamo ancora la ALU, ma evitiamo di spostare i valori perché il risultato ci consente di sostituire il parametro. Questo tipo di istruzione non può essere utilizzato dove sono richieste espressioni più complicate: i = 3*i + i-2non può essere utilizzato sul posto, poiché iè richiesto più volte.

Il terzo - anche più semplice - non considera nemmeno l'idea di "addizione", ma usa un circuito più "primitivo" (in senso computazionale) per un contatore. L'istruzione è in cortocircuito, carica più velocemente ed esegue immediatamente, poiché la rete combinatoria richiesta per il retrofit di un registro per renderlo un contatore è più piccola, e quindi più veloce di quella di un full-adder.

Con i compilatori contemporanei (fare riferimento a C, ormai), che consente l'ottimizzazione del compilatore, la corrispondenza può essere scambiata in base alla convenienza, ma c'è ancora una differenza concettuale nella semantica.

x += 5 si intende

  • Trova il luogo identificato da x
  • Aggiungi 5 ad esso

Ma x = x + 5significa:

  • Valuta x + 5
    • Trova il luogo identificato da x
    • Copia x in un accumulatore
    • Aggiungi 5 all'accumulatore
  • Memorizza il risultato in x
    • Trova il luogo identificato da x
    • Copia l'accumulatore su di esso

Certo, l'ottimizzazione può

  • se "trovare x" non ha effetti collaterali, i due "trovare" possono essere fatti una volta (e x diventa un indirizzo memorizzato in un registro puntatore)
  • le due copie possono essere eluse se si applica ADD al &xposto dell'accumulatore

rendendo così il codice ottimizzato in coincidenza con x += 5quello.

Ma questo può essere fatto solo se "trovare x" non ha effetti collaterali, altrimenti

*(x()) = *(x()) + 5;

e

*(x()) += 5;

sono semanticamente diversi, poiché x()gli effetti collaterali (ammettere x()è una funzione che fa cose strane in giro e restituire un int*) saranno prodotti due o una volta.

L'equivalenza tra x = x + ye x += yè quindi dovuta al caso particolare in cui +=e =sono applicati a un valore l diretto.

Per passare a Python, ha ereditato la sintassi da C, ma poiché non c'è traduzione / ottimizzazione PRIMA dell'esecuzione in linguaggi interpretati, le cose non sono necessariamente così intimamente correlate (poiché c'è un passaggio di analisi in meno). Tuttavia, un interprete può fare riferimento a diverse routine di esecuzione per i tre tipi di espressione, sfruttando diversi codici macchina a seconda di come si forma l'espressione e del contesto di valutazione.


Per chi ama più dettagli ...

Ogni CPU ha una ALU (unità aritmetica-logica) che è, nella sua essenza, una rete combinatoria i cui input e output sono "collegati" ai registri e / o alla memoria a seconda del codice operativo dell'istruzione.

Le operazioni binarie sono in genere implementate come "modificatore di un registro accumulatore con un input preso" da qualche parte ", dove un posto può trovarsi - all'interno del flusso di istruzioni stesso (tipico per il contendente manifest: ADD A 5) - all'interno di un altro registro (tipico per il calcolo dell'espressione con provvisori: ad es. ADD AB) - all'interno della memoria, a un indirizzo fornito da un registro (tipico del recupero dei dati, ad es .: ADD A (H)) - H, in questo caso, funziona come un puntatore a dereferenziazione.

Con questo pseudocodice, x += 5è

ADD (X) 5

mentre lo x = x+5è

MOVE A (X)
ADD A 5
MOVE (X) A

Cioè, x + 5 fornisce un temporaneo che viene successivamente assegnato. x += 5opera direttamente su x.

L'implementazione effettiva dipende dal set di istruzioni reale del processore: se non esiste un ADD (.) ccodice operativo, il primo codice diventa il secondo: impossibile.

Se esiste un tale codice operativo e l'ottimizzazione è abilitata, la seconda espressione, dopo aver eliminato i movimenti inversi e regolato il codice operativo dei registri, diventa la prima.


90
+1 per l'unica risposta che spiega che ai vecchi tempi era utilizzato per mappare un codice macchina diverso (e più efficiente).
Péter Török,

11
@KeithThompson Questo è vero, ma non si può negare che l'assemblaggio abbia avuto un'enorme influenza sul design del linguaggio C (e successivamente su tutti i linguaggi stile C)
MattDavey,

51
Ehm, "+ =" non è mappato su "inc" (è mappato su "add"), "++" è mappato su "inc".
Brendan,

11
Per "20 anni fa", penso che intendi "30 anni fa". E a proposito, COBOL ha battuto C per altri 20 anni con: AGGIUNGI 5 A X.
JoelFan

10
Ottimo in teoria; sbagliato nei fatti. L'ASM INC x86 aggiunge solo 1, quindi non influisce sull'operatore "aggiungi e assegna" qui discusso (questa sarebbe un'ottima risposta per "++" e "-" però).
Mark Brackett,

281

A seconda di come ci pensi, in realtà è più facile da capire perché è più semplice. Prendi ad esempio:

x = x + 5 invoca l'elaborazione mentale di "prendi x, aggiungi cinque ad esso e quindi assegna quel nuovo valore a x"

x += 5 può essere pensato come "aumentare x di 5"

Quindi, non è solo una scorciatoia, in realtà descrive la funzionalità molto più direttamente. Quando si leggono goccioline di codice, è molto più facile da capire.


32
+1, sono totalmente d'accordo. Ho iniziato a programmare da bambino, quando la mia mente era facilmente malleabile e x = x + 5mi turbava ancora. Quando sono entrato in matematica in età avanzata, mi ha infastidito ancora di più. L'uso x += 5è significativamente più descrittivo e ha molto più senso come espressione.
Polinomio

44
C'è anche il caso in cui la variabile ha un nome lungo: reallyreallyreallylongvariablename = reallyreallyreallylongvariablename + 1... oh no !!! un errore di battitura

9
@Matt Fenwick: non deve essere un nome di variabile lungo; potrebbe essere un'espressione di qualche tipo. È probabile che siano ancora più difficili da verificare e il lettore deve dedicare molta attenzione per assicurarsi che siano uguali.
David Thornley,

32
X = X + 5 è una specie di hack quando il tuo obiettivo è incrementare x di 5.
JeffO

1
@Polynomial Penso di essermi imbattuto nel concetto di x = x + 5 anche da bambino. 9 anni se ricordo bene - e per me ha perfettamente senso e ha ancora perfettamente senso per me ora e preferisco di gran lunga a x + = 5. Il primo è molto più dettagliato e posso immaginare il concetto molto più chiaramente - l'idea che sto assegnando a x il valore precedente di x (qualunque cosa sia) e quindi l'aggiunta di 5. Immagino che cervelli diversi funzionino in modi diversi.
Chris Harrison,

48

Almeno in Python , x += ye x = x + ypuò fare cose completamente diverse.

Ad esempio, se lo facciamo

a = []
b = a

allora a += [3]comporterà a == b == [3], mentre a = a + [3]comporterà a == [3]e b == []. Cioè, +=modifica l'oggetto sul posto (beh, potrebbe fare, puoi definire il __iadd__metodo per fare praticamente qualsiasi cosa ti piaccia), mentre =crea un nuovo oggetto e lega la variabile ad esso.

Questo è molto importante quando si esegue un lavoro numerico con NumPy , poiché si finisce frequentemente con più riferimenti a diverse parti di un array ed è importante assicurarsi di non modificare inavvertitamente parte di un array a cui sono presenti altri riferimenti, o inutilmente copiare array (che può essere molto costoso).


4
+1 per __iadd__: ci sono lingue in cui è possibile creare un riferimento a un immutabile datastructure mutevole, dove il operator +=è definito, ad esempio Scala: val sb = StringBuffer(); lb += "mutable structure"vs var s = ""; s += "mutable variable". l'ulteriore modifica del contenuto della struttura dati mentre il secondo rende la variabile puntare a una nuova.
pecora volante

43

Si chiama idioma . I linguaggi di programmazione sono utili perché sono un modo coerente di scrivere un particolare costrutto di programmazione.

Ogni volta che qualcuno x += yti scrive sai che xviene incrementato da ye non da alcune operazioni più complesse (come best practice, in genere non mescolerei operazioni più complicate e queste scorciatoie di sintassi). Questo ha più senso quando si incrementa di 1.


13
x ++ e ++ x sono leggermente diversi da x + = 1 e l'uno dall'altro.
Gary Willoughby,

1
@Gary: ++xe x+=1sono equivalenti in C e Java (forse anche in C #) anche se non necessariamente in C ++ a causa della complessa semantica dell'operatore. La chiave è che entrambi valutano xuna volta, incrementano la variabile di uno e hanno un risultato che è il contenuto della variabile dopo la valutazione.
Donal Fellows,

3
@Donal Fellows: la precedenza è diversa, quindi ++x + 3non è la stessa di x += 1 + 3. Tra parentesi il x += 1ed è identico. Come affermazioni da soli, sono identici.
David Thornley,

1
@DavidThornley: è difficile dire "sono identici" quando entrambi hanno un comportamento indefinito :)
Lightness Races in Orbit

1
Nessuna delle espressioni ++x + 3, x += 1 + 3o (x += 1) + 3hanno un comportamento non definito (assumendo il conseguente valore "si adatta").
John Hascall,

42

Per chiarire un po 'il punto di @ Pubby, considera someObj.foo.bar.func(x, y, z).baz += 5

Senza l' +=operatore, ci sono due modi per andare:

  1. someObj.foo.bar.func(x, y, z).baz = someObj.foo.bar.func(x, y, z).baz + 5. Questo non è solo terribilmente ridondante e lungo, è anche più lento. Pertanto si dovrebbe
  2. Utilizzare una variabile temporanea: tmp := someObj.foo.bar.func(x, y, z); tmp.baz = tmp.bar + 5. Va bene, ma è molto rumoroso per una cosa semplice. Questo è in realtà molto vicino a ciò che accade in fase di runtime, ma è noioso scrivere e il solo utilizzo +=sposta il lavoro sul compilatore / interprete.

Il vantaggio di +=e altri operatori simili è innegabile, mentre abituarsi a loro è solo una questione di tempo.


Una volta che sei a 3 livelli di profondità nella catena di oggetti, puoi smettere di preoccuparti delle piccole ottimizzazioni come 1 e del codice rumoroso come 2. Invece, pensa al tuo design ancora una volta.
Dorus,

4
@Doro: l'espressione che ho scelto è solo un rappresentante arbitrario di "espressione complessa". Sentiti libero di sostituirlo con qualcosa nella tua testa, di cui non ti pignoli;)
back2dos

9
+1: questa è la ragione principale di questa ottimizzazione: è sempre corretta, non importa quanto sia complessa l'espressione sul lato sinistro.
S. Lott,

9
Mettere un refuso lì è una bella illustrazione di ciò che può accadere.
David Thornley,

21

È vero che è più breve e più semplice, ed è vero che probabilmente è stato ispirato dal linguaggio assembly sottostante, ma il motivo per cui è la migliore pratica è che impedisce un'intera classe di errori, e rende più facile rivedere il codice ed essere sicuro cosa fa.

Con

RidiculouslyComplexName += 1;

Dal momento che è coinvolto solo un nome di variabile, sei sicuro di cosa fa l'istruzione.

Con RidiculouslyComplexName = RidiculosulyComplexName + 1;

C'è sempre il dubbio che le due parti siano esattamente le stesse. Hai visto il bug? Peggio ancora quando sono presenti abbonamenti e qualificatori.


5
Peggiora ancora nelle lingue in cui le istruzioni di assegnazione possono creare implicitamente variabili, soprattutto se le lingue fanno distinzione tra maiuscole e minuscole.
supercat

14

Mentre la notazione + = è idiomatica e più breve, questi non sono i motivi per cui è più facile da leggere. La parte più importante della lettura del codice è la mappatura della sintassi sul significato, e quindi più la sintassi si avvicina ai processi di pensiero del programmatore, più sarà leggibile (questo è anche il motivo per cui il codice del boilerplate è cattivo: non fa parte del pensiero processo, ma è ancora necessario per far funzionare il codice). In questo caso, il pensiero è "incrementa la variabile x di 5", non "lascia che x sia il valore di x più 5".

Vi sono altri casi in cui una notazione più breve è dannosa per la leggibilità, ad esempio quando si utilizza un operatore ternario in cui ifun'istruzione sarebbe più appropriata.


11

Per avere un'idea del perché questi operatori sono nelle lingue "C-style" per cominciare, c'è questo estratto da K&R 1st Edition (1978), 34 anni fa:

A parte la concisione, gli operatori di assegnazione hanno il vantaggio di corrispondere meglio al modo di pensare delle persone. Diciamo "aggiungi 2 a i" o "incrementa i di 2", "non" prendi i, aggiungi 2, quindi rimetti il ​​risultato in i ". Quindi i += 2. Inoltre, per un'espressione complicata come

yyval[yypv[p3+p4] + yypv[p1+p2]] += 2

l'operatore di assegnazione semplifica la comprensione del codice, dal momento che il lettore non deve controllare scrupolosamente che due espressioni lunghe siano effettivamente le stesse, o chiedersi perché non lo siano. E un operatore di assegnazione può persino aiutare il compilatore a produrre codice più efficiente.

Penso che sia chiaro da questo passaggio che Brian Kernighan e Dennis Ritchie (K&R), credevano che gli operatori di assegnazione composti aiutassero con la leggibilità del codice.

È passato molto tempo da quando K&R lo ha scritto e molte delle "migliori pratiche" su come le persone dovrebbero scrivere il codice sono cambiate o si sono evolute da allora. Ma questa domanda di programmers.stackexchange è la prima volta che riesco a ricordare qualcuno che ha espresso un reclamo sulla leggibilità delle assegnazioni composte, quindi mi chiedo se molti programmatori trovano che sono un problema? Inoltre, mentre scrivo, la domanda ha 95 voti, quindi forse le persone li trovano stonati quando leggono il codice.


9

Oltre alla leggibilità, in realtà fanno cose diverse: +=non deve valutare il suo operando di sinistra due volte.

Ad esempio, expr = expr + 5evarrebbe exprdue volte (supponendo che exprsia impuro).


Per tutti tranne i compilatori più strani, non importa. La maggior parte dei compilatori è abbastanza intelligente da generare lo stesso binario per expr = expr + 5eexpr += 5
vsz il

7
@vsz Non se exprha effetti collaterali.
Pubblicazione del

6
@vsz: in C, se exprha effetti collaterali, allora expr = expr + 5 deve invocare due volte quegli effetti collaterali.
Keith Thompson,

@Pubby: se ha effetti collaterali, non c'è problema di "convenienza" e "leggibilità", che era il punto della domanda originale.
vsz

2
Meglio stare attenti a quelle dichiarazioni di "effetti collaterali". Legge e scrive come volatileeffetti collaterali x=x+5e x+=5ha gli stessi effetti collaterali quando xèvolatile
MSalters,

6

Oltre agli ovvi meriti che altre persone hanno descritto molto bene, quando hai nomi molto lunghi è più compatto.

  MyVeryVeryVeryVeryVeryLongName += 1;

o

  MyVeryVeryVeryVeryVeryLongName =  MyVeryVeryVeryVeryVeryLongName + 1;

6

È conciso

È molto più breve da digitare. Coinvolge meno operatori. Ha meno superficie e meno opportunità di confusione.

Utilizza un operatore più specifico.

Questo è un esempio inventato e non sono sicuro che i compilatori effettivi lo implementino. x + = y attualmente utilizza un argomento e un operatore e modifica x in posizione. x = x + y potrebbe avere una rappresentazione intermedia di x = z dove z è x + y. Quest'ultimo utilizza due operatori, addizione e assegnazione e una variabile temporanea. Il singolo operatore chiarisce che il lato valore non può essere altro che y e non deve essere interpretato. E teoricamente potrebbe esserci una CPU di fantasia che ha un operatore più-uguale che funziona più velocemente di un operatore più e un operatore di assegnazione in serie.


2
Teoricamente schmeoreticamente. Le ADDistruzioni su molte CPU hanno varianti che funzionano direttamente sui registri o sulla memoria usando altri registri, memoria o costanti come secondo addend. Non tutte le combinazioni sono disponibili (ad es. Aggiungere memoria alla memoria), ma ce ne sono abbastanza per essere utili. Ad ogni modo, qualsiasi compilatore con un ottimizzatore decente saprà generare lo stesso codice x = x + ycome dovrebbe x += y.
Blrfl,

Da qui "inventato".
Mark Canlas,

5

È un bel linguaggio. Se è più veloce o meno dipende dalla lingua. In C, è più veloce perché si traduce in un'istruzione per aumentare la variabile dal lato destro. I linguaggi moderni, inclusi Python, Ruby, C, C ++ e Java supportano tutti la sintassi op =. È compatto e ci si abitua rapidamente. Dal momento che lo vedrai molto nel codice di altre persone (OPC), potresti anche abituarti e usarlo. Ecco cosa succede in un paio di altre lingue.

In Python, la digitazione x += 5causa comunque la creazione dell'oggetto intero 1 (sebbene possa essere disegnato da un pool) e l'orfanotrofio dell'oggetto intero contenente 5.

In Java, si verifica un cast tacito. Prova a digitare

int x = 4;
x = x + 5.2  // This causes a compiler error
x += 5.2     // This is not an error; an implicit cast is done.

Lingue imperative moderne . Nei linguaggi (puri) funzionali x+=5ha lo stesso significato di x=x+5; ad esempio in Haskell quest'ultimo non provoca xun incremento di 5, ma comporta un ciclo di ricorsione infinito. Chi vorrebbe una scorciatoia per quello?
circa il

Non è necessariamente più veloce con i compilatori moderni: anche in C.
HörmannHH,

La velocità +=non dipende tanto dalla lingua quanto dipende dal processore . Ad esempio, X86 è un'architettura a due indirizzi, supporta solo +=nativamente. Una dichiarazione come a = b + c;deve essere compilata come a = b; a += c;perché semplicemente non ci sono istruzioni che possono mettere il risultato dell'aggiunta altrove che nel posto di uno dei riassunti. L'architettura Power, al contrario, è un'architettura a tre indirizzi per la quale non sono disponibili comandi speciali +=. Su questa architettura, le istruzioni a += b;e a = a + b;compilano sempre con lo stesso codice.
cmaster

4

Gli operatori come +=sono molto utili quando si utilizza una variabile come accumulatore , ovvero un totale parziale:

x += 2;
x += 5;
x -= 3;

È molto più facile da leggere rispetto a:

x = x + 2;
x = x + 5;
x = x - 3;

Nel primo caso, concettualmente, stai modificando il valore in x. Nel secondo caso, stai calcolando un nuovo valore e assegnandolo xogni volta. E mentre probabilmente non scriveresti mai un codice così semplice, l'idea rimane la stessa ... l'attenzione è su cosa stai facendo a un valore esistente invece di creare un nuovo valore.


Per me è esattamente l'opposto: la prima variante è come la sporcizia sullo schermo e la seconda è pulita e leggibile.
Mikhail V,

1
Tratti diversi per persone diverse, @MikhailV, ma se sei nuovo nella programmazione potresti cambiare la tua vista dopo un po '.
Caleb,

Non sono così nuovo nella programmazione, penso solo che ti sia semplicemente abituato a + = notazione per molto tempo e quindi puoi leggerlo. Il che inizialmente non rende alcuna sintassi attraente, quindi un operatore + circondato da spazi è oggettivamente più pulito di + = e amici che sono tutti appena distinguibili. Non che la tua risposta sia errata, ma non dovresti fare troppo affidamento sulla tua abitudine facendo dei consumi quanto "sia facile da leggere".
Mikhail V,

La mia sensazione è che si tratti più della differenza concettuale tra accumulare e memorizzare nuovi valori che di rendere l'espressione più compatta. La maggior parte dei linguaggi di programmazione imperativa ha operatori simili, quindi mi sembra di non essere l'unico a trovarlo utile. Ma come ho detto, un colpo diverso per persone diverse. Non usarlo se non ti piace. Se vuoi continuare la discussione, forse Software Engineering Chat sarebbe più appropriato.
Caleb,

1

Considera questo

(some_object[index])->some_other_object[more] += 5

D0 vuoi davvero scrivere

(some_object[index])->some_other_object[more] = (some_object[index])->some_other_object[more] + 5

1

Le altre risposte riguardano i casi più comuni, ma c'è un altro motivo: in alcuni linguaggi di programmazione, può essere sovraccarico; es . Scala .


Lezione di Scala piccola:

var j = 5 #Creates a variable
j += 4    #Compiles

val i = 5 #Creates a constant
i += 4    #Doesn’t compile

Se una classe definisce solo l' +operatore, x+=yè effettivamente una scorciatoia di x=x+y.

Se una classe si sovraccarica +=, tuttavia, non sono:

var a = ""
a += "This works. a now points to a new String."

val b = ""
b += "This doesn’t compile, as b cannot be reassigned."

val c = StringBuffer() #implements +=
c += "This works, as StringBuffer implements “+=(c: String)”."

Inoltre, gli operatori +e +=sono due operatori separati (e non solo questi: + a, ++ a, a ++, a + ba + = b sono anche operatori diversi); nelle lingue in cui è disponibile il sovraccarico dell'operatore ciò potrebbe creare situazioni interessanti. Proprio come descritto sopra - se sovraccarichi l' +operatore per eseguire l'aggiunta, tieni presente che anche questo +=dovrà essere sovraccarico.


"Se una classe definisce solo l'operatore +, x + = y è effettivamente una scorciatoia di x = x + y." Ma sicuramente funziona anche al contrario? In C ++, è molto comune dapprima definire +=e poi definire a+bcome "crea una copia a, mettilo busando +=, restituisci la copia di a".
sinistra circa l'

1

Dillo una volta e una sola volta: in x = x + 1, dico due volte "x".

Ma non scrivere mai, 'a = b + = 1' o dovremo uccidere 10 gattini, 27 topi, un cane e un criceto.


Non dovresti mai cambiare il valore di una variabile, poiché semplifica la dimostrazione del codice corretto - vedi programmazione funzionale. Tuttavia, se lo fai, allora è meglio non dire le cose solo una volta.


"mai cambiare il valore di una variabile" Paradigma funzionale ?
Peter Mortensen,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.