un

guest
1 / ?
back to lessons

Programowanie w Binarnym Absolutnym

Pierwsi programiści pisali w binarnym absolutnym: każda instrukcja i każdy adres w cyfrach binarnych. Jedna instrukcja mogła wyglądać jak 01100101 00001010 — kod instrukcji i adres pamięci w binarnym.

Problem Makaronowego Kodu

Gdy błąd wymagał wprowadzenia nowego instrukcji, programiści mieli dylemat. Wstawienie na miejscu oznaczało, że każdy następny adres instrukcji przesunął się o jeden — wymagało to programisty zaktualizowania każdego odniesienia do adresu w całym programie. Katastrofalne.

Rozwiązanie: zastąpić instrukcję tuż przed punktem wstawiania skokiem do pustego miejsca w pamięci. W tym pustym miejscu: zapisz instrukcję zastąpioną, dodaj nowe instrukcje, a następnie wykonaj skok. Gdy pojawiały się błędy w korekcie, zastosuj tę samą sztuczkę ponownie, korzystając z innych pustych miejsc pamięci.

Wynik: ścieżka wykonawcza przez program skakała do wydawałoby się losowych miejsc. Hamming nazwał to 'słoikiem makaronowym'. Ścieżka sterowania, rysowana na papierze, wyglądała dokładnie jak zagnieciony makaron.

Ujścia Ratunkowe

Dwa natychmiastowe usprawnienia: notacja oktalna (grupowanie cyfr binarnych w grupach po 3) i szesnastkowa (grupowanie po 4, używając A–F dla wartości powyżej 9). Te zmniejszyły błędy podczas pisania, ale nie rozwiązały podstawowego problemu adresowania.

