Qual è la differenza tra "Sintassi" e "Zucchero sintattico"

45

Sfondo

La pagina di Wikipedia su Syntactic Sugar afferma:

In computer science, syntactic sugar is syntax within a programming language that is designed to make things easier to read or to express. It makes the language "sweeter" for humans to use: things can be expressed more clearly, more concisely, or in an alternative style that some may prefer.

Non capisco veramente quale sia la differenza tra Syntactic Sugar e Syntax.

Apprezzo il fatto che la versione zuccherina possa essere più chiara, più concisa, magari rimandare qualche piatto d'acciaio. Ma mi sento a un certo livello, tutta la sintassi sta essenzialmente facendo ciò per formare un'astrazione su ciò che il codice viene compilato.

Dalla stessa pagina di Wikipedia:

Language processors, including compilers, static analyzers, and the like, often expand sugared constructs into more fundamental constructs before processing, a process sometimes called "desugaring".

Come esercizio di pensiero, se prendo "spesso" in questa affermazione per significare "sempre": se la differenza fosse solo se il compilatore "desugars" la sintassi prima di passare a una fase successiva, come potrebbe un programmatore che non sapere che le componenti del compilatore sanno (o si preoccupano) cosa è la Sintassi di Sugar o no?

Una domanda molto correlata su questo sito "Definizione rigorosa dello zucchero sintattico?" ha una risposta che inizia:

IMHO I don't think you can have a definition for syntactic sugar, because the phrase is BS and is likely to be used by people that talk about "real programmers" using "real tools" on "real operating systems"

Quale potrebbe indicare che forse non c'è un'enorme differenza per il programmatore che usa la lingua? Forse la differenza è percepibile solo dallo scrittore di compilatori? Anche se ci possono essere casi in cui è utile per il programmatore usare la lingua per sapere cosa c'è sotto il cofano di Syntactic Sugar? (Ma forse in realtà qualsiasi discorso sull'argomento tende a usare il termine come esca di fiamma?)

Il cuore della domanda

Quindi ... la versione breve della domanda:

  • C'è una vera differenza tra sintassi e zucchero sintattico?
  • A chi importa?

Cibo extra per il pensiero

Bonus sulla contraddizione dell'argomento:

Sulla pagina di Wikipedia è riportato un esempio:

For instance, in the C language the a[i] notation is syntactic sugar for *(a + i)

Mentre un'altra risposta sulla domanda collegata sopra parla dello stesso esempio:

Now consider a[i] == *(a + i). Think about any C program that uses arrays in any substantive way.

E riassume ciò:

The [] notation facilitates this abstraction. It's not syntactic sugar.

La conclusione opposta per lo stesso esempio!

    
posta Don Vince 05.04.2013 - 15:14
fonte

9 risposte

34

La differenza principale è che la sintassi è definita dalla grammatica in una lingua per consentire l'esposizione di alcune funzionalità. Non appena si arriva a quella funzionalità, qualsiasi sintassi altra che consente di fare la stessa cosa è considerata zucchero. Ovviamente, ciò si verifica in strani scenari riguardo a quale delle due sintassi è lo zucchero, soprattutto perché non è sempre chiaro quale sia il primo risultato.

In pratica, lo zucchero sintattico viene usato solo per descrivere la sintassi aggiunta a una lingua per facilitare la facilità d'uso, come ad esempio la creazione di infissi lhs + rhs map a lhs.Add(rhs) . Prenderò in considerazione l'indicizzazione degli array di C come zucchero sintattico.

È importante soprattutto perché i design eleganti tendono a limitare la quantità di duplicati. Avere (o almeno volere) lo zucchero sintattico è visto da alcuni come un segno di un fallimento del design.

    
risposta data 05.04.2013 - 15:36
fonte
10

La sintassi è ciò che un elaboratore di linguaggio usa per capire cosa significano i costrutti di una lingua. Anche i costrutti considerati zucchero sintattico devono essere interpretati dal processore del linguaggio e quindi fanno parte della sintassi di un linguaggio.

Ciò che distingue lo zucchero sintattico dal resto della sintassi di una lingua è che sarebbe possibile rimuovere lo zucchero sintattico dalla lingua senza influire sui programmi che possono essere scritti nella lingua.

Per dare una definizione più formale, direi

Syntactic sugar are those parts of a language's syntax whose effects are defined in terms of other syntax constructs in the language.

Questo non significa in alcun modo denigrare lo zucchero sintattico, o le lingue che lo hanno, perché l'uso dello zucchero sintattico spesso porta a programmi il cui intento è più comprensibile.

    
risposta data 05.04.2013 - 15:35
fonte
6

Le altre risposte non hanno menzionato un concetto chiave: sintassi astratta ; senza di essa, il termine "zucchero sintattico" non ha alcun senso.

La sintassi astratta definisce gli elementi e la struttura dei linguaggi e come le frasi di quella lingua possono essere combinate per costruire frasi più grandi. La sintassi astratta è indipendente dalla sintassi concreta. Il termine "zucchero sintattico", a quanto ho capito, si riferisce alla sintassi concreta.

