Perché le istruzioni in molti linguaggi di programmazione sono terminate da punti e virgola?

130

C'è una ragione per cui un punto e virgola è stato scelto come terminatore di riga invece di un simbolo diverso?

Voglio conoscere la storia di questa decisione e spero che le risposte porteranno a intuizioni che potrebbero influenzare le decisioni future.

    
posta A Coder 13.03.2012 - 10:37
fonte

14 risposte

130

In inglese il punto e virgola viene utilizzato per separare gli elementi in un elenco di istruzioni, ad esempio

She saw three men: Jamie, who came from New Zealand; John, the milkman's son; and George, a gaunt kind of man.

Quando si programma la separazione di un numero di istruzioni e l'utilizzo di un punto completo potrebbe essere facilmente confuso per un punto decimale. L'uso del punto e virgola fornisce un metodo facile da analizzare per separare le singole istruzioni del programma pur rimanendo vicino alla normale punteggiatura inglese.

Modifica per aggiungere
All'inizio, quando la memoria era costosa, l'elaborazione era lenta e venivano elaborati i primi linguaggi di programmazione, era necessario suddividere il programma in istruzioni separate per l'elaborazione. Alcune lingue richiedevano che ogni istruzione fosse posizionata su una riga in modo che il ritorno a capo potesse agire come delimitatore di istruzioni. Altre lingue consentivano un formato più libero per il layout del testo e quindi richiedevano uno specifico carattere di delimitazione. Questo personaggio è stato scelto per essere il punto e virgola, molto probabilmente a causa della somiglianza con il suo uso nella lingua inglese (questa deve essere una supposizione, io non ero lì al momento) e come non produrre un conflitto con gli altri segni di punteggiatura e simboli che sono stati richiesti per scopi matematici o altri scopi sintattici.

Modifica di nuovo
La necessità di un carattere di terminatore risale ai requisiti per l'analisi del testo della lingua. I primi compilatori sono stati scritti in linguaggio assembly o, in alcuni casi, direttamente nelle istruzioni della macchina binaria. Avere un carattere speciale che identifica la fine della frase e delimitare il pezzo di testo che viene elaborato rende l'elaborazione molto più semplice. Come ho detto sopra, altre lingue hanno utilizzato il ritorno a capo o le parentesi. L'alfabeto Algol, Pascal, Ada, BCPL, B, C, PL / M e altre famiglie di lingue utilizzano il punto e virgola. Per quanto riguarda quale sia stato il primo a usare questo particolare personaggio, non torno indietro abbastanza nella storia da ricordare. La sua scelta e adozione ha perfettamente senso come

  • Il suo uso rispecchia l'uso nella normale punteggiatura inglese.
  • Altri caratteri (ad esempio il punto) potrebbero confondere poiché hanno già un uso comune (un punto completo viene anche utilizzato come punto decimale).
  • Un carattere di punteggiatura visibile consente il layout del codice di formato gratuito.
  • L'utilizzo di un simile carattere di delimitatore in derivata o in lingue successive si basa sulla familiarità acquisita da tutti i programmatori che hanno utilizzato la lingua precedente.

Come ultima osservazione, penso che ci sia stato più tempo da dedicare a queste risposte e commenti di quanto è stato speso nel decidere di usare il punto e virgola per terminare una dichiarazione quando si progettava la prima lingua che l'ha usata in questo modo.

    
risposta data 13.03.2012 - 10:48
fonte
70

Molte lingue usano la sintassi che viene modellata dopo C (che è stata modellata dopo B - grazie a @Crollster ). Come si può vedere nei commenti, c'è una lunga catena di questi linguaggi ... B è stato ispirato da PL / I, che è stato preceduto da ALGOL nell'usare ; come separatore.

Poiché in C il terminatore dell'istruzione è ; , queste lingue seguono l'esempio.

Per quanto riguarda il motivo per cui è stato selezionato come terminatore di un'istruzione in C - probabilmente a causa del suo uso in inglese "per indicare dichiarazioni interdipendenti" .

C è stato anche inventato sul PDP-11 in un momento in cui c'era una quantità limitata di memoria disponibile per i set di caratteri, quindi gli inventori delle lingue dovevano lavorare all'interno di questi limiti.

    
risposta data 13.03.2012 - 10:42
fonte
54

