Grammatica di chiusura del trailing genera una nota ambiguità tra un corpo dell'istruzione (nel tuo caso, questo è il ciclo for
, ma si applica anche ad altre istruzioni) e il corpo della chiusura finale. Sebbene sia tecnicamente possibile risolvere questo problema, compiler designers decided to prohibit trailing closure syntax in controlling portions of various high-level statements:
While it would be possible to tell what is intended in some cases by performing arbitrary lookahead or by performing type checking while parsing, these approaches have significant consequences for the architecture for the compiler. As such, we've opted keep the parser simple and disallow this.
Per comprendere la natura del conflitto, considerare questo esempio:
for v in expr { /* code 1 */ } { /* code 2 */ }
Il parser deve fare una scelta riguardo code 1
blocco. Si potrebbe usarlo come una chiusura posteriore della expr
e trattare code 2
come il corpo del ciclo for
, oppure utilizzare code 1
come il corpo del ciclo for
, mentre il trattamento code 2
come un gruppo indipendente di istruzioni racchiuse tra parentesi graffe - un classico shift-reduce conflict .
Risolvere tali conflitti è molto costoso. Essenzialmente, il parser deve continuare a guardare avanti attraverso più token, fino a quando solo un'interpretazione ha senso, o il parser esaurisce i token (nel qual caso prende una decisione arbitraria in un modo o nell'altro, richiedendo ai programmatori di disambiguare il loro programma quando quella scelta non è ciò che volevano).
L'aggiunta di parentesi rimuove l'ambiguità. Proposte sono state considerate per rimuovere l'ambiguità aggiungendo una parola chiave obbligatoria per separare la parte di controllo del loop dal suo corpo, cioè
// The syntax of rejected proposal
for doubled in numbers.map { $0 * 2 } do {
print(doubled) // ^^
}
aggiunta di un extra do
parola "attacca" il blocco di sinistra, se del caso, l'espressione e rende il blocco a destra il corpo dell'istruzione loop. Questo approccio ha un grosso svantaggio, perché è un cambio di rottura. Questo è il motivo per cui questa proposta è stata respinta.
Questo è un elegante trucco. –