In generale, quando si progetta una lingua, si vorrà creare una sintassi concreta per ogni termine della sintassi astratta, in modo che le persone possano scrivere codice nella propria lingua usando testo normale.

Ora diciamo che crei una sintassi concreta e imbarazzante per foo . Gli utenti si lamentano e tu implementi una nuova sintassi concreta per rappresentare la stessa sintassi astratta . Il risultato è che la sintassi e la semantica astratte non sono cambiate, ma ora hai due sintassi concrete per lo stesso termine sintattico astratto.

Questo, credo, è ciò che le persone intendono quando dicono "zucchero sintattico" - cambiamenti che riguardano solo la sintassi concreta, ma che non influiscono sulla sintassi o sulla semantica astratta.

E quindi la differenza tra "zucchero sintattico" e "sintassi concreta" è ora chiara. Per me. :)

Questa interpretazione aiuta anche a spiegare che cosa avrebbe potuto volere Alan Perlis quando ha detto "lo zucchero sintattico causa il cancro del punto e virgola": tutto lo zucchero sintattico concreto nel mondo non può correggere una sintassi astratta debole e tutto lo sforzo che si spende aggiungendo quello zucchero è uno sforzo che non stai affrontando con il vero problema: la sintassi astratta.

Dovrei anche notare che questa è solo la mia opinione; Lo credo solo perché è l'unica interpretazione che riesco a pensare che abbia senso per me.

    
risposta data 05.04.2013 - 17:05
fonte
4

Lo zucchero sintattico è un sottoinsieme della sintassi delle lingue. L'idea di base è che esiste più di un modo per dire la stessa cosa.

Ciò che rende difficile dire quali pezzi sono zucchero sintattico e quali pezzi sono "pura sintassi" sono affermazioni come "è difficile dire quale forma è venuta prima" o "è difficile sapere da che parte l'autore della lingua intesa "o" è in qualche modo arbitrario decidere quale forma è più semplice ".

Ciò che lo rende facile per decidere quali pezzi sono puri o zuccherini è quello di porre la domanda all'interno del frame di uno specifico compilatore o interprete. La pura sintassi è la roba che un compilatore converte direttamente in codice macchina o che l'interprete risponde direttamente. Lo zucchero è la roba che prima viene trasformata in un'altra roba di sintassi prima che accadano queste cose dirette. A seconda dell'implementazione, questo può o non può essere lo stesso di quello che l'autore ha inteso o anche quello che afferma la lingua specifica.

In pratica, questo è il modo in cui viene decisa la realtà della questione.

    
risposta data 06.04.2013 - 01:43
fonte
3

In realtà, la tua prima citazione da Wikipedia dice tutto ... "rende le cose più facili da leggere ...", ".... più dolce da usare per gli umani ....".

Per iscritto, le forme abbreviate come "do not" o "have not" potrebbero essere considerate zucchero sintattico.

    
risposta data 05.04.2013 - 17:14
fonte
3

Normalmente lo zucchero di sintassi è la parte del linguaggio che può essere espressa dalla parte esistente del linguaggio (sintassi) senza perdita di generalità, ma con una possibile perdita di chiarezza. A volte i compilatori hanno una fase di desugaring esplicita che trasforma l'AST creato dal codice sorgente e applica semplici passaggi per rimuovere i nodi corrispondenti allo zucchero.

Ad esempio Haskell ha zucchero di sintassi per le monadi con le seguenti regole applicate in modo ricorsivo

do { f }            ~> f
do { g; h }         ~> g >> do h
do { x <- f; h }    ~> f >>= \x -> do h
do { let x = f; h } ~> let x = f in do h

In questo momento non importa cosa significhi esattamente - tuttavia è possibile vedere che la sintassi speciale su LHS può essere trasformata in qualcosa di più basilare su RHS (vale a dire applicazioni di funzione, lambdas e let ). Questa procedura consente di mantenere il meglio di entrambi i mondi:

  1. La sintassi su LHS è più semplice per programmatore (sintassi sugar) che esprime le idee esistenti in modo più chiaro
  2. Tuttavia, poiché il supporto nel compilatore per i costrutti RHS esiste già nel compilatore, non è necessario trattarlo come qualcosa di speciale al di fuori del parser e del desugaring (tranne che per la segnalazione degli errori).

Analogamente in C puoi immaginare una regola di riscrittura di tipo desugaring (a causa dell'overloading dell'operatore, ecc. non è vero per C ++):

f->h ~> (*f).h
f[h] ~> *(f + h)

