Dwa i pół tysiąca lat temu grecki filozof Heraklit opisywał przy pomocy metafory rzeki ciągle zmieniający się świat. Wszystko płynie i „nie można wejść dwa razy do tej samej wody”. Także czas odmierzany zegarem komputera płynie nieustannie. Czy jednak metafora rzeki pasuje do opisu działania komputera? Próba odpowiedzi na to pytanie pozwala lepiej zrozumieć strukturę programów komputerowych.

Działanie programu jest napędzane zegarem komputera, który nigdy się nie zatrzymuje (chyba, że wskutek awarii lub wyłączenia zasilania). Nie mamy możliwości wpływania na ten proces. Raz uruchomiony program działa bez naszej ingerencji a czasem nawet wiedzy – deterministycznie i automatycznie.

W rytm zegara następują w programach dwa rodzaje przepływów: przepływ danych i przepływ sterowania.

Upraszczając nieco problem można rzec, że przepływ sterowania wiąże się z wykonywaniem przez komputer kolejnych instrukcji programu, a przepływ danych z wykonywanymi przez ten program działaniami:

komputer → sterowanie → dane

Czyli komputer wykonuje instrukcje, a te instrukcje powodują zmiany stanu (pamięci) komputera. Nic nie stoi na przeszkodzie, aby taki sam stan mógł pojawiać się wielokrotnie. W odniesieniu do świata maszyn Heraklit nie miał więc racji. Jednokierunkowość zmian w czasie jest jedną z różnic między człowiekiem a maszyną.

Drugą istotną różnicą jest determinizm. Przepływ danych i sterowania odbywa się w sposób automatyczny. Po uruchomieniu programu komputer samodzielnie (automatycznie) wykonuje kolejne jego instrukcje. Można z góry przewidzieć kolejność wykonywania działań (na tym przecież polega programowanie maszyn). Człowiek tymczasem przed każdym działaniem podejmuje świadomą decyzję.

Te dwa zagadnienia wyglądają paradoksalnie:

1. Istnieje pozorna sprzeczność między trwałością a przemijaniem. Komputer może bez końca wracać do stanu początkowego (trwałość), a jednak każdy program zaczyna się i kończy (przemijanie).

2. W przypadku większości programów następuje interakcja z otoczeniem. Jeśli program wydrukował raport na drukarce, to nie może już tego cofnąć. Nie ma powrotu do stanu w którym kartka była czysta! Jak to pogodzić z tezą o możliwości powrotu do stanu początkowego?

3. Z kolei interakcja między komputerami i ludźmi (lub ludźmi za pośrednictwem komputerów) wiąże się z brakiem determinizmu, gdy tymczasem komputery działają deterministycznie (automatycznie).

Aby wyjaśnić te paradoksy, musimy dobrze rozumieć na czym polega przepływ sterowania, co to jest stan komputera oraz jak wygląda automatyzm działania w przypadku interakcji z otoczeniem.

 

1. Przepływ sterowania. Co to jest sterowanie w komputerze? Człowiek myśli sekwencyjnie (po kolei) i tak tworzy programy. Każe komputerowi wykonywać kolejne instrukcje programu. Wskazanie na aktualnie wykonywaną instrukcję nazywa się potocznie sterowaniem. Każdy program kiedyś się zaczyna i zazwyczaj kiedyś się kończy. Początek to przejście sterowania do pierwszej instrukcji. Koniec – to przejście do instrukcji zakończenia (stop). Jeśli w programie pojawi się instrukcja warunkowa (if) – sterowanie może zmieniać się zależnie od sprawdzanego warunku. W programie mogą też występować pętle – a więc powrót do wcześniej wykonywanych instrukcji. W pętli następuje powtarzanie bloku tych samych instrukcji dopóki nie wystąpią warunki zakończenia pętli. Programy, które nigdy się nie zatrzymują (jakaś pętla nigdy się nie kończy) zazwyczaj uważa się za błędne.

2. Pojęcie stanu. Programy działają na zmiennych – czyli odczytują i zmieniają stan pamięci komputera. Stan komputera – rozumiany jako zawartość pamięci (łącznie z zapamiętanym sterowaniem) może być identyczny w różnych momentach (przynajmniej w zakresie istotnym dla programu). Skutkiem działania programu jest przejście systemu komputerowego od jednego stanu (początkowego dla programu) do drugiego (końcowego dla tego programu). Kolejne kroki tego „przechodzenia” wiążą się z wykonywaniem kolejnych instrukcji (przepływ sterowania). Ten sam program lub jego fragment może być uruchamiany wielokrotnie i zawsze będzie działał tak samo o ile uzyska takie same dane.

3. Interakcja z otoczeniem. Nie da się cofnąć operacji drukowania kartki. Tak – ale stan kartki nie wyznacza stanu komputera, tylko otoczenia w którym on funkcjonuje. Powyższy opis sterowania i stanu (pamięci) dotyczył świata komputerów, a nie świata w którym komputer działa!

4. Automatyzm i determinizm. Gdy dane do komputera wprowadza człowiek, komputer nie ma wpływu na to co odczytuje. Jednak programista musiał przewidzieć różne możliwości i komputer nie może znaleźć się wskutek odczytania danych w innym stanie, niż to wynika z jego konstrukcji (działania programu). Indeterminizm dotyczy wyłącznie świata zewnętrznego. Interakcja z programem nie może zmieniać zasad działania ustalonych przez programistę! To odróżnienie jest ważne i obowiązuje zawsze – nawet w przypadku systemów sterujących różnymi urządzeniami – gdy komputer odczytuje informacje na temat zewnętrznych skutków generowanych sygnałów.

  Sterowanie Stan (dane)

Maszyna

Automatyzm / determinizm

Trwałość – możliwość powrotu do stanu początkowego

Człowiek

Wolna wola / indeterminizm

Jednokierunkowe zmiany w czasie

Interakcja

Sposób reakcji na dowolne zmiany otoczenia nie jest swobodny ale zdeterminowany strukturą programu (zdefiniowany przez programistę).

Trwałe zmiany dotyczą otoczenia, a nie wnętrza komputera.

Opisane aspekty programów: sterowanie, dane, interakcja - wyczerpują w całości zagadnienie przepływów w programach. Wiele idei, jakie powstały w dziedzinie tworzenia oprogramowania to realizacja różnych pomysłów na to jak sobie radzić z przepływami w tych trzech aspektach.

PS.
Powyższy fragment eseju o filozofii programowania został przygotowany na potrzeby modularnego kursu programowania: http://otwartaedukacja.pl/programowanie