FORTRAN usato carriage return per delineare le dichiarazioni. COBOL periodo usato. LISP non ha usato nulla, basandosi su parentesi per tutto. ALGOL è stata la prima lingua a utilizzare il punto e virgola per separare le istruzioni. PASCAL ha seguito il lead di ALGOL, utilizzando il punto e virgola per separare le istruzioni.

PL / I ha usato il punto e virgola per terminare le dichiarazioni. C'è una differenza, ed è facilmente visibile in PASCAL. Ada ha seguito il comando di PL / I per questo articolo, piuttosto che per ALGOL.

Il punto e virgola come separatore di istruzioni o terminatore è stato rapidamente accettato dalla comunità di informatica come notazione utile e, per quanto ne so, ogni successivo linguaggio strutturato a blocchi ha seguito il comando di ALGOL e utilizzato il punto e virgola per separare o terminare le affermazioni.

Mi è stato detto molti anni fa che BCPL usava sia il ritorno a capo AND come separatori / terminatori di istruzioni, ma non ho mai usato il linguaggio da solo e non sono in grado di verificarlo. A un certo punto, l'uso del ritorno a capo per separare o terminare le dichiarazioni è stato eliminato dai discendenti di BCPL. BCPL generò B, B generò C, C generò C ++, Java, D e tutta una serie di cose considerevolmente meno ponderate di PASCAL e Ada.

    
risposta data 13.03.2012 - 15:50
fonte
14

Why not any other symbol?

Alcune lingue hanno usato altri simboli - le vecchie versioni di BASIC usavano invece i due punti, per un esempio.

Ignorando le poche eccezioni, tuttavia, penso che ci siano due ragioni principali. Il primo è che stai semplicemente cercando qualcosa di non ambiguo. In un parser tipico, se si verifica un errore abbastanza grave che non è possibile continuare a eseguire il parsing dell'istruzione corrente, si tenta in genere di riportare il parser in sincronia semplicemente ignorando il terminatore dell'istruzione e riavviare il parser dal inizio della prossima dichiarazione. Per questo, vuoi qualcosa che normalmente non si verificherà in nessun'altra parte del codice, e un punto e virgola è un simbolo con poco altro significato allegato, quindi è abbastanza facile dedicare a questo scopo.

La seconda ragione è in qualche modo simile, ma mirava più verso le persone che leggono / usano il codice. Di nuovo, torna al fatto che il vero simbolo che usi non ha molta importanza. C'è un vantaggio sostanziale nella leggibilità per ottenere dall'uso del simbolo che il tuo lettore è abituato a vedere per uno scopo particolare, quando e se possibile. Ciò non significa che C sia l'unica sintassi perfetta e tutto il resto dovrebbe seguirlo pedissequamente, ma vuol dire che abbastanza persone hanno familiarità con quello stile di sintassi che un linguaggio vagamente simile guadagna molto (e perde molto poco) seguendo più o meno la stessa sintassi dove può.

Vorrei notare che questo è molto simile alla progettazione di quasi tutti gli altri programmi. Se scrivo un programma che utilizza finestre di qualche tipo, cercherò di utilizzare solo le funzionalità native delle piattaforme di destinazione. Molte delle decisioni che incorporano saranno in gran parte arbitrarie e potrebbero essere fatte in modo diverso senza alcuna perdita di funzionalità, ma allo stesso modo, cambiandole senza un sostanziale guadagno in funzionalità confondono semplicemente gli utenti senza realizzare nulla di utile. Gli stessi principi di base si applicano a "cosa dovrebbe terminare (o separare) le affermazioni in una lingua?" come "come dovrebbe apparire una barra di scorrimento" o "come dovrebbe funzionare un albero di controllo?" In tutti questi casi, la decisione è per lo più arbitraria e l'uniformità offre un vantaggio sostanziale in sé e per sé.

Aggiungo che più o meno lo stesso accade in molte lingue, proprio nel modo in cui molti di noi sono così abituati a programmare prima che poche persone ci pensano. Perché tutti usano "+" per indicare l'aggiunta, o "-" per indicare la sottrazione? Perché la forma del simbolo non ha molta importanza, ma tutti sono d'accordo nell'applicare lo stesso significato a ciascun simbolo. Molto importante.

    
risposta data 13.03.2012 - 16:47
fonte
7

