Perché i vecchi BASIC (e forse altre lingue) usano i numeri di riga come parte del codice sorgente?
Voglio dire, quali problemi ha (provare a) risolvere?
Il BASIC deve essere inserito nel contesto con i suoi linguaggi contemporanei: early fortran, cobol e assembly.
Indietro quando ero dilettevole su 6502 assembly senza etichette, ciò significava che quando hai scoperto che dovevi aggiungere un'istruzione da qualche parte nel mezzo di un codice ben confezionato (ho poi aggiunto NOP s) dovevi passare e ripetere tutti gli indirizzi di salto. Questo è stato che richiede tempo.
Fortran era un sistema basato sulla numerazione di righe precedente al BASIC. In Fortran, le colonne 1-5 erano un numero di riga da utilizzare per i target per la ramificazione. La cosa fondamentale con Fortran era che i compilatori tendevano ad essere un po 'più intelligenti dell'interprete BASIC e aggiungere alcune istruzioni era solo una questione di punzonare alcune carte e metterle nel mazzo nel posto giusto.
BASIC, d'altra parte doveva mantenere tutte le sue istruzioni ordinate. Non c'era molto di un concetto di "continuazione della linea precedente". Invece, in Applesoft BASIC (uno dei dialetti ampiamente usati con cui ho familiarità e in cui posso trovare informazioni) ogni riga in memoria era rappresentata come:
NN NN TT TT AA BB CC DD .. .. 00
Aveva due byte per l'indirizzo della riga successiva ( NN NN
). Due byte per il numero di riga di questa linea ( TT TT
), quindi una lista di token ( AA BB CC DD .. ..
) seguita dal marcatore di fine riga ( 00
). (Si tratta di pagina 84-88 di Inside the Apple // e )
Un punto importante da comprendere quando si guarda a quella rappresentazione della memoria è che le righe possono essere memorizzate nella memoria senza ordine. La struttura della memoria era quella di una lista collegata con un puntatore 'next line' nella struttura. Ciò ha reso facile aggiungere nuove linee tra due linee, ma è necessario numerare ogni riga affinché funzioni correttamente.
Molte volte lavorando con BASIC, si stava effettivamente lavorando in BASIC stesso. In particolare, una determinata stringa era o un numero di riga e istruzioni BASIC, oppure un comando all'interprete di base a RUN
o LIST
. Ciò ha reso facile distinguere il codice dai comandi: tutto il codice inizia con i numeri.
Queste due informazioni identificano il motivo per cui sono stati utilizzati i numeri: è possibile ottenere molte informazioni a 16 bit. Le etichette basate su stringhe richiederebbero molto più spazio e sarebbero più difficili da ordinare. I numeri sono facili da usare, comprensibili e più facili da rappresentare.
In seguito i dialetti BASIC in cui non eri in l'interprete per tutto il tempo erano in grado di eliminare ogni riga numerata e invece avevano solo bisogno di numerare le linee che erano bersagli di ramo. In effetti, etichette.
L'editing dei primi microcomputer era basato sulla linea. Non puoi semplicemente muoverti liberamente nel codice sorgente e modificarlo. Hai avuto una singola riga nella parte inferiore dello schermo in cui è possibile digitare i comandi e immettere il codice. Il resto dello schermo era costituito da elenchi di codici e output di comandi di sola lettura. Se vuoi modificare la riga 90 nel programma hai scritto " EDIT 90
", e il contenuto della riga 90
è entrato nel buffer di modifica a riga singola. Quando hai modificato la riga su cui premi invio, l'elenco dei programmi è stato aggiornato. Quindi hai bisogno dei numeri di linea per poter modificare il programma.
Quando gli editor di codice sono diventati più avanzati e ti hanno permesso di muovere il cursore nella lista dei codici non hai più bisogno dei numeri di riga.
Se stai pensando ai dialetti BASIC dei microcomputer domestici a 8 bit degli anni 80, allora quei computer non avevano editor di testo (a meno che non avessi comprato qualche applicazione di word processor). Non c'era modo di avere l'intero codice sorgente del programma BASIC "aperto in un editor", come avresti quando si programma oggi. Il programmatore non penserebbe nemmeno al programma come a un codice sorgente, o testo, in realtà.
Quindi, diciamo che hai un programma semplice senza numeri di linea in testa:
FOR I=1 TO 42
PRINT I
NEXT I
Avvia il tuo computer. Hai un prompt "pronto" o qualcosa del genere, e il cursore si trova nella riga successiva. Questo è molto simile agli ambienti REPL di oggi di diversi linguaggi di scripting, anche se non in modo molto rigoroso basato sulla linea, più simile a uno screen based. Quindi non abbastanza REPL di oggi, ma vicino.
Ora, se inizi a entrare nel programma, potresti ricevere un errore dopo la prima riga, perché l'interprete BASIC tenta di eseguirlo immediatamente (e dimenticarlo), e non ha senso senza che NEXT termini il ciclo. Questo non è un editor di testo in cui si modifica il testo, qui si assegnano i comandi al computer!
Quindi hai bisogno di un modo per dire, questa è la linea del programma, salvala! Potresti avere un comando speciale o solo un simbolo che dice che hey, questa è una linea di programma, memorizzala. Immaginiamo questo:
#FOR I=1 TO 42
#PRINT I
#NEXT I
Ok, ora il nostro interprete BASIC immaginario ha immagazzinato il programma ed è possibile eseguirlo. Ma ora vuoi modificare la linea PRINT. Come si fa? Non sei in un editor di testo, non puoi semplicemente spostare il cursore sulla linea e modificarlo. O vuoi aggiungere un'altra linea come LET COUNT=COUNT+1
nel ciclo. Come indicherai dove inserire la nuova linea?
I numeri di riga risolvono ciò in un modo molto semplice, anche se piuttosto klunky. Se si inserisce una riga di programma con un numero già esistente, la vecchia riga viene sostituita. Ora l'ambiente REPL basato su schermo diventa utile, perché puoi semplicemente spostare il cursore sul programma elenco sullo schermo, modificare la linea sullo schermo e premere ENTER per memorizzarlo. Sembra che tu stia modificando la linea, mentre in effetti stai modificando il testo sullo schermo e poi sostituendo l'intera linea con una nuova dallo schermo. Inoltre, l'inserimento di nuove linee diventa facile se si lasciano numeri inutilizzati in mezzo. Per dimostrare:
10 FOR I=1 TO 42
20 PRINT I
30 NEXT I
Dopo aver reinserito la riga 20 con le modifiche e aggiunto nuove righe, potrebbe essere
5 LET COUNT=0
10 FOR I=1 TO 42
20 PRINT "Index", I
25 LET COUNT=COUNT+1
30 NEXT I
C'è il vantaggio (o la maledizione, dato che abilita il famoso codice spaghetti BASIC) di poter usare i numeri di linea come costrutti linguistici, almeno come obiettivo di GOTO
AND GOSUB
comandi. Questo potrebbe essere sostituito da etichette, ma l'uso dei numeri di riga è molto più semplice da implementare nell'interprete BASIC, che era comunque un indubbio vantaggio in un tipico computer di casa a 8 bit degli anni '80.
Ancora più importante, dal punto di vista dell'esperienza utente, i numeri di linea sono davvero un'interfaccia sorprendentemente semplice ma completa per la modifica del codice. Basta digitare una riga che inizia con un numero per inserire un nuovo codice. Usa LIST 100-200
per mostrare le linee 100-200. Per modificare una linea, elencarla sullo schermo, modificare il testo sullo schermo e reinserire la linea. Per rimuovere una riga, modificarla in modo che sia vuota, cioè semplicemente dare il numero di riga con niente dopo di essa. Un paragrafo per descriverlo. Confronta provando a descrivere l'uso di vecchi editor di testo come edlin di DOS, o ed o ex di Unix: hai bisogno di un paragrafo (solo una lieve iperbole ) solo per spiegare come l'utente può uscirne, se avviato per errore!
Altre risposte spiegano come sono diventati i numeri di linea. Sto cercando di coprire qui, perché i numeri di riga sono sopravvissuti finché hanno fatto, come hanno continuato a risolvere un problema del mondo reale: hanno offerto un modo per eseguire la programmazione reale senza un vero editor, in un modo molto semplice. Una volta corretto, gli editor di testo a schermo intero facili da usare sono diventati il modo principale per modificare il codice, sia con le limitazioni dell'hardware che scomparendo, sia quando l'inerzia delle persone che adattavano le nuove cose è stata superata, quindi i dialetti BASIC basati sulla linea numero scomparivano rapidamente dall'uso, perché il problema principale di usabilità che hanno risolto non era più un problema.
Nel luogo e nell'era in cui è stato sviluppato Basic, il miglior dispositivo I / O disponibile era un telescrivente. La modifica di un programma è stata effettuata stampando (su carta) un elenco dell'intero programma, o la parte interessante di esso, e quindi digitando linee di sostituzione con numeri di linea.
Questo è anche il motivo per cui la numerazione di linea predefinita era di 10, quindi c'erano numeri inutilizzati tra le linee esistenti.
"Numeri di riga" indica alcune cose diverse.
Prima di tutto, tieni presente che il concetto di "linee" non è stato intorno per sempre. Molti linguaggi di programmazione in questa era utilizzavano schede perforate e avere numeri di sequenza (di solito nelle ultime colonne della scheda) ti ha aiutato a recuperare il tuo mazzo nell'ordine corretto se lasciato cadere, o qualcosa di terribile è accaduto nel lettore di schede. C'erano delle macchine per farlo automaticamente.
I numeri di riga da utilizzare come target delle dichiarazioni GOTO
sono un concetto completamente diverso. In FORTRAN IV, erano facoltativi e precedevano l'istruzione (nelle colonne 1-5). Oltre ad essere più facile da implementare rispetto alle etichette in formato libero, c'era anche il concetto di GOTO calcolato e assegnato , che ti ha permesso di saltare a un numero di linea arbitrario. Questo era qualcosa che i linguaggi di programmazione più moderni non hanno (sebbene le dichiarazioni di switch
si avvicinino), ma era un trucco familiare per i programmatori di assemblatori.
BASIC era derivato da FORTRAN e intendeva essere più semplice da implementare e comprendere, quindi forzare ogni "linea" ad avere un numero di riga (sia per il sequencing che come target di GOTO
/ GOSUB
statement) era probabilmente una decisione di progettazione presa per questo motivo.
Ho iniziato a programmare in COBOL che utilizzava numeri di riga nelle colonne 1-6 di ogni riga. Poiché negli anni '70 non esistevano IDE, tutto veniva fatto tramite schede perforate e il numero di riga veniva usato per identificare quali linee nella fonte originale dovevano essere sostituite e quali nuove linee venivano aggiunte. Abbiamo usato per incrementare i numeri di riga per 100 per darci spazio per aggiungere più righe.
Il BASIC è arrivato più tardi di FORTRAN, nell'era dei terminali di linea. Presenta un ambiente di lettura-exe-print-loop che era più interattivo di un mazzo di carte.
Ho imparato a programmare, in BASIC, su un display a una riga che conteneva 24 caratteri. I numeri di riga erano un modo naturale per specificare dove si desiderava una linea, modificando uno o inserendo tra gli altri.
Non riesco davvero a immaginare come potresti farlo.
Un punto che nessuno ha ancora menzionato è che è più facile per i principianti ragionare sul flusso del programma dove i bersagli del ramo sono espliciti. Quindi, piuttosto che dover abbinare (eventualmente annidato) le istruzioni BEGIN / END (o qualunque sia il delimitatore di blocco usato), era abbastanza ovvio dove andava il flusso di controllo. Questo è stato probabilmente utile per il pubblico di riferimento di BASIC (è il Beginner's Codice di istruzione simbolico per tutti gli usi, dopo tutto).
Il Dartmouth Time Sharing System utilizzava un'interfaccia teletype. Quindi ha usato un'interfaccia basata sui comandi. Originariamente, i numeri di riga erano appena usati come mezzo per modificare il programma. È possibile inserire, sostituire o eliminare utilizzando un numero di linea. Non sembra che la versione precedente usasse i numeri di riga per le istruzioni goto, ma questa era un'aggiunta successiva alla lingua.
Leggi altre domande sui tag history language-design source-code