Dlaczego BASIC używał numerów linii?

95

Dlaczego stare języki BASIC (a może inne języki) używały numerów wierszy jako części kodu źródłowego?

Mam na myśli, jakie problemy to (próbował) rozwiązać?

DerMike
źródło
27
Jeśli wykonałeś już poważny wysiłek związany z ponownym wyszukiwaniem, nie chowaj informacji o tym w komentarzach, odpowiednio edytuj swoje pytanie. Co więcej, Google zabrał mnie bezpośrednio tutaj: stackoverflow.com/questions/541421/... i tutaj stackoverflow.com/questions/2435488/…
Doc Brown
13
Głosuję za zamknięciem tego pytania jako nie na temat, ponieważ odpowiedź jest już w toku przepełnienia stosu .
Andres F.,
6
Applesoft BASIC był pierwszym językiem programowania, którego się nauczyłem. Pamiętam, że słyszałem, że Pascal nie ma numerów linii i mówię: „Ale jak mam zrobić GOTO bez numerów linii? Jak to ma działać?”
Jens Schauder
14
Zabawne, kiedy ostatni raz sprawdzałem, ocenialiśmy, czy pytanie dotyczyło tematu na podstawie jego treści, a nie zawartości innych stron (i prawdopodobnie odpowiedzi, które tam leżą).
MatthewRock

Odpowiedzi:

130

BASIC należy rozpatrywać w kontekście współczesnych języków: wczesnego fortranu, kobolu i asemblera.

Wcześniej, kiedy zajmowałem się montażem 6502 bez etykiet, oznaczało to, że kiedy odkryłeś, że musisz dodać instrukcję gdzieś pośrodku ciasno upakowanego kodu (później dodałem NOP ), musisz przejść i powtórzyć cały skok adresy. To było czasochłonne.

Fortran był systemem opartym na numerach linii, który był wcześniejszy niż BASIC. W Fortranie kolumny 1-5 były numerami linii, które miały być użyte dla celów do rozgałęzienia. Kluczową sprawą w Fortranie było to, że kompilatory były nieco bardziej inteligentne niż interpreter BASIC, a dodanie kilku instrukcji było po prostu kwestią wybicia niektórych kart i umieszczenia ich w talii we właściwym miejscu.

Z drugiej strony BASIC musiał zachować wszystkie instrukcje w porządku. Nie było zbyt wiele koncepcji „kontynuacji poprzedniej linii”. Zamiast tego w Applesoft BASIC (jeden z powszechnie używanych dialektów, które znam i mogę znaleźć informacje) każda linia w pamięci była reprezentowana jako:

NN NN   TT TT   AA BB CC DD .. .. 00

