Non importa quanto sia restrittiva una lingua, alcuni programmatori troveranno comunque dei modi per rovinare tutto. Immagina il seguente pezzo di codice:
var price = this.ApplyVAT(basePrice);
if (this.acceptsRebate)
{
return new RebateCalculator(RebateType.Default).Transform(price);
}
return price;
Facciamolo a pezzi:
// Rebats calculator became variable cal.
var cal = new RebateCalculator(RebateType.Default);
// stylecop complain if i dont put comment here and leave line empty. don't know why??
//
// don't know price now so later maybe!!!
Price pp = null;
// Func is transforms price to price!
Func<Price, Price> tar = cal.Do;
var g = Tax(bPR);
// changed by MAG 02/08/2013
// if arebt2 is true, the condition should match.....
if (arebt2)
{
// assign g to g2
var g2 = g;
// don't remember what tar mean but its very important!!! don't remove!!!
pp = tar(g);
}
else
{
// it's the same!
pp = g;
}
// i can return now because i know price!!!
return pp;
Il codice è ancora conforme allo stesso IL e non viola alcuna regola di analisi del codice StyleCop o Code (mentre StyleCop è dannatamente severo che ti obbliga a scrivere codice in modo molto preciso). Ma ora è un pezzo di merda, completamente impossibile da lavorare. Come potresti progettare una lingua che dica che quei commenti sono inutili e fastidiosi, che le mie convenzioni sui nomi sono tra le più povere e che le variabili intermedie aggiungono più danni che benefici?
L'uso di Unicode nei nomi è un buon esempio. Nel codice sopra, non ho nemmeno usato Unicode nei nomi delle variabili. [A-Za-z0-9_]
è sufficiente per dare nomi senza senso. D'altra parte, Unicode può essere molto utile per migliorare il codice . Questo pezzo di codice:
const numeric Pi = 3.1415926535897932384626433832795;
numeric firstAlpha = deltaY / deltaX + Pi;
numeric secondAlpha = this.Compute(firstAlpha);
Assert.Equals(math.Infinity, secondAlpha);
è leggibile a sufficienza, ma consentire a Unicode di nominare i nomi può consentire al programmatore di scrivere questo (il problema è che non si è in grado di digitare nomi di variabili su una parola chiave non greca):
const numeric π = 3.1415926535897932384626433832795;
numeric α₁ = Δy / Δx + π;
numeric α₂ = this.Compute(α₁);
Assert.Equals(math.∞, α₂);
Alcuni sviluppatori ritengono che la seconda variante spinga troppo la denominazione, ma potrebbe essere un eccellente miglioramento della leggibilità per alcuni progetti (come un progetto scritto da un team di scienziati).
Parlando di convenzioni di denominazione, non ho visto una singola regola che impedisca effettivamente di dare nomi sfavorevoli alle variabili. Un esempio come il codice sopra può essere prevenuto da una regola simile a:
The names of private variables should contain at least four characters. The names of public variables should contain at least six characters.
Ma questo non impedirà di rinominare pp
in ppppppp
solo per eliminare l'avviso. Una regola aggiuntiva:
The names can't contain a character consecutively repeated more than two times. For example, feed
is a valid name, while feeed
is not.
può anche essere aggirato rinominando la variabile in ppabcde
.
L'obiettivo effettivo
Ciò che è più importante è che un linguaggio di programmazione ben progettato dovrebbe aiutare a evitare errori . Ad esempio:
if (this.isEnabled)
this.PlayVideo();
this.PlaySubtitles();
è un segno che qualcosa è andato storto. Quando vedo che in un codice C #, do la colpa:
-
Il programmatore, perché è molto semplice sempre inserire parentesi graffe, invece di rischiare di perdere migliaia di dollari a causa di uno stupido bug, difficile da rilevare durante le revisioni del codice e per trovare più tardi,
-
Il programmatore, ancora una volta, perché avrebbe dovuto usare strumenti adeguati (StyleCop in questo caso),
-
La lingua, perché tale sintassi avrebbe potuto essere proibita,
-
L'IDE, perché non ha reagito al fatto che il programmatore ha rovinato il rientro.
Conclusione
-
Sii restrittivo quando aiuta a evitare bug e quando la flessibilità della sintassi non è particolarmente utile.
-
Non essere restrittivo solo per aiutare i principianti: troveranno comunque dei modi per rendere il loro codice illeggibile.
-
Aggiungi zucchero sintattico quando aiuta la leggibilità il più delle volte, senza essere usato impropriamente il più delle volte.
Esempio di Python
Se conosci Python, questo è un buon esempio di rigore utile . Le persone che hanno appena iniziato a impararlo sono generalmente negativamente sorprese dalla sua severità:
What? I can't indent the code like I want? This is annoying!
o
There are no switch statements in Python? Are you serious?! Are you telling that I have to use if-elif-else
every time I need a switch?
Alcuni anni dopo, la persona confermerebbe che:
-
Avere un'indentazione significativa è un'idea eccellente, perché impedisce errori sottili (come quello con if
sopra) e riduce lo sforzo di scrivere codice (invece di mettere i punti e virgola e codice di rientro, ti occupi solo di indentazione).
-
Non hanno bisogno di un interruttore, perché in ogni caso sostituiscono condizionalmente il polimorfismo e quando hanno effettivamente bisogno di un meccanismo simile a switch
, un dizionario è una scelta perfetta.