Il punto e virgola era stato originariamente proposto in Algol 60 come istruzione separatore , non come terminatore.

Prima di Algol 60, l'unico linguaggio di programmazione di alto livello esistente era Fortran, che richiedeva che ogni istruzione fosse su una riga separata. Le dichiarazioni che abbracciavano più righe, come i do-loops, erano considerate una stranezza e venivano considerate come "blocchi di istruzioni".

I progettisti di Algol 60 si sono resi conto che le dichiarazioni avevano bisogno di una struttura gerarchica (se-then-else, do-loops, case statement ecc.) e potevano essere annidate l'una dentro l'altra. Quindi, l'idea di ogni affermazione seduta su una linea separata non aveva più senso. Composizione sequenziale delle dichiarazioni del modulo S1; S2; ...; Sn opzionalmente racchiuso tra parentesi begin - end è stato chiamato dichiarazioni composte e si inserisce nella struttura gerarchica delle dichiarazioni previste da Algol 60. Quindi, qui , il punto e virgola è chiaramente una dichiarazione separatore , non un terminatore.

Ciò ha dato origine a problemi nella pratica. Algol 60 aveva anche una "dichiarazione vuota" che era denotata scrivendo nulla. Quindi, si potrebbe scrivere " begin S1; end " dove appare il punto e virgola come se stesse chiudendo S1. Ma il compilatore Algol 60 lo trattava veramente come un separatore tra S1 e una dichiarazione vuota invisibile che la seguiva. Queste sottigliezze erano un po 'troppo per i programmatori pratici. Essendo stato utilizzato per linguaggi orientati alla linea come Assembly e Fortran, pensavano davvero a punto e virgola come terminatore per le istruzioni. Quando i programmi sono stati scritti, in genere è stato inserito il punto e virgola alla fine delle istruzioni, in questo modo:

    a[i] := 0;
    i := i+1

e il punto e virgola sembrava davvero un terminatore per la prima affermazione. Se i programmatori hanno trattato il punto e virgola come un terminatore, un'istruzione come questa darebbe un errore di sintassi:

    if i > 0 then
      a[i] := 0;
    else
      a[i] := 1;

perché il punto e virgola termina il "se" e, quindi, il "else" diventa penzolante. I programmatori erano completamente confusi.

Quindi, PL / I, che è stato il successore di IBM per Fortran orientato alla linea, ha deciso di rendere il punto e virgola un'istruzione terminatore piuttosto che un separatore. I programmatori erano felici di questa scelta. La maggior parte dei linguaggi di programmazione ha seguito l'esempio. (Pascal resistette alla tendenza, ma il suo successore Ada rinunciò.)

[Nota aggiunta: articolo di Wikipedia sulla programmazione dei confronti linguistici ha una bella tabella che riassume come il punto e virgola è trattato in vari linguaggi di programmazione.]

    
risposta data 16.03.2012 - 12:54
fonte
6

Questo è praticamente un lavoro di supposizione, ma guardando una tastiera QWERTY standard limitata ai valori ASCII i caratteri naturali per la terminazione / separazione sarebbero.!?,:; e ritorni di carrello. di quelli!?: dovrebbe essere immediatamente squalificato per aver preso più chiavi e la terminazione dell'istruzione sarà una cosa molto comune. I periodi sarebbero squalificati perché sono facilmente confusi con punti decimali che li renderebbero inutilmente complicati per essere un terminatore dato lo spazio limitato dei computer iniziali. i ritorni a capo sarebbero squalificati dopo che le righe di codice potevano essere più lunghe di quelle che possono essere mostrate su una singola riga sullo schermo, quindi sarebbe più difficile leggere un programma quando le righe dovessero scorrere in orizzontale, o richiedere caratteri aggiuntivi per creare una continuazione sulla riga successiva che aggiunge di nuovo complessità. questo lascia, e; come opzioni, di quelle, è usato molto più spesso in scrittura rispetto a; quindi il punto e virgola è scelto perché è più facile da digitare, meno confuso perché aggiunge significato a un personaggio con un significato limitato e meno complicato perché i casi speciali non esistono realmente con il suo uso.

