Che cosè lo zucchero sintattico nei linguaggi di programmazione?

La migliore risposta

Lo zucchero sintattico, o zucchero sintattico, è una “scorciatoia” visivamente o logicamente accattivante fornita dal linguaggio, che riduce la quantità di codice che deve essere scritto in alcune situazioni comuni.

Ad esempio, quando si imposta una variabile su un valore che dipende da una condizione, in un linguaggio più semplice con meno “zucchero” si potrebbe fare questo:

int a;

if(SomeFunction() == 2)

a = 4;

else

a = 9;

Questo è un po troppo per unoperazione così semplice; in linguaggi più semplici, gli sviluppatori spesso creavano una funzione “Inline If” per racchiudere questa logica in qualcosa di più conciso:

public T Iif(bool condition, T ifTrue, T ifFalse)

{

if(condition) return ifTrue;

return ifFalse;

}

...

//usage

int a = Iif(SomeFunction() == 2, 4, 9);

Ecco, ora luso effettivo è molto più conciso. Molti linguaggi moderni, incluso C #, incorporano unoperazione come questa direttamente nelle specifiche del linguaggio sotto forma di “operatore condizionale ternario”:

int a = SomeFunction() == 2 ? 4 : 9;

Questo operatore è lo “zucchero di sintassi” fornito dal linguaggio per unoperazione condizionale.

Ora, un sotto-caso comune di questa impostazione di variabile condizionale è che se la nostra prima scelta per un mezzo per produrre un valore per impostare la variabile restituisce null, dovremmo usare mezzi alternativi. Ad esempio:

MyClass theClass = GetMyClass();

if(theClass == null)

theClass = FailSafeMyClassGetter();

Non male, ma su questo possiamo migliorare:

MyClass theClass = GetMyClass() ?? FailSafeMyClassGetter();

Il “??” Loperatore è noto come “operatore di coalescenza nullo” e fondamentalmente produce il primo valore letto da sinistra a destra che non è nullo.

Un altro C # ottenuto di recente era la “proprietà auto”. In breve, C # ha quelle che vengono chiamate “proprietà”; coppie di blocchi di codice che rappresentano un “membro dati” di un oggetto, in grado di eseguire una convalida o una logica di calcolo più complesse di quanto potrebbe fare un semplice campo, ma a cui è possibile accedere come se il membro fosse un campo invece di utilizzare GetX () e SetX () chiamate al metodo, quindi diventa facile differenziare nel codice quando si “riaccede ai dati rispetto allesecuzione di operazioni. È buona pratica in C #, per motivi di coerenza e manutenzione, utilizzare le proprietà invece dei campi quando si implementano membri di dati visibili pubblicamente . Tuttavia, nove volte su dieci, la proprietà “racchiude” solo una variabile di campo privato e quindi, seguendo la best practice, limplementazione della proprietà per un semplice valore di dati potrebbe essere:

private int \_myIntProperty;

public int MyIntProperty

{

get

{

return \_myIntProperty;

}

set

{

\_myIntProperty = value;

}

}

Un po brutto, molto ripetitivo e con molte più righe di codice di quante ne abbiamo realmente bisogno. In passato era allettante rinunciare best practice e usa semplicemente un campo in questi semplici casi, in modo da ridurre la tentazione e leffetto dannoso che può avere sul codice base se in seguito hai deciso di aver davvero bisogno di una proprietà, i progettisti di C # hanno incluso un po di sintassi in C # 3.0 specifica:

public int MyIntProperty { get; set; }

Questa dichiarazione di proprietà viene trattata come la dichiarazione precedente, ma è molto più veloce e più facile scrivere una classe piena di questi piuttosto che farlo alla vecchia maniera, ed è anche molto più facile da mantenere.

Questi sono solo un paio di esempi di “sintassi zuccherina” disponibile in C #. Altri includono:

* Inferenza del tipo di variabile – var someInt = 5; – Il compilatore può determinare il tipo di una variabile locale dichiarata dallassegnazione iniziale, quindi non devi per specificarlo esplicitamente (e quindi cambiarlo se il tipo di cui hai bisogno cambia).

* yield return – Gran parte della programmazione .NET coinvolge raccolte di oggetti e eseguire attività ripetitive su ogni elemento dello stesso. Implementare linterfaccia IEnumerable che consente vari cicli integrati come foreach per gestire literazione nella raccolta. La parola chiave yield return ha semplificato notevolmente questo aspetto, consentendo di definire la logica delliteratore stesso allinterno del metodo GetEnumerator () della raccolta.

* async / await – Allo stesso modo, sempre più attività di programmazione devono essere eseguite “in modo asincrono” dando il lavorare su un altro “thread” dellapplicazione, quindi il lavoro del programma può essere suddiviso tra più processori nel moderno PC, mentre linterfaccia utente dellapplicazione rimane “reattiva” alle richieste del sistema operativo di ridisegnare linterfaccia utente ed eseguire altri compiti visivi. Il concetto di threading non è difficile da capire, ma fino a C # 4.0 richiedeva essenzialmente di dividere il metodo in due; un metodo avvia loperazione asincrona, quindi viene chiamato un secondo quando il thread in background ha terminato il lavoro. Non più; queste due nuove parole chiave consentono di definire una funzione che svolge un lavoro asincrono in modo molto sincrono, mentre il compilatore divide i metodi dietro le quinte durante la creazione del codice.

Risposta

Non esiste una definizione formale di zucchero sintattico, questa è una nozione nebulosa.

Lo zucchero sintattico nella sua definizione più accettata è una sintassi extra che viene immediatamente tradotta in una forma più primitiva e ingombrante dal compilatore ma consente unesperienza “più dolce” per il programmatore nellesprimere alcune istruzioni comuni.

Il problema con questa definizione è che la sintassi “extra” non è una descrizione molto significativa. In alcuni casi è abbastanza chiaro che abbiamo zucchero sintattico, per esempio il rapporto sul linguaggio Haskell definisce esplicitamente determinati elementi sintattici (blocchi di do e comprensioni di lista) mediante la loro traduzione in una sintassi più semplice. Questo è un caso abbastanza chiaro di zucchero sintattico, esistono solo per facilitare la scrittura di un programma, non in senso profondo nella traduzione del programma da parte del compilatore in un albero simbolico.

In altri casi, è molto meno chiaro perché il linguaggio non si preoccupa di questo tipo di formalizzazione, per esempio i decoratori in Python sono spesso descritti da come scriveresti il ​​codice equivalente senza di loro ma per quanto ne so non è mai detto esplicitamente: “tu non dovresti compilare i decoratori direttamente nella tua rappresentazione intermedia ma piuttosto tradurli in questo modo in anticipo ”. Alcune implementazioni di Python potrebbero scegliere di fare proprio questo, ma altre potrebbero aver aggiunto decoratori come caratteristica della loro rappresentazione intermedia.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *