Punto e virgola opzionale


10

Molto spesso, in un linguaggio imperativo di uso generale, sono richiesti punti e virgola come delimitatori di istruzioni o completamente non consentiti (ad esempio C e Python).

Tuttavia, alcune lingue, come JavaScript, ti consentono di rinunciare a delimitare le tue dichiarazioni con punti e virgola, a favore di altri delimitatori (come una nuova riga).

Quali sono le decisioni di progettazione alla base di questo? Capisco che i punti e virgola sono essenziali quando si scrivono più istruzioni sulla stessa riga, ma c'è un altro motivo per renderle obbligatorie (tranne che dopo la C)?


1
Devi pensare ai terminatori di istruzioni (perl, c) e ai delimitatori di istruzioni (javascript, pascal).

5
In Python, i punti e virgola possono essere usati per separare più istruzioni sulla stessa riga. E poiché è consentita un'istruzione "vuota", i punti e virgola possono essere utilizzati alla fine della maggior parte delle istruzioni.
Greg Hewgill,

1
I understand that semicolons are essential when writing multiple statements on the same line- Dipende dalla lingua. Il mio preferito non ha affatto delimitatori del genere, la prossima istruzione inizia quando tutti gli argomenti della funzione sono stati esauriti.
Izkata,

1
@MichaelT: Non credo che le tue classificazioni siano corrette: Perl appartiene probabilmente a entrambi i gruppi e JavaScript è effettivamente nel campo "terminatori di istruzioni" (poiché le implementazioni sono necessarie per inferire un punto e virgola prima }o alla fine del file).
Ruakh

Sì, dipende assolutamente dalla lingua. La mia ipotesi personale sarebbe che i punti e virgola siano solo una sorta di convenzione concordata, che la maggior parte dei progettisti di lingue segue. Almeno ha un senso dal punto di vista del linguaggio più naturale. Lo stesso con {e} per i blocchi, a proposito: sono usati da molte lingue, tuttavia non tutte e in realtà non devi farlo. Non esiste una ragione universale dietro questo.
JensG,

Risposte:


24

Renderli obbligatori (o impedirli completamente) riduce il numero di casi angolari, elimina una potenziale fonte di bug oscuri e semplifica il design del compilatore / interprete.

I progettisti linguistici che hanno scelto di renderli opzionali hanno scelto di convivere con l'ambiguità in cambio di una maggiore flessibilità sintattica.


7
@RobertHarvey Heretic! Dovrebbe esserci un modo ovvio per farlo e solo uno. Per inciso, c'è solo un modo per farlo in perl.

1
A proposito: alcune lingue hanno una buona dose di ridondanza nelle grammatiche in generale, quindi rendere facoltativo il punto e virgola è solo occasionalmente ambiguo nella pratica. Detto questo, penso che il punto e virgola sia un po 'di ridondanza sbagliata da rilasciare - mi piace abbastanza Haskell in cui invece rilasciate le parentesi e le virgole per gli argomenti. OK, puoi anche eliminare il punto e virgola in Haskell, ma non è esattamente la stessa cosa di Javascript.
Steve314,

2
IIRC il problema è che non si adattano al modello formale ma che i generatori di parser non producono buoni messaggi di errore. Cioè hanno una conoscenza limitata degli errori comuni mentre il parser scritto a mano può ottenere un messaggio di errore molto più utile. Gcc, ad esempio, usava il bisonte per la grammatica C. Allo stesso modo, il problema è che i "casi limite" non sono casi limite formali, ma quelli morbidi - vale a dire che per parser l'AST è chiaro e per l'uomo l'AST è "chiaro" ma non sono d'accordo su come sia l'AST.
Maciej Piechotka,

2
@Maciej Piechotka - Non intendevo implicare che le parentesi fossero opzionali in Haskell. Sto parlando di abbandonare qualcosa di ridondante come decisione di progettazione del linguaggio. Il punto è che non usi parentesi o virgole per una chiamata di funzione in Haskell. È possibile passare una tupla come argomento, ma questo è ancora la sintassi per una tupla, non per il passaggio di argomenti. Haskell (e ML e altri) "lasciarono cadere" le parentesi e le virgole per argomenti di funzione, nel senso che esiste questa convenzione comune in altre lingue (da Algol?), Ma Haskell non lo fa.
Steve314,

1
@Maciej Piechotka - Ovviamente non è mai stata una vera e propria convenzione universale - solo perché le lingue della famiglia Algol non significano che altre lingue si definiscano relative a ciò, quindi la mia affermazione "abbandonata" è sbagliata in questo senso - ma con tutto le lingue della famiglia C in questi giorni sembra un po 'così.
Steve314,

15

JavaScript ci ha mostrato che questa è una pessima idea. Per esempio:

return
0;

In C, questo restituisce un valore di 0. In JavaScript, questo ritorna undefinedperché un punto e virgola viene inserito dopo l'istruzione return, e non è immediatamente ovvio il motivo per cui il tuo codice si rompe a meno che non ti capiti di conoscere i dettagli dell'inserimento automatico del punto e virgola.