Miał dwa bajty na adres następnej linii ( NN NN). Dwa bajty dla numeru linii tej linii ( TT TT), a następnie lista tokenów ( AA BB CC DD .. ..), a następnie znacznik końca linii ( 00). (Jest to strona 84-88 Inside the Apple // e )

Ważnym aspektem, na który należy zwrócić uwagę, patrząc na tę reprezentację pamięci, jest to, że linie mogą być przechowywane w pamięci poza kolejnością. Struktura pamięci była połączoną listą ze wskaźnikiem „następnej linii” w strukturze. Ułatwiło to dodawanie nowych linii między dwiema liniami - ale trzeba było ponumerować każdą linię, aby działała poprawnie.

Wiele razy pracując z BASIC, tak naprawdę pracowałeś w BASIC. W szczególności danym ciągiem był albo numer linii i instrukcje BASIC, albo polecenie podstawowego interpretera do RUNlub LIST. Ułatwiło to odróżnienie kodu od poleceń - cały kod zaczyna się od cyfr.

Te dwie informacje wskazują, dlaczego użyto liczb - możesz uzyskać wiele informacji w 16 bitach. Etykiety oparte na łańcuchach zajmowałyby znacznie więcej miejsca i są trudniejsze do zamówienia. Liczby są łatwe w obsłudze, zrozumiałe i łatwiejsze do przedstawienia.

Późniejsze dialekty BASIC, gdzie nie byli w interpreter cały czas byli w stanie pozbyć się każda linia ponumerowane i zamiast tylko potrzebne do numeru linii, które były Branża cele. W efekcie etykiety.


źródło
3
Dobry sos, zapomniałem o Mini Asemblerze. To przywraca wspomnienia .
Blrfl
3
@Blrfl Jeśli pamięć służy ... ] CALL -936 * F666 G $ ... Tak, na początek FP basic.
3
Nie, to był edytor linii. Polecenia zostały zidentyfikowane przez brak numerów linii. Instrukcje były poprzedzone numerami wierszy wskazującymi zarówno, że były to oświadczenia, jak i wskazujące, czy poszły i / lub który wiersz nadpisały. To była wbudowana część edytora linii BASIC, nie było to oddzielne narzędzie ani środowisko.
RBarryYoung
3
@RBarryYoung ] PRINT "FOO"został natychmiast uruchomiony przez tłumacza BASIC. To jest oświadczenie. Jeśli chcesz go uruchomić później, zrobisz to ] 10 PRINT "FOO"i wtedy ] RUN. W środowisku AppleSoft BASIC każdą instrukcję BASIC można uruchomić natychmiast lub z opóźnieniem - w systemie DOS było tylko kilka poleceń, które nie były prawidłowymi instrukcjami BASIC. Różnica między instrukcją teraz a instrukcją później była numerem linii. Możesz także zmodyfikować opóźnione polecenie, wprowadzając ponownie odpowiedni numer wiersza. Można również umieścić wiele instrukcji w jednym wierszu::
4
Jak zauważono w artykule w Wikipedii ( en.wikipedia.org/wiki/Dartmouth_BASIC ) „ DTSS (Dartmouth Time Sharing System) zaimplementował wczesny ... interaktywny interfejs wiersza poleceń. ... Każda linia rozpoczynająca się od numeru linii została dodana do program, zastępujący wcześniej zapisaną linię o tym samym numerze; wszystko inne zostało uznane za polecenie DTSS i natychmiast wykonane ... Ta metoda edycji była konieczna ze względu na użycie teleprinterów jako terminali dla systemu Dartmouth Timesharing.
RBarryYoung
50

Na wczesnych mikrokomputerach edycja odbywała się liniowo. Nie można po prostu swobodnie poruszać się w kodzie źródłowym i edytować. Na dole ekranu był jeden wiersz, w którym można było wpisywać polecenia i wprowadzać kod. Reszta ekranu zawierała tylko kody do odczytu i dane wyjściowe poleceń. Jeśli chcesz edytować powiedz linię 90 w programie, który napisałeś „ EDIT 90”, a zawartość linii 90weszła do bufora edycji jednowierszowej. Po zredagowaniu linii naciśnij Enter, a lista programów została zaktualizowana. Potrzebne były więc numery linii, aby móc edytować program.

Kiedy edytory kodu stały się bardziej zaawansowane i pozwoliły Ci przesuwać kursor na liście kodów, nie potrzebujesz już numerów linii.

JacquesB
źródło
38
Edytujesz linię? Luksus! Pierwsze BASICY, których użyłem, sprawiły, że przepisałeś całą linię. Co naprawdę było do bani, gdy trzeba było przenumerować podprogram.
TMN
48
Ekran? Jaki ekran? W moim pierwszym Basicu „ekranem” była rolka papieru.
ddyer
18
@ddyer: Kiedyś marzyłem o rolce papieru! Wszystko, co mieliśmy, to wiązka elektrod. Wieczorem, kiedy praca miała zostać wykonana, musieliśmy ustawić się w rzędzie i obserwować, kto został porażony prądem, aby sprawdzić, czy program działa poprawnie. ... - Poważnie, jestem zdumiony, że ludziom udało się w tamtym czasie napisać działające programy.
leftaroundabout
26
Elektryczność! Cholerny luksus. Dłutowaliśmy nasze polecenia granitem
Michael Durrant
10
@TMN i ddyer OK, oboje wiecie, dokąd to zmierza, prawda ...? ;-D ==> dilbert.com/strip/1992-09-08 ==> imgs.xkcd.com/comics/real_programmers.png
Baard Kopperud
45