Il punto e virgola è stato scelto perché era il miglior personaggio basato sulla pigrizia e sulla semplicità.

    
risposta data 13.03.2012 - 16:15
fonte
6

È in gran parte una scelta arbitraria. Alcune lingue hanno fatto altre scelte. COBOL termina le istruzioni con il carattere . . FORTRAN, BASIC e Python generalmente terminano le istruzioni con newline (con sintassi speciale per istruzioni multilinea). E Lisp mette tra parentesi le sue affermazioni con parentesi.

Il motivo principale per cui ; è così popolare come separatore / terminatore di istruzioni è che la maggior parte delle lingue popolari di oggi si basa su ALGOL , che utilizzava quella convenzione.

instead of a different symbol?

Quale altro simbolo potresti scegliere?

I caratteri ASCII # $ @ [] ^ _ '{|} ~ non erano sempre presenti nelle prime codifiche dei caratteri come ISO 646 .

I caratteri ()*+-/<=> vengono in genere utilizzati come operatori matematici e creerebbero ambiguità di analisi se usati come terminatori di istruzioni.

product = a * b *  // If '*' were a statement terminator,
c * d *            // Are there two factors, or four?

Problemi simili si applicherebbero a ' e " , che sono tipicamente usati come delimitatori di stringhe; , , che viene in genere utilizzato per separare gli argomenti della funzione e . , che viene in genere utilizzato come punto decimale (o come delimitatore in costrutti come some_struct.some_field ).

Questo lascia !%&:;? .

Scegliere ! o ? probabilmente non causerebbe difficoltà tecniche, ma i loro significati inglesi darebbero l'umore sbagliato al programma.

print(x)?  # Yes, you should.
           # It's an IMPERATIVE language; stop questioning my commands.
print(x)!  # OK!  You don't have to shout!

Il & sarebbe una scelta più sensata come separatore di istruzioni (non terminatore), perché

do_thing_a() &
do_thing_b()

può essere letto come un comando per fare cosa A e quindi fare la cosa B. Ma la maggior parte delle lingue con un operatore & la usano come logica o bit a bit AND invece.

Il segno % potrebbe causare confusione in istruzioni come interest_rate = 2.99% (che imposterà la variabile su 2.99 invece del previsto 0.0299 ). Ovviamente, il noto significato matematico di % non ha impedito a C di utilizzarlo come operatore rimanente.

Quindi lascia : e ; .

: è una scelta sensata, e infatti è usato come separatore di istruzioni intra-line nella maggior parte dei dialetti di BASIC.

Ma ; ha la grammatica inglese su un lato; può essere usato per separare le clausole all'interno di una frase.

    
risposta data 29.03.2012 - 04:55
fonte
3

Piuttosto che cercare di rispondere alla tua domanda, penso che sia meglio concentrarsi sulla tua domanda implicita:

I want to know the history behind this decision, and hope the answers will lead to insights that may influence future decisions in the design and implementation of programming languages.

Se vuoi imparare a programmare la progettazione del linguaggio e la cronologia delle implementazioni, e ottenere maggiori informazioni sul processo, allora i procedimenti del La storia delle conferenze linguistiche di programmazione è un ottimo punto di partenza. (Penso che avrete bisogno di un abbonamento ACM per essere in grado di accedere al procedimento però.)

Why are statements in many programming languages terminated by semicolons? Is there a reason that a semi-colon was chosen as a line terminator instead of a different symbol?

Considerando la domanda principale come una domanda di esempio a cui potresti voler rispondere leggendo il procedimento HOPL, vorrei offrire il seguente punto: le persone che progettano un nuovo linguaggio di programmazione di solito lo fanno perché considerano quelle sapere di essere rotto / carente in qualche modo. Il loro nuovo linguaggio è, da un lato, progettato per risolvere questa carenza. D'altra parte, i progettisti di linguaggi copieranno anche elementi di design da altre lingue che pensano siano buoni, o semplicemente non modificheranno quegli elementi con cui non hanno riscontrato problemi.

