Klasyka programowania w świecie Linuksa
W świecie Linuksa, gdzie królują nowoczesne języki jak Python, Rust czy Go, warto czasem spojrzeć wstecz i przypomnieć sobie fundamenty, na których budowano współczesne podejście do programowania. Pascal i Modula-2 to dwa języki, które odegrały istotną rolę w historii informatyki, szczególnie w edukacji i systemach operacyjnych. Choć dziś nie są już powszechnie używane, ich wpływ na strukturę kodu, modularność i dobre praktyki programistyczne jest nie do przecenienia. W tym wpisie przyjrzymy się bliżej tym dwóm językom, porównując ich cechy, filozofię projektową oraz zastosowanie w środowisku Linuksa.

Pascal kontra Modula-2 – podobieństwa, różnice i praktyka
Geneza i filozofia
- Pascal został stworzony przez Niklausa Wirtha w 1970 roku jako język edukacyjny, mający nauczyć studentów strukturalnego programowania. Jego składnia jest przejrzysta, a struktura programu wymusza logiczne myślenie.
- Modula-2, również autorstwa Wirtha, pojawił się dekadę później jako odpowiedź na ograniczenia Pascala. Język ten wprowadził koncepcję modułów, lepsze wsparcie dla programowania systemowego i większą elastyczność.
Struktura i modularność
- Pascal operuje głównie na procedurach i funkcjach, bez natywnego wsparcia dla podziału kodu na niezależne jednostki.
- Modula-2 wprowadza moduły jako podstawowy element organizacji kodu, co czyni go bardziej odpowiednim do większych projektów i systemów operacyjnych – w tym również tych opartych na Linuksie.
Kompilatory i wsparcie w Linuksie
- Pascal ma kilka aktywnych kompilatorów dostępnych na Linuksa, takich jak Free Pascal czy GNU Pascal, które umożliwiają tworzenie aplikacji konsolowych, GUI, a nawet gier.
- Modula-2 jest mniej popularny, ale nadal dostępny dzięki projektom takim jak GNU Modula-2 czy Mocka, choć jego ekosystem jest znacznie skromniejszy.
⚙️ Zastosowanie praktyczne
- Pascal świetnie sprawdza się w nauce programowania, tworzeniu narzędzi edukacyjnych i prostych aplikacji.
- Modula-2, dzięki swojej modularności i lepszej kontroli nad sprzętem, był wykorzystywany w projektach systemowych – np. w systemie operacyjnym Lilith, stworzonym przez ETH Zurich.
Modula-2 to „młodszy brat Pascala”, też autorstwa Niklausa Wirtha. Na pierwszy rzut oka kod wygląda bardzo podobnie, ale różnice są głębokie: Modula-2 powstała, żeby naprawić ograniczenia Pascala i nadać językowi bardziej modułową, systemową i praktyczną naturę.
Oto tabelka z różnicami:
Cecha / aspekt | Pascal | Modula-2 |
---|---|---|
Modularność | Brak prawdziwych modułów – są tylko jednostki programowe (w standardowym Pascalu nawet tego nie ma, dopiero w Turbo Pascalu pojawiły się unit ). | Wbudowany system MODULE / DEFINITION MODULE / IMPLEMENTATION MODULE – czysta separacja interfejsu od implementacji. |
Zakres użycia | Głównie język nauczania i akademicki, rzadziej do systemów operacyjnych. | Projektowany do programowania systemowego (np. OS Lilith, później Oberon). |
Typy liczbowe | integer , real , boolean , char (proste). | Bogatsze: CARDINAL , INTEGER , LONGCARD , LONGINT , REAL , LONGREAL , CHAR , BOOLEAN , SET . |
Sterowanie wejściem/wyjściem | Wbudowane procedury read , write (Turbo Pascal: readln , writeln ). | Brak I/O w języku! Standardowe wejście/wyjście jest w oddzielnym module InOut . |
Zakres zmiennych | Zmienna globalna → widoczna wszędzie w jednostce. | Zmienna globalna w module → widoczna tylko w module (ukryta), eksportowana tylko jeśli zadeklarowana w DEFINITION MODULE. |
Procedury i funkcje | Można definiować, funkcje mogą zwracać wartości. | Podobnie, ale można przekazywać procedury jako parametry (procedural variables). |
Wskaźniki i dynamiczna pamięć | Ograniczone wsparcie (np. w standardowym Pascalu brak dispose , dopiero w Turbo Pascalu). | Wbudowane wskaźniki (POINTER TO ) i alokacja dynamiczna (NEW , DISPOSE ). |
Sterowanie przepływem | for , while , repeat , case . | Te same plus korutyny (TRANSFER między procesami). |
Import/eksport symboli | Brak w standardowym Pascalu (dopiero w Turbo Pascalu unit interface/implementation ). | Jasne reguły: FROM module IMPORT identyfikator . |
Bezpieczeństwo typów | Silne, ale z wyjątkami (np. w Turbo Pascalu łatwo było robić casty). | Jeszcze bardziej rygorystyczne – brak automatycznych konwersji między INTEGER a CARDINAL . |
Cel projektowy | Nauka programowania, prosty kompilator. | Budowa modułowych systemów operacyjnych i kompilatorów. |
Przykładowe kody programu w języku Modula-2
DEFINITION MODULE Stack;
CONST
MaxSize = 100;
TYPE
Index = CARDINAL;
Item = INTEGER;
PROCEDURE Push(x : Item);
PROCEDURE Pop(VAR x : Item);
PROCEDURE IsEmpty() : BOOLEAN;
PROCEDURE IsFull() : BOOLEAN;
END Stack.
----------------------------
IMPLEMENTATION MODULE Stack;
VAR
data : ARRAY [0..MaxSize-1] OF Item;
top : Index;
PROCEDURE Push(x : Item);
BEGIN
IF top < MaxSize THEN
data[top] := x;
INC(top);
ELSE
HALT; (* przepełnienie stosu *)
END;
END Push;
PROCEDURE Pop(VAR x : Item);
BEGIN
IF top > 0 THEN
DEC(top);
x := data[top];
ELSE
HALT; (* próba zdjęcia z pustego stosu *)
END;
END Pop;
PROCEDURE IsEmpty() : BOOLEAN;
BEGIN
RETURN top = 0;
END IsEmpty;
PROCEDURE IsFull() : BOOLEAN;
BEGIN
RETURN top = MaxSize;
END IsFull;
BEGIN
top := 0; (* inicjalizacja modułu *)
END Stack.
----------------------------
MODULE Main;
FROM InOut IMPORT WriteString, WriteLn, WriteCard;
FROM Stack IMPORT Push, Pop, IsEmpty;
VAR
value : INTEGER;
BEGIN
Push(10);
Push(20);
Push(30);
WHILE NOT IsEmpty() DO
Pop(value);
WriteString("Pobrano: ");
WriteCard(value, 0);
WriteLn;
END;
END Main.