Jeśli myślisz o dialektach BASIC 8-bitowych domowych mikrokomputerów z lat 80-tych, to komputery te nie miały edytorów tekstu (chyba że kupiłeś jakieś edytory tekstu). Nie było możliwości, aby cały kod źródłowy programu BASIC był „otwarty w edytorze”, tak jak zrobiłbyś to podczas programowania. Programista nawet nie pomyślałby o programie jako pliku kodu źródłowego lub tekście.

Przykładowy problem

Powiedzmy, że masz prosty program bez numerów linii w głowie:

FOR I=1 TO 42
PRINT I
NEXT I

Uruchamiasz komputer. Masz monit „gotowy” lub coś w tym rodzaju, a kursor siedzi w następnym wierszu. Jest to bardzo podobne do dzisiejszych środowisk REPL różnych języków skryptowych, choć nie tak ściśle oparte na liniach, a bardziej na ekranie. Więc nie całkiem jak dzisiejsze REPL, ale blisko.

Teraz, jeśli zaczniesz wchodzić do programu, możesz dostać błąd po pierwszym wierszu, ponieważ interpreter języka BASIC próbuje natychmiast go wykonać (i zapomnieć), a bez NEXT zakończenie pętli nie ma sensu. To nie jest edytor tekstu, w którym edytujesz tekst, tutaj podajesz polecenia do komputera!

Częściowe rozwiązanie

Więc musisz powiedzieć, to jest linia programu, zapisz ją! Możesz mieć specjalne polecenie lub tylko symbol informujący, że hej, to jest linia programu, zapisz ją. Wyobraźmy sobie to:

#FOR I=1 TO 42
#PRINT I
#NEXT I

Ok, teraz nasz wymyślony interpreter języka BASIC przechował program i możesz go uruchomić. Ale teraz chcesz edytować wiersz PRINT. Jak ty to robisz? Nie jesteś w edytorze tekstu, nie możesz po prostu przesunąć kursora do linii i edytować go. Lub chcesz dodać kolejną linię jak LET COUNT=COUNT+1w pętli. Jak wskazać, gdzie należy wstawić nową linię?

Rozwiązanie robocze

Numery linii rozwiązują to w bardzo łatwy, choć raczej niezdarny sposób. Jeśli wprowadzisz wiersz programu z już istniejącym numerem, stary wiersz zostanie zastąpiony. Teraz środowisko REPL oparte na ekranie staje się przydatne, ponieważ możesz po prostu przesunąć kursor do listy programów na ekranie, edytować wiersz na ekranie i nacisnąć ENTER, aby go zapisać. Wygląda na to, że edytujesz linię, podczas gdy w rzeczywistości edytujesz tekst na ekranie, a następnie zastępujesz całą linię nową na ekranie. Ponadto wstawianie nowych wierszy staje się łatwe, jeśli między nimi pozostawisz nieużywane liczby. Aby zademonstrować:

10 FOR I=1 TO 42
20 PRINT I
30 NEXT I

Po ponownym wejściu do linii 20 ze zmianami i dodaniu nowych linii może być

5 LET COUNT=0
10 FOR I=1 TO 42
20 PRINT "Index", I
25 LET COUNT=COUNT+1
30 NEXT I

Więcej problemów, które właśnie rozwiązaliśmy

Zaletą (lub przekleństwem, ponieważ umożliwia słynny kod BASIC spaghetti) jest możliwość używania numerów linii jako konstrukcji języka, przynajmniej jako celu poleceń GOTOAND GOSUB. Można to zastąpić etykietami, ale użycie numerów linii jest znacznie prostsze do zaimplementowania w interpretera BASIC, co wciąż było wyraźną zaletą w typowym 8-bitowym komputerze domowym lat 80.