Specialmente quell'ultima parte è importante: invece di cercare di scoprire quale linguaggio di programmazione sia mai stato il primo a usare il punto e virgola come terminatori e perché molti altri linguaggi di programmazione lo hanno copiato, probabilmente imparerai di più guardando le lingue che ha non copiato. Ad esempio, mentre Smalltalk ha preso molta ispirazione da Simula, ha non copiato la sua sintassi e in particolare l'uso del punto e virgola come terminatori di istruzioni. Ha cambiato completamente i terminatori (separatori) e utilizza il punto e virgola per qualcos'altro. Al contrario, la prima lingua che abbia mai usato un punto e virgola come terminatore di un'istruzione potrebbe avere avuto un motivo per cambiare questo da quello che era usato nelle lingue precedenti. È anche possibile che sia stata la prima lingua a introdurre l'intero concetto di terminatore di un'istruzione (o lo facesse indipendentemente dalle altre lingue) e che il punto e virgola sia stato utilizzato per qualche motivo che è ora perso nel tempo. (Sospetto che quest'ultimo sia il caso qui, poiché nessuno degli altri rispondenti è riuscito a ricavare una citazione dalla persona che ha introdotto il punto e virgola piuttosto che offrire supposizioni adattate sul motivo per cui il punto e virgola era una buona scelta.) Ma per riaffermare la mia Punto, penso che imparerai di più guardando perché i progettisti di linguaggi hanno cambiato le cose piuttosto che il motivo per cui le hanno copiate / conservate. Quando le persone cambiano le cose di solito vogliono o devono spiegare il cambiamento, mentre non lo fanno quando copiano o mantengono le stesse cose perché "perché dovremmo cambiarlo? è proprio come è fatto! "

    
risposta data 26.03.2012 - 14:38
fonte
2

Riguarda la visibilità.

I primi separatori di istruzioni erano il "." come in COBOL e nuova riga, ritorno a capo in FORTRAN.

Il CR si è dimostrato limitante in quanto rende difficile il flusso di un'istruzione su più righe.

L'arresto completo ha causato un problema più interessante. Quando leggi il testo inglese il tuo cervello elabora i punti fermi a livello subliminale, sei consapevole che una frase è finita e puoi sospendere il respiro ma non ti accorgi del tutto. che lo segnalò. Anche in molti font il "." è il carattere più piccolo possibile a volte reso come un singolo pixel. Periodi mancanti o supplementari sono diventati la causa più comune di errori nei programmi COBOL.

Quindi, imparando dai primi errori, ALGOL sceglie un terminatore specifico che consentirebbe a un'istruzione di scorrere su più righe, e ne sceglie una visibile e facilmente rilevabile dai lettori umani. Il punto e virgola essendo entrambi grandi e abbastanza inusuali in inglese comune non deve essere elaborato inconsciamente.

    
risposta data 28.03.2012 - 12:27
fonte
1

Ho capito che è stato scelto perché c'era bisogno di un esplicito terminatore di istruzioni diverso da un carriage-return / new-line. Ai tempi delle schermate di 80 colonne, in realtà una singola riga di codice avvolto su più righe era abbastanza comune che usare \ r o \ n per il terminatore dell'istruzione non avrebbe funzionato.

I punti e virgola erano semplicemente convenienti perché non vengono utilizzati nelle istruzioni matematiche / matematiche. In quanto tali, non sono in conflitto con il contenuto effettivo delle dichiarazioni in misura significativa.

Personalmente, penso che l'uso continuo del punto e virgola, insieme ai requisiti di stile per mantenere le linee sotto gli 80 caratteri, sia francamente stupido e anacronistico. Linguaggi come python hanno ampiamente dimostrato che è possibile scrivere codice facilmente comprensibile e conciso più facilmente senza di essi. Inoltre, se hai problemi con righe più lunghe di 80 caratteri, hai bisogno di un monitor più grande.

    
risposta data 13.03.2012 - 20:30
fonte
0

Ecco due domande: perché ALGOL ha ottenuto il punto e virgola e il motivo per cui altre lingue lo hanno seguito.

La prima domanda ha già una risposta in molti modi qui.

Come secondo, l'ALGOL è stato ampiamente utilizzato come linguaggio pseudocode per la scrittura degli algoritmi. Quindi, i punti e virgola diventarono presto naturali per gli utenti di lingue diverse. E naturalmente sono stati presi per le lingue più giovani.

    
risposta data 09.01.2016 - 11:14
fonte
0

Potrei sbagliarmi, ma penso che questo abbia qualcosa a che fare con il fatto che in molti assemblatori è stato usato un punto e virgola per iniziare un commento, di solito messo dopo un'istruzione. Tutto dopo un ; era un commento e non faceva più parte dell'istruzione stessa.

Quindi è necessario terminare le istruzioni quando le si digita in un interprete. Brevi istruzioni (ad esempio espressioni matematiche) potrebbero essere terminate semplicemente premendo il tasto Invio, dicendo all'interprete che l'espressione è pronta per essere calcolata e ha prodotto un risultato. Ma a volte si voleva inserire più righe di codice per l'istruzione, quindi un modo per ottenerlo era usare un carattere speciale come terminatore dell'istruzione invece di dipendere solo dal tasto Invio. In questo modo, l'utente poteva inserire più righe di codice contemporaneamente, perché Invio non l'aveva ancora inviato all'interprete. Solo quando l'interprete ha trovato il carattere di terminazione in una riga inserita con Invio, alla fine lo esegue e ne calcola il risultato.

Ora unisci queste due cose insieme, e il punto e virgola sembra essere una scelta ovvia per il carattere che termina: dice dove finisce la parte dell'istruzione e parte la parte del commento, quindi quando l'interprete la incontra in una riga, sa che può lavare tutte le linee dell'espressione che ha bufferizzato finora ed eseguirlo, perché l'istruzione è appena terminata, ora siamo in un commento (beh, almeno fino alla fine di questa riga, perché inizierà la prossima riga ancora in modalità codice, iniziando una nuova espressione / istruzione).

Ciò presuppone, naturalmente, che sia stato davvero il punto e virgola che è stato usato per i commenti della persona che ha inventato questa idea di riutilizzarla come terminatori di istruzioni. Avendo avuto qualsiasi altro carattere, avremmo potuto finire con un terminatore di istruzioni diverso.

Inb4: No, questo non è un account storico. Non ho alcuna prova che questo sia il vero modo in cui il punto e virgola prende vita. È solo come immagino possa essere accaduto.

    
risposta data 01.07.2018 - 07:12
fonte
-1

La maggior parte delle lingue ha preso il punto e virgola perché era già ampiamente utilizzato a tale scopo e il cambiamento non aveva senso.

E considerando le prime lingue per fare quella scelta, dovrai considerare quali sono le alternative. Quando si progetta un linguaggio, si desidera che siano disponibili i caratteri necessari e in questo momento i set di caratteri sono stati codificati su 6 bit, spesso con alcuni pattern riservati, spesso con alcuni caratteri non definiti in modo definitivo (per un successivo verificarsi di questo, si pensi al varianti nazionali di ISO-646 - la variante americana è ben conosciuta con il nome ASCII - che riutilizza i codici per caratteri "comuni" come [ , # o $ , e vedi l'effetto in un contesto dove c'è solo la metà delle posizioni di codice disponibili e lettere e cifre che riservano più della metà di quelle).

Probabilmente non c'era nessun altro carattere che potesse essere usato come separatore di istruzioni come intuitivamente ( . è probabilmente già l'unico serio contendente per quei criteri) e senza introdurre lexing o difficoltà di analisi in un momento in cui la teoria di parsing e lexing era ancora in elaborazione ( . è ora fuori questione a causa del suo utilizzo in numeri reali).

    
risposta data 15.03.2012 - 15:55
fonte
-1

Un altro motivo per cui utilizzare il punto e virgola è perché è uno dei caratteri che non richiediamo o utilizziamo più spesso.

Supponiamo di usarlo più spesso come nome di variabile o qualcosa e se il punto e virgola sarebbe stato usato come parola chiave o come operatore, sarebbe stato un conflitto di simboli per il compilatore, quindi era importante usare un simbolo che non è spesso usato nella codifica.

Credo che i linguaggi di programmazione in stile C lo rendessero popolare e quindi gli autori di nuovi linguaggi di programmazione non volevano reinventare la ruota e hanno continuato a utilizzarla fino ad ora.

    
risposta data 16.03.2012 - 14:34
fonte

Leggi altre domande sui tag