1
@delnan: Python non è progettato per assomigliare a C. È noto per essere basato sul rientro e quindi fortemente orientato alla linea e non richiede punti e virgola. JavaScript tecnicamente non richiedere loro; ne sta inserendo uno quando ne trova uno mancante, che trasforma ciò che assomiglia a un'istruzione sintatticamente valida in due istruzioni distinte con semantica completamente diversa.
Mason Wheeler,

7
Non è una cattiva idea, è solo fonte di confusione per le persone che cercano di usare JavaScript senza preoccuparsi di imparare a inserire automaticamente il punto e virgola . Forse invece di dire "questa è una pessima idea" potresti dire con maggiore precisione "rendere facoltativi i punti e virgola introduce insidie ​​per i programmatori che non escono e apprendono tutti i dettagli".
TehShrike,

4
@delnan: il motivo per cui è sorprendente è che JavaScript di solito non inserisce un punto e virgola alla fine di una riga, tranne per correggere un programma altrimenti non valido. After returnè uno dei pochi casi in cui JavaScript inserirà un punto e virgola anche se il programma sarebbe valido senza di esso. (Ma ovviamente, questo mina il punto di Mason Wheeler. Il problema non è che i punti e virgola sono opzionali, è che le regole sono incoerenti.)
ruakh

6
@TehShrike: Rendere i punti e virgola facoltativi introduce insidie ​​per tutti i programmatori, perché interpreta arbitrariamente i refusi invece di chiederti cosa intendevi. Tutti fanno un refuso di tanto in tanto.
Jan Hudec,

1
javascript ha dimostrato che la sua implementazione di punti e virgola facoltativi è difettosa. Non mostra che i punti e virgola opzionali sono di per sé cattivi.
CodesInChaos

4

Semplifica in qualche modo la grammatica e il parser per rendere obbligatori i punti e virgola. In sostanza, consente al lexer di scaricare tutto lo spazio bianco, comprese le nuove righe, e il parser non deve preoccuparsene affatto.

D'altra parte, una volta che inizi a voler dire al parser dello spazio bianco, non è così difficile rendere facoltativi i punti e virgola. Spesso puoi semplicemente raggrupparli insieme con un whitespacetoken e il tuo parser può gestirlo bene.

Ad esempio, prova a inserire i punti e virgola nelle seguenti serie di istruzioni C.

functionCall(3, 4) 9 + (3 / 8) variable++ while(1) { printf("Hello, world\n") }

Mentre ci sono alcune cose strane che non puoi più fare, come while(1);, per la maggior parte, è relativamente facile con le moderne tecniche di analisi determinare dove finiscono le dichiarazioni senza un delimitatore specifico. Anche se vuoi ancora consentire le cose strane, non è così difficile creare un newline_or_semicolonnon terminale.


Quando C è stato originariamente sviluppato nei primi anni '70, per semplificare i compilatori erano necessari terminatori di istruzioni. A metà degli anni '90, quando è stato sviluppato Javascript, era meno preoccupante.
Sean McSomething,

3

I punti e virgola sono utili in una grammatica per 2 motivi. In primo luogo, ti consente di dividere lunghe affermazioni in più righe senza avere caratteri di continuazione divina (sto parlando di te, Fortran e Basic). In secondo luogo, consente al parser di avere un modo per "smettere" di analizzare quando la sintassi viene davvero contorta a causa di un errore di battitura. Rubando dall'esempio di Karl Bielefeldt,

functionCall(3, 4) 9 + (3 / 8) variable++ while(1) { printf("Hello, world\n") }

immagina di aver digitato una parentesi aperta extra:

functionCall((3, 4) 9 + (3 / 8) variable++ while(1) { printf("Hello, world\n") }

ora dov'è l'errore? Se hai il punto e virgola, è più facile per il parser rinunciare al primo punto e virgola. Potrebbe anche continuare ad analizzare dopo il punto e virgola se lo desiderasse.

functionCall((3, 4);  <- something is wrong here. emit error and keep going.
                      9 + (3 / 8); variable++; while(1) { printf("Hello, world\n"); }

Ora è più facile per il parser segnalare un errore e individuare più facilmente la riga / colonna in cui si è verificato.


1
Fortran e Basic almeno hanno scelto decentemente marcatori di continuazione della linea (& e _, rispettivamente). Per puro "" OMG, cosa stavano pensando ", niente batte FoxPro. Per continuare una linea, hai usato un punto e virgola.
DougM

2

I punti e virgola non sono sempre tutto o niente come quelli menzionati nella tua domanda. Ad esempio, la grammatica di Lua è attentamente progettata per essere in forma libera (tutti gli spazi bianchi, comprese le nuove righe, possono essere ignorati) ma anche senza la necessità di usare punti e virgola. Ad esempio, i seguenti programmi sono equivalenti:

--One statement per line
x = 1
y = 2

--Multiple statements per line
x = 1 y = 2

--You can add semicolons if you want but its just for clarity:
x = 1; y = 2

0

A parte il design e la costruzione, credo che molti programmatori provengano da ambienti diversi e alcuni hanno imparato a usare il punto e virgola e altri no. Molte nuove lingue che stanno emergendo non richiedono un punto e virgola, ma permettono comunque che esista. Penso che potrebbe essere solo un modo per far sì che più programmatori imparino come programmare in queste nuove lingue senza dover rinunciare alle loro abitudini da quando hanno iniziato.

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.