Co ważniejsze, z punktu widzenia doświadczenia użytkownika numery linii są naprawdę zaskakująco łatwym, ale kompletnym interfejsem do edycji kodu. Wystarczy wpisać linię zaczynającą się od cyfry, aby wstawić nowy kod. Służy LIST 100-200do wyświetlania linii 100-200. Aby edytować linię, wyświetl ją na ekranie, edytuj tekst na ekranie i ponownie wprowadź linię. Aby usunąć linię, edytuj ją, aby była pusta, to znaczy po prostu podaj numer linii bez niczego po nim. Jeden akapit, aby to opisać. Porównaj próbę opisania użycia starych edytorów tekstu, takich jak edlin z DOS, ed lub ex z Uniksa: potrzebujesz jednego akapitu (tylko niewielka hiperbola), aby wyjaśnić, w jaki sposób użytkownik może z nich wyjść, gdy został uruchomiony przypadkowo!

Wniosek

Inne odpowiedzi wyjaśniają, jak powstały numery linii. Próbuję tutaj wyjaśnić, dlaczego numery linii przetrwały tak długo, jak przetrwały, w jaki sposób rozwiązują rzeczywisty problem: oferowali sposób na faktyczne programowanie bez prawdziwego edytora, w bardzo prosty sposób. Kiedyś właściwe, łatwe w użyciu pełnoekranowe edytory tekstu stały się głównym sposobem edytowania kodu, zarówno ze znikającymi ograniczeniami sprzętowymi, jak i po przezwyciężeniu bezwładności ludzi dostosowujących nowe rzeczy, wtedy dialekty BASIC oparte na numerach linii dość szybko zniknęły z użycia, ponieważ podstawowy problem użyteczności, który rozwiązali, nie był już problemem.

hyde
źródło
4
Udało wam się. Posiadanie ekranu wielowierszowego zamiast drukowania tty lub pojedynczej linii ułatwia, ale bez koncepcji pliku źródłowego nadal jest zorientowany liniowo.
JDługosz
Jednak fakt, że system jest architekturą 8-bitową, nie jest tak naprawdę czynnikiem ograniczającym. Teraz fakt, że wspomniany system może mieć tylko kilka kilobajtów pamięci RAM i garść kilobajtów pamięci ROM, a być może nawet nie będzie trwałego miejsca do przechowywania (jeśli pękł magnetofon kasetowy) ...
CVn
wciąż trudno sobie wyobrazić kodowanie bez edytora tekstu
phuclv
@ LưuVĩnhPhúc Cóż, istnieje wiele emulatorów do uruchamiania „prawdziwych rzeczy”, takich jak prawie każdy 8-bitowy komputer domowy lub MSDOS i jego GWBASIC z dosbox. Jako przykład możesz dostać jeden z wielu emulatorów C64, a następnie Google, aby znaleźć Podręcznik użytkownika w formacie PDF :-)
hyde
1
@phuclv - Trudno sobie teraz wyobrazić kodowanie bez edytora tekstu. W tej chwili trudno sobie wyobrazić niedogodność korzystania z edytora tekstu, zapisania go i skompilowania, zanim będzie można go uruchomić ... i tak naprawdę przyszło do świata komputerów; Pascal i C. Oba skompilowane języki, oba swobodnie edytowalne za pomocą edytora tekstu, oba zdecydowanie nie są środowiskiem programistycznym samym w sobie (BASIC był zarówno środowiskiem programistycznym, jak i środowiskiem wykonawczym). Pascal był moim następnym językiem i pod wieloma względami dość wyzwalającym. Zdecydowanie mocniejszy. Ale pod innymi względami trochę mniej ekscytujący.
DavidO
17

W czasach, w których opracowywano Basic, najlepszym dostępnym urządzeniem we / wy był teletyp. Edycja programu polegała na wydrukowaniu (na papierze) listy całego programu lub jego interesującej części, a następnie wpisaniu linii zastępczych numerami linii.