Symboliczne assemblage (na przykład IBM's SAP — Symbolic Assembly Program — i SOAP — Symbolic Optimizing Assembly Program na IBM 650) pozwalało programistom pisać nazwy instrukcji (ADD, MOVE) i etykiety symboliczne adresów zamiast binarnych. Assembler tłumaczył to na binarne w czasie wejścia, automatycznie zarządzając przypisaniami adresów.

SOAP wykonywał dodatkową optymalizację: układał instrukcje na taśmie obrotowej tak, aby następna instrukcja dotarła do głowy odczytującej dokładnie w momencie, gdy poprzednia zakończyła się — minimalizacja opóźnienia kodowania. SOAP nawet skompilował się: program A był przetwarzany jako dane, aby wygenerować B, B uruchamiano na A, aby zmierzyć, jak dużo samokompilacja się poprawiła.

Kora Analizy & Hierarchia Języka

Biblioteki & Przenoszalne Kodowanie

Hamming zauważył, że pomysł na odtwarzalne oprogramowanie (biblioteki matematyczne) pojawił się bardzo wcześnie - Babbage go opracował. Problem: biblioteka z absolutnymi adresami wymagała, aby każda procedura zajmowała te same miejsca pamięci każdorazowo. Gdy cała biblioteka stała się zbyt duża, programy rywalizowały o te same adresy.

Rozwiązanie: kod przemieszczalny. Assemblery generują instrukcje, które odnoszą się do pamięci względnie - to jest jako odległości od adresu początkowego - a nie adresów absolutnych. Linker rozwiązuje ostateczne adresy podczas ładowania.

Niedopubliczowane raporty von Neumanna (szeroko rozpowszechnione) opisywały niezbędne triki programistyczne. Pierwsza publikowana książka o programowaniu (Wilkes, Wheeler & Gill, EDSAC, 1951) sformułowała te techniki.

Wyjaśnij, dlaczego biblioteki o adresach absolutnych stworzyły problem skalowania, a jak kod przenoszalny go rozwiązał. Jakie właściwość absolutnych adresów spowodowała kolizję, a co oznacza 'przenoszalny' technicznie?

Rozdzielająca Języka Projekt

FORTRAN (1957, IBM) i ALGOL (1958, międzynarodowy komitet) reprezentują dwie filozofie projektowania, które wyprodukowały zupełnie różne wyniki.

FORTRAN

John Backus kierował projektem FORTRAN (FORmula TRANslation) w IBM. Cel projektowania: stworzenie języka łatwego do użytku dla naukowców i inżynierów. FORTRAN akceptował notację matematyczną, która wydawała się naturalna dla swoich użytkowników: A = B + C * D zamiast ADD B, C; STORE T; MULTIPLY T, D; STORE A.

FORTRAN przetrwał 60+ lat. Nadal jest używany w obliczeniach naukowych, dynamice płynów, modelowaniu klimatu oraz w informatyce. Hamming uznał tę trwałość za dowód dobrego projektu.

ALGOL

ALGOL (Język Algorytmiczny) został zaprojektowany przez komitet logików i naukowców komputerowych, mając na celu matematyczną staranność: czysto logiczny, formalnie zdefiniowany język. Notacja Backus-Naur (BNF) została wynaleziona, aby opisać gramatykę ALGOL.

ALGOL nie powiódł się w praktyce. Choć jego elegancja logiczna i ogromne wpływy na projektowanie kolejnych języków (Pascal, C oraz niemal każdy nowoczesny język odziedziczył po gramatyce ALGOL), ALGOL sam w sobie nigdy nie został szeroko wdrożony. Wyrok Hamminga: logicznie zaprojektowany, niemożliwy do użytkowania przez ludzi.

Hierarchia Języków

Hamming opisał naturalną hierarchię od języka maszynowego przez assemblerski, wyższych języków programowania, aż po 'język problemowy' bliski sposobowi myślenia specjalistów o ich dziedzinie. Na każdym poziomie dodaje się czytelność dla człowieka kosztem efektywności maszyny.

Hamming's Four Language Design Criteria

Hamming wyciągnął z lekcji FORTRAN vs ALGOL cztery kryteria dla skutecznego języka programowania:

1. Latwe do nauki - początkujący może szybko stać się produktywny

2. Latwe do użytkowania - codzienne zadania wymagają minimalnej ceremonii

3. Latwe do debugowania - błędy wywołują znaczące, łatwo zlokalizowane komunikaty

4. Latwe do użytkowania podprogramów - ponowne użycie i abstrakcja nie wymagają heroicznego wysiłku

Dodał obserwację strukturalną: język ludzki zawiera około 60% powtarzalności; pismo zawiera około 40%. Języki o niskiej powtarzalności (jak APL) tworzą eleganckie jednostronicowe fragmenty, które eksperci uważają za piękne, a początkujący za nieprzezroczyste - i które zawierają błędy nieodkrywalne, gdy pojedynczy znak zmienia znaczenie.

Implika: język zaprojektowany dla elegancji logicznej optymalizuje dla złego czytelnika. Programista jest człowiekiem; ludzie potrzebują powtarzalności, aby wykryć błędy i komunikować intencje.

Zastosuj kryteria Hamminga do języka programowania, który dobrze znasz. Ocena każdego kryterium na skali od 1 do 5 (5=wybitnie). Następnie zidentyfikuj kryterium, które, gdy zostanie wzmocnione, najbardziej poprawiłoby język - i wyjaśnij, jakby wyglądał konkretne zmiany.

Psychologiczne vs Logiczne Projektowanie Języków Programowania

Hamming powrócił do kontrastu FORTRAN/ALGOL jako do lekcji o dynamice instytucjonalnej i ludzkiej, a nie tylko o projektowaniu języków.

FORTRAN został zaprojektowany psychologicznie - dla ludzi, którzy go używali, szczególnie naukowców, którzy myśleli w notacji matematycznej. ALGOL został zaprojektowany logicznie - dla poprawności formalnej i elegancji teoretycznej.

Paradoks, który zidentyfikował Hamming: **logicznie poprawny język, który ludzie odrzucają, nie powiedzie się; język zaprojektowany praktycznie, który ludzie przyjmują, powiedzie się, nawet jeśli jest logicznie mniej schludny.

Wskazał APL jako przypadek skrajny: logicznie elegancki, wyrażalny w jednej linijce, z własnym zestawem znaków specjalnych. Ekspertów lubiło. Zwykli programiści uważali je za nierzydzące. Zmiana pojedynczego znaku mogła bezspłycie zmienić sens programu. APL ma małą społeczność oddaną i niemalże zerowy użytek wśród mainstreamowych programistów.

Argument o nadmiarowości ludzkich komunikatów: język mówiony jest ~60% nadmiarowy (powtarzane konteksty, sformułowania wyjaśniające, przewidywalna struktura). Język pisanym ~40% nadmiarowy. Ta nadmiarowość służy wykrywaniu błędów - ludzie są nieufni, więc język ewoluował, aby zawierać wystarczająco dużo powtarzających się informacji, aby wykryć i poprawić błędy. Niskonadmiarowy język usuwa tę osłonę bezpieczeństwa.

Hierarchia Kompilatora

Hamming opisał warstwowanie kompilatora/interpretera: program może odczytać wyższyny język i przetłumaczyć go na niższyny. Nakładaj tę warstwę - każda tłumaczy na jeden poziom niżej. Na szczycie: język specjalistyczny dla ekspertów z określonej dziedziny (biologia, finanse, fizyka), którzy piszą naturalnie. Na dole: kod maszynowy. Każde przejście to kompilator czy interpreter.

Przewidywanie Przetrwania Języka

Do 1993 roku Hamming obserwował wiele języków, które odniosły sukces i nie powiodły się. FORTRAN (1957) przetrwał. ALGOL (1958) nie powiódł się. COBOL (1959) przetrwał dziesięciolecia w obliczeniach biznesowych. LISP (1958) przetrwał w badaniach AI. PL/I (1964) próbował zjednoczyć wszystko i nie powiodło się.

Wykorzystując rozróżnienie psychologiczne wobec logicznego projektu Hamminga oraz jego cztery kryteria, wyjaśnij, dlaczego jeden język, który znasz, odniósł sukces, a drugi nie powiódł się (lub niepowoduje się). Twoja wyjaśnienie powinno identyfikować konkretne czynniki ludzkie, które kierowały do przyjęcia lub odrzucenia - nie tylko właściwości techniczne.

Ponawiający się Odpowiednik

Rozdział o historii oprogramowania Hamminga zawiera ponawiające się wyobrażenie:

1. Istnieje bolesne ograniczenie (absolutne adresy, binarna notacja, niemal niewykonawalny kod)

2. Ktoś wynalazkuje warstwę abstrakcji, która ukrywa ograniczenie

3. Abstrakcja pozwala na nową skalę, która tworzy nowe bolesne ograniczenia

4. Powtarzanie

Binarny → oktalny/heksadecymalny → symboliczny język maszynowy → FORTRAN → programowanie strukturalne → obiektowo-orientowane języki → języki specjalistyczne. Każde poziom rozwiązuje najbardziej dotkliwe problemy poprzednika, wprowadzając jednocześnie nową klasę problemów.

Problem z makaronowym kodem (adresy absolutne) prowadził do symbolicznego języka maszynowego. Duże programy w języku maszynowym prowadziły do FORTRAN. Duże programy w FORTRAN prowadziły do programowania strukturalnego i następnie do orientacji obiektowej. Wykład Hamminga zakończył się przed tymi późniejszymi przejściami, ale wzorzec kontynuuje się.

Jego lekcja dla inżynierów: zawsze rozwiązujesz ból, który ujawnił poprzednia abstrakcja. Zrozumienie poziomu, na którym się aktualnie znajdujesz, wymaga wiedzy na temat powodu istnienia poziomu poniżej niego.

Zidentyfikuj warstwę abstrakcji oprogramowania, z którą regularnie współpracujesz. Jakie bolesne ograniczenie w warstwie poniżej ukrywa? A co nowego rodzaju problemy wprowadza twoja bieżąca warstwa - co ból będzie musiało rozwiązać warstwa wyższa?