Potresti immaginare di scrivere tutti i programmi senza usare -> o [] in C che usano questa costruzione oggi. Tuttavia sarebbe più difficile per i programmatori utilizzarlo, quindi fornire lo zucchero di sintassi (credo che negli anni '70 potrebbe essere un lavoro semplificato anche per i compilatori). È forse meno chiaro in quanto tecnicamente puoi aggiungere la seguente regola di riscrittura perfettamente valida:

*f ~> f[0] -- * and [] have the same expressiveness 

Lo zucchero di sintassi è cattivo? Non necessariamente - c'è il pericolo che venga usato come culto cargo senza comprendere un significato più profondo. Ad esempio, le seguenti funzioni sono equivalenti in Haskell, ma molti principianti potrebbero scrivere il primo modulo senza capire che stanno sfruttando troppo zucchero sintattico:

f1 = do x <- doSomething
        return x
f2 = doSomething

Inoltre lo zucchero della sintassi potrebbe complicare eccessivamente la lingua o essere troppo ristretto per consentire un codice idiomatico generalizzato. Inoltre potrebbe significare che il linguaggio non è abbastanza potente per fare certe cose facilmente - potrebbe essere di progettazione (non dare agli sviluppatori strumenti taglienti o linguaggio di nicchia molto specifico che aggiungere un costrutto più potente danneggerebbe altri obiettivi) o per omissione - quest'ultimo la forma ha dato alla sintassi lo zucchero del brutto nome. Se il linguaggio è abbastanza potente da usare altri costrutti senza aggiungere lo zucchero di sintassi, è considerato più elegante da usare.

    
risposta data 05.04.2013 - 22:20
fonte
3

Penso che l'esempio più ovvio sarebbe la sintassi "+=" in C.

i = i + 1;

e

 i +=  1;

fare esattamente la stessa cosa e compilare esattamente lo stesso insieme di istruzioni della macchina. Il secondo modulo salva un paio di caratteri digitando, ma, soprattutto, rende molto chiaro che stai modificando un valore in base al suo valore corrente.

Stavo per citare l'operatore post / prefisso "++" come l'esempio canonico, ma mi sono reso conto che questo era più che zucchero sintattico. Non c'è modo di esprimere la differenza tra ++ i e i ++ in una singola espressione usando la sintassi i = i + 1 .

    
risposta data 16.12.2013 - 02:25
fonte
1

In primo luogo, affronterò alcune delle altre risposte con un esempio concreto. Il ciclo basato su C ++ 11 per loop (molto simile a foreach loop in varie altre lingue)

for (auto value : container) {
    do_something_with(value);
}

è esattamente equivalente a (cioè, una versione zuccherata di)

for (auto iterator = begin(container); iterator != end(container); ++iterator) {
    do_something_with(*iterator);
}

Ora, nonostante non aggiunga nuova sintassi o semantica astratta al linguaggio, ha una vera utilità.

La prima versione rende esplicito l'intento (visitando ogni elemento in un contenitore). Inoltre, proibisce comportamenti insoliti, come la modifica del contenitore durante l'attraversamento, o l'ulteriore avanzamento di iterator nel corpo del loop, oppure il tentativo di ottenere le condizioni del loop sottilmente errate. Questo evita possibili fonti di bug e, così facendo, riduce la difficoltà di leggere e ragionare sul codice.

Ad esempio, un errore di un carattere nella seconda versione:

for (auto iterator = begin(container); iterator <= end(container); ++iterator) {
    do_something_with(*iterator);
}

fornisce un errore one-past-end e un comportamento indefinito.

Quindi, la versione zuccherata è utile proprio perché è più restrittiva, e quindi più semplice da fidarsi di & capire.

Secondo, alla domanda originale:

Is there a real difference between Syntax and Syntactic Sugar?

No, lo "zucchero sintattico" è sintassi del linguaggio (concreto), considerato "zucchero" perché non estende la sintassi astratta o la funzionalità di base del linguaggio. Mi piace la risposta di Matt Fenwick su questo.

Who does it matter to?

È importante per gli utenti del linguaggio, così come qualsiasi altra sintassi, e in quello zucchero viene fornito per supportare (e in un certo senso benedire) specifici idiomi.

Infine, nella domanda bonus

The [] notation facilitates this abstraction.

questo suona molto simile alla definizione dello zucchero sintattico: supporta (e fornisce la benedizione degli autori del linguaggio per) usando i puntatori come array. La forma p[i] non è realmente più restrittiva di *(p+i) , quindi l'unica differenza è la chiara comunicazione di intenti (e un leggero guadagno di leggibilità).

    
risposta data 05.04.2013 - 17:32
fonte
0

Qualunque fosse la connotazione originale della frase, oggigiorno è principalmente un peggiorativo, quasi sempre formulato come "giusto" o "solo" zucchero sintattico. Praticamente interessa solo ai programmatori che amano fare le cose in modo illeggibile e vogliono un modo conciso per giustificarlo ai loro colleghi. Una definizione da parte di coloro che usano principalmente il termine oggi, dal loro punto di vista, sarebbe qualcosa di simile:

Syntax that is redundant with other more widely applicable syntax, in order to provide a crutch for programmers who don't really understand the language.

Ecco perché ottieni due conclusioni opposte per lo stesso elemento sintattico. Il tuo primo esempio sulla notazione degli array sta usando il significato positivo originale del termine, qualcosa di simile alla risposta di Bart. Il secondo esempio consiste nel difendere la notazione dell'array contro l'accusa di essere zucchero sintattico in senso peggiorativo. In altre parole, sta sostenendo che la sintassi è un'astrazione utile piuttosto che una stampella.

    
risposta data 05.04.2013 - 16:49
fonte

Leggi altre domande sui tag