Dlatego też domyślna numeracja linii wynosiła 10, więc między istniejącymi liniami nie byłyby używane liczby.

ddyer
źródło
1
W rzeczywistości czytniki kart (wraz z klawiszami) i drukarka liniowa były lepszymi urządzeniami I / O niż teleprinter, ale te były znacznie tańsze.
supercat
Numeracja linii przez 10 była de facto standardem, a nie rygorystycznym wymogiem. I wielu BASIC-ów miało renpolecenie, aby zmienić numerację. Typowe wywołanie to ren 10, 10(zmiana numeracji od dziesiątej, zwiększanie o dziesięć - zachowanie domyślne, jeśli tylko się wpisze ren. Komendy gotoi gosubi then (linenumber)zostaną automatycznie zaktualizowane. Ale to zdecydowanie nie było dostępne w najwcześniejszych BASICACH. Ale IIRC było dostępne w Apple Integer Basic, Applesoft FP basic, TI Basic / Extended Basic, MS Basic / GW Basic itp.
DavidO
13

„Numery linii” oznaczają kilka różnych rzeczy.

Przede wszystkim pamiętaj, że koncepcja „linii” nie istniała od zawsze. Wiele języków programowania w tej erze używało kart dziurkowanych , a posiadanie numerów sekwencyjnych (zwykle w kilku ostatnich kolumnach karty) pomogło ci odzyskać talię w odpowiedniej kolejności, jeśli ją upuściłeś, lub coś strasznego wydarzyło się w czytniku kart. Były maszyny, aby to zrobić automatycznie.

Numery wierszy stosowane jako cele GOTOinstrukcji to zupełnie inna koncepcja. W FORTRAN IV były one opcjonalne i poprzedzały stwierdzenie (w kolumnach 1-5). Oprócz tego, że jest łatwiejsze do wdrożenia niż etykiety swobodne, pojawiła się także koncepcja obliczonego i przypisanego GOTO , która pozwoliła ci przejść do dowolnego numeru linii. Było to coś, czego większość współczesnych języków programowania nie ma (chociaż switchinstrukcje się zbliżają), ale była to znana sztuczka dla asemblerów.

BASIC wywodzi się z FORTRAN i miał być prostszy w implementacji i zrozumieniu, dlatego zmuszanie każdej „linii” do posiadania numeru linii (zarówno w celu sekwencjonowania, jak i celu GOTO/ GOSUBinstrukcji) było prawdopodobnie decyzją projektową z tego powodu.

Mike Harris
źródło
2
Ach, obliczone i przypisane gotos. Pamięci tablic zmiennych etykiet w PL / 1, zapętlanie jednej tablicy w celu znalezienia dopasowania, a następnie użycie tego dopasowania indeksu tablicy jako indeksu w tablicy zmiennych etykiet w celu wykonania goto. Lub Cobol zmienił gotos. I nie używa numerów linii! BBC basic miał bardzo przydatną instrukcję zmiany numeracji.
Kickstart
GCC zezwala na obliczone GOTO jako rozszerzenie (choć nie bezpośrednio z numerem linii) - możesz robić takie rzeczygoto array_of_labels[some_computation()];
immibis
Drobne: FORTRAN wymagał etykiet dla celów GOTO(lub ASSIGN) i oryginalnej aka arytmetyki aka trójdrożnej IForaz (rzadko używanych) alternatywnych zwrotów CALLi sortowania celów (prawdopodobnie ograniczników) DOi FORMATinstrukcji. W innych stwierdzeniach były one opcjonalne.
dave_thompson_085
Niektóre języki BASIC (np. Atari) pozwalały nawet na użycie dowolnych wyrażeń liczbowych w instrukcjach GOTO. Tak więc, przy odpowiedniej konwencji numeracji wierszy, możesz napisać, GOTO 1000+N*100aby emulować switchinstrukcję.
dan04
6

Zacząłem programować w języku COBOL, który używał numerów linii w kolumnach 1-6 każdej linii. Ponieważ w latach 70. nie było IDE, wszystko zrobiono za pomocą kart perforowanych, a numer linii wykorzystano do zidentyfikowania, które linie w oryginalnym źródle miały zostać zastąpione, a które nowe linie dodane. Zwiększaliśmy numery linii o 100, aby dać nam miejsce na dodanie kolejnych linii.

Keith Miller
źródło
14
COBOL nie używał tych numerów linii. Były one wyłącznie wygodą, więc kiedy jakiś biedny schlub upuścił swoją talię, a karty poszły wszędzie, mógł po prostu je zebrać i poprowadzić przez sortownik kart, aby przywrócić je we właściwej kolejności. NIE trzeba było wybijać numerów linii na karty. (Studenci nie. Sklepy produkcyjne zrobiły.)
John R. Strohm
5

BASIC powstał później niż FORTRAN, w erze terminalu. Zawierało środowisko odczytu-exe-print-loop, które było bardziej interaktywne niż talia kart.

Nauczyłem się programować w języku BASIC na wyświetlaczu jednowierszowym , który zawiera 24 znaki. Numery linii były naturalnym sposobem na określenie, gdzie ma się znaleźć linia, niezależnie od tego, czy edytujesz jedną, czy wstawiasz między innymi.

Naprawdę nie wyobrażam sobie, jak inaczej byś to zrobił.

JDługosz
źródło
2
wydaje się, że nie oferuje to nic istotnego w porównaniu z punktami przedstawionymi i wyjaśnionymi w poprzednich 4 odpowiedziach
komnata
2
Czy to źle? Myślę, że Jaques tak naprawdę nie omawiał istoty edycji jednowierszowej w odniesieniu do wstawiania linii i mentalnego śledzenia kodu.
JDługosz
1
@jameslarge Czy tęsknię za tym punktem akapitu zaczynającym się od „Wiele razy podczas pracy z BASIC ...”? Z wahaniem nazywam BASIC systemem operacyjnym. To był DOS. A DOS nie potrzebował BASIC-a, tylko tyle miałeś czasu na pracę.
2
@ Ian, chociaż to prawda, został zaprojektowany dla systemu, który używał teletypów dla systemu io (Dartmouth Time Sharing System).
Jules
3
@MichaelT, Ups! Wycofam połowę mojego komentarza, ale będę opowiadał się za tym, że BASIC to system operacyjny na niektórych komputerach. Myślę; Apple] [, TI 99/4, IBM 5100, HP 9830a, Compucolor 8001, TRS-80 Model 1, Comodore Vic20, Sinclair ZX80 i inne. Wszystko uruchomione do BASIC-a z ROM-u. Niektóre miały opcjonalny system operacyjny, który można załadować z kasety audio lub z dyskietki, jeśli zapłaciłeś dodatkowe $$ za napęd dyskietek.
Solomon Slow
1

Nikt jeszcze nie wspomniał, że początkującym łatwiej jest zrozumieć przebieg programu, w którym cele rozgałęzienia są wyraźne. Zamiast więc dopasowywać (ewentualnie zagnieżdżone) instrukcje BEGIN / END (lub dowolne użyte ograniczniki bloków), było całkiem oczywiste, dokąd poszedł przepływ sterowania. Był to prawdopodobnie użyteczne podane grupy docelowej Zasadniczej (to jest dla początkujących All-purpose Symbolic Instruction Code, mimo wszystko).

TMN
źródło
1

Dartmouth Time Sharing System wykorzystał interfejs telegraficzny. Dlatego używał interfejsu opartego na poleceniach. Początkowo numery linii były po prostu używane do edycji programu. Możesz wstawiać, zamieniać lub usuwać za pomocą numeru linii. Nie wydaje się, aby wczesna wersja używała numerów wierszy dla instrukcji goto, ale było to późniejsze uzupełnienie języka.

C. Fugate
źródło