Czy istnieje powód, dla którego średnik został wybrany jako terminator linii zamiast innego symbolu?
Chcę poznać historię tej decyzji i mam nadzieję, że odpowiedzi doprowadzą do wglądu, który może wpłynąć na przyszłe decyzje.
Czy istnieje powód, dla którego średnik został wybrany jako terminator linii zamiast innego symbolu?
Chcę poznać historię tej decyzji i mam nadzieję, że odpowiedzi doprowadzą do wglądu, który może wpłynąć na przyszłe decyzje.
Odpowiedzi:
W języku angielskim średnik służy na przykład do oddzielania pozycji na liście instrukcji
Podczas programowania oddzielasz kilka instrukcji i używasz kropki, można łatwo pomylić dziesiętną część. Użycie średnika zapewnia łatwą do przeanalizowania metodę oddzielania poszczególnych instrukcji programu, pozostając przy normalnej angielskiej interpunkcji.
Edytuj, aby dodać
We wczesnych dniach, gdy pamięć była droga, przetwarzanie trwało długo i opracowywano pierwsze języki programowania, konieczne było podzielenie programu na osobne instrukcje do przetwarzania. Niektóre języki wymagały umieszczenia każdej instrukcji w wierszu, aby znak powrotu karetki mógł działać jako separator instrukcji. Inne języki pozwalały na bardziej swobodny format układu tekstu, dlatego wymagały określonego znaku ogranicznika. Postać ta została wybrana jako średnik, najprawdopodobniej ze względu na podobieństwo do jej używania w języku angielskim (to musi być przypuszczenie; w tym czasie mnie tam nie było) i ponieważ nie spowodowała konfliktu z inną interpunkcją znaki i symbole, które były wymagane do celów matematycznych lub innych celów składniowych.
Edytuj ponownie
Potrzeba niektórych znaków terminatora wraca do wymagań dotyczących parsowania tekstu języka. Wczesne kompilatory zostały napisane w języku asemblera lub, w niektórych przypadkach, bezpośrednio w ręcznie wykonanych instrukcjach maszyn binarnych. Posiadanie specjalnego znaku identyfikującego koniec instrukcji i ograniczającego fragment przetwarzanego tekstu znacznie ułatwia przetwarzanie. Jak powiedziałem powyżej, inne języki używały znaku powrotu karetki lub nawiasów. Algol, Pascal, Ada, BCPL, B, C, PL / M i inne rodziny języków używają średnika. Jeśli chodzi o to, kto pierwszy użył tej konkretnej postaci, nie cofam się wystarczająco daleko w historii, aby pamiętać. Jego wybór i przyjęcie ma sens, ponieważ
Na koniec uważam, że na te odpowiedzi i komentarze poświęcono więcej czasu niż na decyzję o użyciu średnika do zakończenia instrukcji przy projektowaniu pierwszego języka, który używał jej w ten sposób.
źródło
Wiele języków używa składni, która jest modelowana po C (która została modelowana po B - dzięki @Crollster). Jak widać w komentarzach, istnieje długi łańcuch takich języków ... B został zainspirowany przez PL / I, który został poprzedzony przez ALGOL przy użyciu
;
jako separatora.Ponieważ w C terminatorem instrukcji jest
;
, języki te są takie same.Jeśli chodzi o to, dlaczego wybrano go jako terminator instrukcji w C - być może ze względu na jego użycie w języku angielskim „do wskazania instrukcji niezależnych” .
C został również wynaleziony na PDP-11 w czasie, gdy dostępna była ograniczona ilość pamięci dla zestawów znaków, więc wynalazcy języków musieli pracować w tych ograniczeniach.
źródło
FORTRAN użył znaku powrotu karetki do określenia instrukcji. Okres wykorzystany COBOL. LISP niczego nie wykorzystywał, opierając się na nawiasach. ALGOL był pierwszym językiem, który używał średnika do oddzielania instrukcji. PASCAL podążył za przykładem ALGOL, używając średnika do oddzielenia instrukcji.
PL / I użyłem średnika do zakończenia instrukcji. Jest różnica i można to łatwo dostrzec w PASCAL. Ada poszła w ślady PL / I w tym jednym elemencie, a nie ALGOL.
Średnik jako separator lub terminator instrukcji został szybko zaakceptowany przez społeczność informatyczną jako przydatna notacja i, o ile mi wiadomo, każdy kolejny język o strukturze blokowej podążał za przykładem ALGOL i używał średnika do oddzielania lub kończenia instrukcji.
Wiele lat temu powiedziano mi, że BCPL używał zarówno średnika, jak i znaku powrotu karetki jako separatorów / terminatorów instrukcji, ale sam nigdy nie użyłem tego języka i nie jestem w stanie tego zweryfikować. W pewnym momencie użycie powrotu karetki do oddzielnych lub zakończonych instrukcji zostało porzucone przez potomków BCPL. BCPL spłodził B, B spłodził C, C spłodził C ++, Java, D i całą masę rzeczy znacznie mniej przemyślanych niż PASCAL i Ady.
źródło
Kilka języków używało innych symboli - stare wersje BASIC zamiast tego używały dwukropka, na przykład.
Ignorując kilka wyjątków, myślę jednak, że istnieją dwa podstawowe powody. Po pierwsze, po prostu szukasz czegoś jednoznacznego. W typowym parserze, jeśli wystąpi na tyle poważny błąd, że nie można kontynuować analizowania bieżącej instrukcji, zwykle próbuje się z powrotem zsynchronizować analizator, po prostu przechodząc do terminatora instrukcji i ponownie uruchamiając parser z początek następnej wypowiedzi. W tym celu potrzebujesz czegoś, co normalnie nie wystąpiłoby nigdzie indziej w kodzie, a średnik to symbol, do którego dołączono niewiele innych znaczeń, więc dość łatwo poświęcić to temu celowi.
Drugi powód jest nieco podobny, ale dotyczy bardziej osób czytających / używających kodu. Ponownie wraca do faktu, że faktyczny symbol, którego używasz, nie ma większego znaczenia. Znaczną zaletą czytelności jest korzystanie z symbolu, który czytelnik jest przyzwyczajony widzieć w określonym celu, kiedy i jeśli to możliwe. Nie oznacza to, że C jest jedyną idealną składnią i wszystko inne powinno być zgodne z nią niewolniczo, ale oznacza to, że wystarczająca liczba osób zna ten styl składni, że niejasny podobny język zyskuje dużo (i bardzo mało traci), postępując zgodnie z grubsza taka sama składnia, gdzie to możliwe.
Chciałbym zauważyć, że jest to podobne do projektowania prawie każdego innego programu. Jeśli napiszę program, który korzysta z jakiegoś systemu Windows, spróbuję po prostu użyć natywnych funkcji platform docelowych. Wiele decyzji, które wcielają się w życie, będzie w dużej mierze arbitralnych i może być podejmowanych inaczej bez poważnej utraty funkcjonalności - ale również ich zmiana bez znacznego zwiększenia funkcjonalności po prostu dezorientuje użytkowników, nie osiągając niczego pożytecznego. Te same podstawowe zasady mają zastosowanie do „co powinno zakończyć (lub oddzielić) stwierdzenia w języku?” jako „jak powinien wyglądać pasek przewijania” lub „jak powinno działać sterowanie drzewem?” We wszystkich tych przypadkach decyzja jest w większości arbitralna, a jednolitość sama w sobie zapewnia znaczne korzyści.
Dodam, że tak samo dzieje się w wielu językach, po prostu w taki sposób, że większość z nas jest tak przyzwyczajona przed programowaniem, że niewiele osób o tym myśli. Dlaczego wszyscy używają „+” do oznaczenia dodania lub „-” do oznaczenia odejmowania? Ponieważ kształt symbolu nie ma większego znaczenia, ale każdy, kto zgadza się zastosować to samo znaczenie do każdego symbolu, ma duże znaczenie.
źródło
Semicolon został pierwotnie zaproponowany w Algolu 60 jako separator instrukcji , a nie terminator.
Przed Algolem 60 jedynym dostępnym językiem programowania wysokiego poziomu był Fortran, który wymagał, aby każda instrukcja znajdowała się w osobnej linii. Instrukcje obejmujące wiele wierszy, takie jak pętle do, uważano za osobliwości i traktowano je jako „bloki instrukcji”.
Projektanci Algola 60 zdali sobie sprawę, że instrukcje potrzebują hierarchicznej struktury (jeśli-to-jeszcze, pętle do, instrukcje przypadków itp.) I że mogą być zagnieżdżone w sobie. Tak więc idea każdego stwierdzenia umieszczonego w osobnej linii nie miała już sensu. Układ sekwencyjny wyrażeń w postaci S1; S2; ...; Sn opcjonalnie ujęty w zaczynać - końcowe wsporniki były nazywane oświadczenia złożone , i pasują do hierarchicznej struktury sprawozdań przewidzianych przez Algol 60. Więc tutaj, średnik jest wyraźnie oświadczenie separator , nie terminator.
To spowodowało problemy w praktyce. Algol 60 miał również „puste zdanie”, które oznaczono przez nic nie pisząc. Można więc napisać „ początek S1; koniec ”, gdzie średnik wygląda tak, jakby kończył S1. Ale kompilator Algol 60 naprawdę traktował go jako separator między S1 a niewidoczną pustą instrukcją po nim. Te subtelności były trochę dla praktycznych programistów. Przyzwyczajeni do języków zorientowanych liniowo, takich jak Assembly i Fortran, naprawdę myśleli o średniku jako terminatorze instrukcji. Kiedy programy były wypisywane, zwykle na końcu instrukcji umieszczany był średnik:
a średnik naprawdę wyglądał jak terminator pierwszego zdania. Jeśli programiści traktowali średnik jako terminator, wówczas taka instrukcja dałaby błąd składniowy:
ponieważ średnik kończy „if”, a zatem „else” staje się wiszące. Programiści byli całkowicie zdezorientowani.
Tak więc PL / I, który był następcą IBM zorientowanego liniowo Fortrana, postanowił uczynić średnik terminatorem instrukcji, a nie separatorem. Programiści byli zadowoleni z tego wyboru. Większość języków programowania poszła podobnie. (Pascal oparł się temu trendowi, ale jego następca Ada zrezygnowała z niego).
[Uwaga dodana: artykuł w Wikipedii na temat porównań języków programowania zawiera ładną tabelę podsumowującą sposób traktowania średnika w różnych językach programowania.]
źródło
Jest to dość czysta domysł, ale patrząc na standardową klawiaturę QWERTY ograniczoną do wartości ASCII, naturalnymi znakami zakończenia / separacji byłyby.!?,:; i zwroty karetki. z nich!?: należy natychmiast zdyskwalifikować za przyjmowanie wielu kluczy, a zakończenie instrukcji będzie bardzo powszechne. Okresy zostałyby zdyskwalifikowane, ponieważ można je łatwo pomylić z kropkami dziesiętnymi, co uczyniłoby ich niepotrzebnie skomplikowanymi jako terminator, biorąc pod uwagę ograniczoną przestrzeń początkowych komputerów. powrót karetki byłby zdyskwalifikowany, gdyby linie kodu mogły być dłuższe niż to, co może być pokazane w pojedynczej linii na ekranie, więc trudniej byłoby odczytać program, gdy linie musiały być przewijane w poziomie, lub wymagają dodatkowych znaków, aby utworzyć kontynuację w następnym wierszu, co ponownie zwiększa złożoność. to pozostawia i; ponieważ ich opcje są znacznie częściej używane w formie pisemnej niż; tak więc średnik jest wybierany, ponieważ jest łatwiejszy do wpisania, mniej mylący, ponieważ dodaje znaczenie znakowi o ograniczonym znaczeniu i jest mniej skomplikowany, ponieważ przy jego użyciu nie istnieją specjalne przypadki.
Średnik został wybrany, ponieważ był to najlepszy znak oparty na lenistwie i prostocie.
źródło
Jest to w dużej mierze arbitralny wybór. Niektóre języki dokonały innych wyborów. COBOL kończy instrukcje ze
.
znakiem. FORTRAN, BASIC i Python zazwyczaj kończą instrukcje nowymi liniami (ze specjalną składnią dla instrukcji wieloliniowych). A Lisp nawiasuje swoje wypowiedzi nawiasami.Głównym powodem
;
jest tak popularny, że separator / terminator instrukcji jest taki, że większość współczesnych popularnych języków opiera się na ALGOL , który stosował tę konwencję.Jaki inny symbol możesz wybrać?
Znaki ASCII # $ @ [] ^ _ `{|} ~ nie zawsze były obecne we wczesnym kodowaniu znaków, takim jak ISO 646 .
Znaki
()*+-/<=>
są zwykle używane jako operatory matematyczne i tworzyłyby dwuznaczności podczas analizowania, gdyby były używane jako terminatory instrukcji.Podobne problemy dotyczyłyby
'
i"
, które są zwykle używane jako ograniczniki ciągów;,
, który jest zwykle używany do oddzielania argumentów funkcji, i.
który jest zwykle używany jako przecinek dziesiętny (lub jako separator w konstrukcjach podobnychsome_struct.some_field
).To pozostawia
!%&:;?
.Wybór
!
lub?
prawdopodobnie nie spowodowałby problemów technicznych, ale ich angielskie znaczenie nadałoby programowi zły nastrój.&
Byłby bardziej sensowny wybór jako separator oświadczenie (nie terminatora), ponieważmożna odczytać jako polecenie wykonania czynności A, a następnie czynności B. Jednak większość języków z
&
operatorem używa tego jako logicznego lub bitowego AND .%
Znak może powodować zamieszanie w sprawozdaniach takich jakinterest_rate = 2.99%
(co byłoby ustawić zmienną2.99
zamiast oczekiwanego0.0299
). Oczywiście dobrze znane matematyczne znaczenie słowa „%
nie” powstrzymało C przed użyciem go jako operatora reszty.Więc pozostawia
:
i;
.:
jest rozsądnym wyborem i rzeczywiście jest używany jako separator instrukcji wewnątrz wierszy w większości dialektów języka BASIC.Ale
;
ma na boku gramatykę angielską; można go wykorzystać do oddzielenia zdań w zdaniu.źródło
Zamiast próbować odpowiedzieć na główne pytanie, myślę, że lepiej skoncentrować się na domyślnym pytaniu:
Jeśli chcesz dowiedzieć się więcej o historii projektowania i implementacji języka programowania oraz uzyskać lepszy wgląd w proces, to dobrze jest zacząć od konferencji z historii języków programowania . (Myślę, że będziesz potrzebować członkostwa w ACM, aby mieć dostęp do postępowania.)
Biorąc twoje główne pytanie za przykładowe pytanie, na które możesz spróbować odpowiedzieć, czytając postępowanie HOPL, chciałbym zaproponować następującą kwestię: ludzie projektujący nowy język programowania zwykle to robią, ponieważ uważają te, o których wiedzą, że są jakoś zepsuty / niedobór. Ich nowy język jest z jednej strony zaprojektowany, aby naprawić ten brak. Z drugiej strony projektanci języków kopiują również elementy projektu z innych języków, które uważają za dobre, lub po prostu nie zmieniają tych elementów, z którymi nie mieli problemu.
Szczególnie ta ostatnia część jest ważna: zamiast próbować dowiedzieć się, który język programowania był pierwszym, który używał średników jako terminatorów i dlaczego wiele innych języków programowania to skopiowało, prawdopodobnie dowiesz się więcej, patrząc na języki, które nie zostały skopiowane to. Na przykład, podczas gdy Smalltalk czerpał wiele inspiracji od Simuli, tak nie byłoskopiuj jego składnię, aw szczególności użycie średników jako terminatorów instrukcji. Zmieniło terminatory (naprawdę separatory) na kropkę i używa średnika do czegoś innego. I odwrotnie, pierwszy język, który używał średnika jako terminatora instrukcji, mógł mieć powód do zmiany tego z tego, który był używany w językach, które pojawiły się przed nim. Możliwe jest również, że był to pierwszy język, który wprowadził całą koncepcję terminatora instrukcji (lub zrobił to niezależnie od innych języków) i że średnik został użyty z jakiegoś powodu, który stracił czas. (Podejrzewam, że tak jest w tym przypadku, ponieważ żaden z pozostałych osób odpowiadających nie był w stanie wykopać cytatu od osoby, która wprowadziła średnik, zamiast oferować dopuszczone przypuszczenia, dlaczego ten średnik był dobrym wyborem). punkt, Myślę, że dowiesz się więcej, patrząc na to, dlaczego projektanci języków zmienili rzeczy, a nie dlaczego je skopiowali / zachowali. Kiedy ludzie zmieniają rzeczy, zwykle chcą lub muszą wyjaśnić zmianę, podczas gdy nie robią tego podczas kopiowania lub utrzymywania tego samego, ponieważ „dlaczego mielibyśmy to zmienić? właśnie tak to się robi! ”
źródło
Chodzi o widoczność.
Wczesnymi separatorami były „.” jak w COBOL i nowej linii, powrót karetki w FORTRAN.
CR okazał się ograniczający, ponieważ utrudnia przepływ instrukcji w kilku wierszach.
Kropka spowodowała bardziej interesujący problem. Kiedy czytasz tekst w języku angielskim, twój mózg przetwarza kropki na poziomie podprogowym, masz świadomość, że zdanie się skończyło i możesz wstrzymać oddech, ale tak naprawdę tego nie zauważasz. to sygnalizowało. Również w wielu czcionkach „.” to najmniejsza możliwa postać czasami renderowana jako pojedynczy piksel. Brakujące lub dodatkowe okresy stały się najczęstszą przyczyną błędów w programach COBOL.
Ucząc się na wczesnych błędach, ALGOL wybrał określony terminator, który pozwoliłby na przepływ instrukcji przez kilka wierszy, i wybrał taki, który był widoczny i łatwo zauważalny przez ludzkich czytelników. Średnik jest zarówno duży, jak i dość nietypowy we wspólnym języku angielskim, aby nie przetwarzać go podświadomie.
źródło
Zrozumiałem, że został wybrany, ponieważ istnieje potrzeba wyraźnego zakończenia instrukcji innej niż znak powrotu karetki / nowa linia. W czasach ekranów 80-kolumnowych posiadanie jednego wiersza zawijania kodu w wielu wierszach było na tyle powszechne, że użycie \ r lub \ n jako terminatora instrukcji nie działało.
Średniki były po prostu wygodne, ponieważ nie są używane w instrukcjach logiki / matematyki. Jako takie, nie kolidują one z rzeczywistą treścią oświadczeń w znaczącym stopniu.
Osobiście uważam, że ciągłe używanie średnika, wraz z wymaganiami stylu, aby linie nie przekraczały 80 znaków, jest szczerze głupie i anachroniczne. Języki takie jak python wykazały, że można bez nich pisać łatwiej i bardziej zwięźle. Ponadto, jeśli masz problemy z liniami dłuższymi niż 80 znaków, potrzebujesz większego monitora.
źródło
Oto dwa pytania: Dlaczego ALGOL otrzymał średnik i dlaczego poszły za nim inne języki.
Na pierwsze pytanie można już odpowiedzieć na wiele sposobów.
Jako drugi, ALGOL był bardzo szeroko stosowany jako język pseudokodów do pisania algorytmów. Tak więc średniki wkrótce stały się naturalne dla użytkowników różnych języków. I naturalnie zostały wzięte za młodsze języki.
źródło
Mogę się mylić, ale myślę, że ma to coś wspólnego z faktem, że w wielu asemblerach do rozpoczęcia komentarza użyto średnika, zwykle umieszczanego po instrukcji. Wszystko po a
;
było komentarzem i nie było już częścią samej instrukcji.Następnie trzeba zakończyć instrukcje podczas pisania ich w tłumaczu. Krótkie instrukcje (np. Wyrażenia matematyczne) można zakończyć, po prostu naciskając klawisz Enter, informując tłumacza, że wyrażenie jest gotowe do obliczenia i dało wynik. Ale czasami chciałem wprowadzić wiele wierszy kodu dla instrukcji, więc jednym ze sposobów na osiągnięcie tego było użycie jakiegoś znaku specjalnego jako terminatora instrukcji zamiast polegania tylko na klawiszu Enter. W ten sposób użytkownik może wprowadzić więcej wierszy kodu, ponieważ Enter nie wysłał go jeszcze do tłumacza. Dopiero gdy interpreter znajdzie znak kończący w wierszu wpisanym za pomocą Enter, w końcu go wykona i obliczy wynik.
Teraz połącz te dwie rzeczy razem, a średnik wydaje się oczywistym wyborem dla znaku kończącego: mówi, gdzie kończy się część instrukcji, a zaczyna część komentarza, więc kiedy interpreter napotka ją w linii, wie, że może się spłukać wszystkie wiersze wyrażenia, które do tej pory buforowały i wykonują je, ponieważ instrukcja właśnie się zakończyła, teraz jesteśmy w komentarzu (cóż, przynajmniej do końca tego wiersza, ponieważ następny wiersz zacznie się w kodzie tryb ponownie, rozpoczynając nowe wyrażenie / instrukcję).
Zakłada się oczywiście, że tak naprawdę to średnik został użyty w komentarzach przez osobę, która wpadła na pomysł ponownego użycia go jako terminatorów instrukcji. Mając jakąkolwiek inną postać, moglibyśmy skończyć z innym terminatorem instrukcji.
Inb4: Nie, to nie jest konto historyczne. Nie mam żadnych dowodów na to, że w ten sposób powstały średniki. Tak sobie wyobrażam, że to mogło się wydarzyć.
źródło
Większość języków wzięła średnik, ponieważ był już powszechnie używany do tego celu, a zmiana nie miała sensu.
Biorąc pod uwagę pierwsze języki, które dokonają tego wyboru, musisz rozważyć, jakie są alternatywy. Projektując język, chcesz, aby potrzebne znaki były dostępne, a zestawy znaków w tym czasie zostały zakodowane na 6 bitach, często z pewnymi zastrzeżonymi wzorami, często z pewnymi nieokreślonymi znakami (w późniejszym przypadku pomyśl o krajowe warianty ISO-646 - wariant amerykański jest dobrze znany pod nazwą ASCII - które ponownie wykorzystują kody dla „wspólnych” znaków, takich jak
[
,#
lub$
i widzą efekt w kontekście, w którym jest tylko połowa pozycji kodu dostępne oraz litery i cyfry rezerwujące więcej niż połowę z nich).Prawdopodobnie nie było żadnej innej postaci, która mogłaby być użyta jako separator instrukcji tak intuicyjnie (
.
prawdopodobnie jest już jedynym poważnym konkurentem dla tych kryteriów) i bez wprowadzania trudności z leksykowaniem lub analizowaniem w czasie, gdy teoria analizowania i leksykowania była wciąż w fazie opracowywania (.
jest teraz bez pytania ze względu na jego użycie w liczbach rzeczywistych).źródło
Innym powodem używania średnika jest to, że jest to jeden z znaków, których nie wymagamy ani nie używamy częściej.
Załóżmy, że używamy go częściej jako nazwy zmiennej lub czegoś innego, a jeśli średnik byłby użyty jako słowo kluczowe lub jako operator, byłby to konflikt symboli dla kompilatora, dlatego ważne było użycie symbolu, który nie jest często używane w kodowaniu.
Wierzę, że języki programowania w stylu C sprawiły, że stał się popularny, a następnie autorzy nowych języków programowania nie chcieli wynaleźć koła na nowo i nadal go używali, aż do teraz.
źródło