|
|
Ten artykuł trzeba dopracować zgodnie z zaleceniami edycyjnymi:
Przykłady wymagają rewizji oraz uporządkowania.
Dokładniejsze informacje o tym, co trzeba poprawić, być może leżą na stronie dyskusji tego artykułu.
Po wyeliminowaniu niedoskonałości prosimy usunąć szablon {{Dopracować}} z kodu tego artykułu. |
Ada to strukturalny, kompilowany, imperatywny, statycznie typowany oraz obiektowy język programowania opracowany przez Jean Ichbiaha oraz zespół z CII Honeywell Bull w latach 70. XX wieku. Język ten wygrał konkurs zorganizowany przez Departament Obrony USA (U.S. Department of Defense – DoD), pokonując 19 innych projektów. Nazwa języka, nadana przez DoD, pochodzi od imienia lady Augusty Ady Lovelace, uważanej za pierwszą programistkę w historii.
Historia
W latach 70. departament obrony USA dostrzegł problem polegający na wykorzystywaniu dużej liczby wielorakich języków programowania używanych do implementacji wewnętrznych projektów informatycznych dla systemów wbudowanych. Wiele z nich było już przestarzałych albo mocno związanych ze sprzętem, a żaden z nich nie wspierał bezpiecznego programowania modułowego. W 1975 roku była powołana grupa robocza High Order Language Working Group (HOLWG), której zadaniem była redukcja liczby używanych narzędzi albo zaprojektowanie nowego języka programowania, który spełniałby wymagania wszystkich dotychczas realizowanych projektów. Efektem działań grupy był język Ada, a liczba używanych języków spadła z ponad 450 w roku 1983 do 37 w 1996.
Grupa robocza HOLWG rozpoczęła prace od wydania Wymagań językowych Stellmana (ang. Steelman Language Requirements), serii dokumentów opisujących założenia, które poszczególne języki programowania powinny spełniać. Następnie dokonano formalnej weryfikacji wielu istniejących języków, lecz w 1977 stwierdzono, że każdy z nich ma w świetle tych dokumentów poważne mankamenty, które go eliminują. Wobec tego ogłoszony stał się konkurs na stworzenie nowego języka. Do startu zaproszono cztery zespoły, którym nadano oznaczenia kolorystyczne:
W kwietniu 1978, po publicznych badaniach, propozycje zespołu czerwonego oraz zielonego przeszły do kolejnej fazy. Rok później ostateczne zwycięstwo przyznano koncepcji zielonej opracowanej przez CII Honeywell Bull. Otrzymała ona nazwę Ada na cześć lady Augusty Ady Lovelace, uważanej za pierwszą programistkę w historii. Zwycięska propozycja czerpała pomysły z języka LIS, który Ichbiah oraz jego grupa zaprojektowali w latach 70. Pierwsze wydanie dokumentacji języka Ada było opublikowane w ACM SIGPLAN Notices w czerwcu 1979 roku. Dokumentacja standardu wojskowego była zatwierdzona 10 grudnia 1980 roku (urodziny Ady Lovelace) oraz otrzymała numer MIL-STD-1815.
W roku 1981 C. A. R. Hoare skrytykował Adę w swojej mowie podczas odbioru Nagrody Turinga jako język zbyt skomplikowany, a przez to zawodny, lecz później prawdopodobnie zmienił zdanie, czego wyrazem jest przedmowa, którą napisał dla podręcznika Ady.
Pojawienie się Ady wywołało duże zainteresowanie wśród społeczności programistów w pierwszych latach swojego istnienia. Wśród zwolenników pojawiały się opinie, że może ona zostać podstawowym językiem programowania ogólnego przeznaczenia. Jean Ichbiah publicznie stwierdził, że w przeciągu 10 lat na rynku pozostaną zaledwie dwa języki: Ada oraz Lisp. Wczesne kompilatory Ada z trudem radziły sobie z implementacją dużego, złożonego języka, a wydajność zarówno generowanego kodu, jak oraz procesu kompilacji, analogicznie jak jakość narzędzi, pozostawiały wiele do życzenia. Twórcy kompilatorów skierowali swoje wysiłki ku uzyskaniu certyfikacji ACVC wymaganej przez agencje rządowe. Pierwszą certyfikowaną implementacją Ady był translator NYU Ada/Ed, który uzyskał ten status 11 kwietnia 1983 roku. Był on zaimplementowany w wysokopoziomowym języku SETL.
W 1987 roku Departament Obrony USA wydał zarządzenie wymagające użycia Ady w każdym projekcie programistycznym, gdzie nowy kod stanowił więcej niż 30% ogólnego wyniku, aczkolwiek wielokrotnie zezwalano na wyjątki od tej reguły. Reguła była zniesiona 10 lat później.
Przez lata 80. oraz 90. poprawiono ogólną jakość oraz wydajność kompilatorów Ady, lecz wciąż pojawiały się poważne problemy na drodze do pełnego wykorzystania możliwości języka. Jednym z nich był zaproponowany model wielozadaniowości, który znacząco odbiegał od dotychczasowych rozwiązań znanych programistom. Z uwagi na obecność kluczowych mechanizmów bezpieczeństwa, Ada jest aktualnie używana nie tylko w aplikacjach wojskowych, ale także w projektach komercyjnych, gdzie błąd programistyczny może posiadać kosztowne konsekwencje. Przykładami takich obszarów jest kontrola lotów, awionika samolotów, satelity, automatyczne systemy transportowe czy bankowość. Przykładowo, oprogramowanie systemu Fly-by-wire w samolocie Boeing 777 było w całości napisane w Adzie.
Właściwości
Ada jest wieloparadygmatowym językiem programowania ogólnego przeznaczenia. Jego składnia była zaprojektowana w taki sposób, aby zminimalizować szanse popełnienia trudnych do wykrycia błędów. Uzyskiwane jest to poprzez przemyślany oraz konsekwentny dobór poszczególnych elementów składni, a także ich jednoznaczność.
Wśród kluczowych właściwości języka da się wymienić:
- bezpieczny, ścisły system typów, nastawiony na semantykę, a nie na fizyczną reprezentację danych,
- wsparcie dla programowania obiektowego,
- zaawansowany mechanizm pakietów oraz modułów,
- wsparcie dla zaawansowanych modeli współbieżności,
- mechanizmy zarządzania pamięcią,
- wsparcie dla programowania kontraktowego,
- ustandaryzowane interfejsy do łączenia kodu Ady z językami C, C++, FORTRAN oraz COBOL.
Standaryzacja
Język stał się standardem ANSI w 1983 roku (ANSI/MIL-STD 1815A), a następnie bez żadnych dodatkowych modyfikacji — standardem ISO w 1987 roku (ISO-8652:1987). Ustandaryzowana wersja języka jest powszechnie nazywana Ada 83 albo Ada 87, zależnie od tego, którą datę ogłoszenia standardu weźmiemy.
Wspólny standard ANSI/ISO (ISO-8652:1995) Ada 95 stał się opublikowany w lutym 1995 roku, przez co Ada stała się pierwszym obiektowo zorientowanym, ustandaryzowanym językiem programowania. Aby pomóc w dopracowaniu oraz przyjęciu standardu, US Air Force sfinansowała prace nad kompilatorem GNAT. Aktualnie GNAT jest częścią pakietu GNU Compiler Collection.
Prace nad standaryzacją Ady są nieustannie kontynuowane. W październiku 2001 ukazała się techniczna errata do standardu Ada 95, a w 2007 — pierwsza znacząca poprawka ISO/IEC 8652:1995/Amd 1:2007. Nowy, ujednolicony tekst standardu stał się opublikowany 9 marca 2007 roku. Ukończenie kolejnej rewizji jest planowane na rok 2012 (ISO/IEC 8652:201z Ed. 3).
Przykłady
Oto prosty przykład (funkcja Ackermanna) kodu w Adzie demonstrujący parę jej cech. Program, żeby się skompilować, musi być umieszczony w pliku "ackermann.adb" (wielkość liter bez znaczenia).
with Ada.Command_Line; use Ada.Command_Line;
with Gnat.Io; use Gnat.Io;
procedure Ackermann is
function Ack (x, y : in Integer) return Integer
is
begin
if (x = 0) then
return y + 1;
elsif (y = 0) then
return Ack (x - 1,1);
else
return Ack (x - 1, Ack (x, y - 1));
end if;
end Ack;
x,y,a : Integer;
begin
if (Argument_Count = 2) then
x := Integer'Value (Argument (1));
y := Integer'Value (Argument (2));
elsif (Argument_Count = 1) then
x := 3;
y := Integer'Value (Argument (1));
else
x := 3;
y := 3;
end if;
a := Ack (x, y);
Put ("Ack (");
Put (x);
Put (",");
Put (y);
Put (") = ");
Put (a);
New_Line;
end Ackermann;
Można zauważyć, że:
- Wszystkie nazwy są nieczułe na wielkość znaków.
- Cały program to jedna wielka procedura, która może zawierać podprocedury (w tym wypadku funkcję ack).
- Wszystkie zamknięcia są zapisywane za pomocą end co_zamykamy. Umożliwia to uniknąć przypadkowych pomyłek, ale w opinii wielu programistów jest nadmiarowe.
- Przypisanie jest zapisywane " := " , natomiast porównanie przez " = " . Argumentuje się to tym, że w C są pomyłki polegające na zapisie " = " zamiast właściwego " == " .
- Nie ma odpowiednika funkcji printf, uważanej za niebezpieczną. Chociaż funkcje " Put " oraz " New_Line " (z modułu " Gnat.Io ") są bezpieczniejsze, są bardzo niewygodne w użyciu.
- " elsif " pisze się łącznie nie zaś oddzielnie jak w C. Jest to pewne usprawnienie, używane przez przeważajaca ilość nowych języków.
- Składnie atrybutów to obiekt'atrybut (lub klasa'atrybut), zamiast bardziej tradycyjnych selekcji " . " czy " :: " .
- Rzutowania są przeprowadzane składnią Klasa'Value(wartość). Jest to znaczne ulepszenie wobec C, gdzie (klasa)wartość prowadzi do niepewnej kolejności wykonywania działań oraz zwykle w większych wyrażeniach jest zapisywane jako ((klasa)(wartość)).
- Występuje rozróżnienie "procedur" (w nomenklaturze C: funkcje niezwracające wartości) oraz "funkcji" (w nomenklaturze C: funkcje zwracające wartość). Przeważajaca ilość współczesnych języków nie zawiera tego rozróżnienia.
Wartościowanie leniwe
Operatorami short circuit nazywamy takie, które nie są obliczane jeśli nie jest to konieczne. Inną nazwą jest tego rodzaju jest wartościowanie leniwe.
W Adzie są następujące konstrukcje:
- A or B
- Obliczane jest A
- Jeśli A jest prawdziwe, obliczane jest B. Niezależnie od wyniku B, wynik wyrażenia to "prawda".
- Jeśli A jest fałszywe, obliczane jest B. Jeśli B jest prawdziwe, wynik to "prawda", w przeciwnym razie "fałsz".
- A or else B
- Obliczane jest A
- Jeśli A jest prawdziwe, wynik to "prawda", a B nie jest obliczane.
- Jeśli A jest fałszywe, obliczane jest B. Jeśli B jest prawdziwe, wynik to "prawda", w przeciwnym razie "fałsz".
- A and B
- Obliczane jest A
- Jeśli A jest prawdziwe, obliczane jest B. Jeśli B jest też prawdziwe, wynik to "prawda", w przeciwnym razie fałsz.
- Jeśli A jest fałszywe, obliczane jest B, ale niezależnie od wyniku B, wynik wyrażenia to fałsz.
- A and then B
- Obliczane jest A
- Jeśli A jest prawdziwe, obliczane jest B. Jeśli B jest też prawdziwe, wynik to "prawda", w przeciwnym razie "fałsz".
- Jeśli A jest fałszywe, wynik to "fałsz", a B nie jest obliczane.
Przykład ("short_circuit.adb"):
with Text_IO, Ada.Integer_Text_IO;
use Text_IO, Ada.Integer_Text_IO;
procedure Short_Circuit is
function Is_Odd (i : Integer) return Boolean
is
begin
Put ("Testing");
Put (i);
New_Line;
return ((i / 2) * 2) /= i;
end;
begin
Put_Line ("Testing if ""5 and 6"" are odd");
if (Is_Odd (5) and Is_Odd (6)) then
Put_Line ("True");
else
Put_Line ("False");
end if;
Put_Line ("Testing if ""5 or 6"" are odd");
if (Is_Odd (5) or Is_Odd (6)) then
Put_Line ("True");
else
Put_Line ("False");
end if;
Put_Line ("Testing if ""5 and then 6"" are odd");
if (Is_Odd (5) and then Is_Odd (6)) then
Put_Line ("True");
else
Put_Line ("False");
end if;
Put_Line ("Testing if ""5 or else 6"" are odd");
if (Is_Odd (5) or else Is_Odd (6)) then
Put_Line ("True");
else
Put_Line ("False");
end if;
Put_Line ("Testing if ""6 and 5"" are odd");
if (Is_Odd (6) and Is_Odd (5)) then
Put_Line ("True");
else
Put_Line ("False");
end if;
Put_Line ("Testing if ""6 or 5"" are odd");
if (Is_Odd (6) or Is_Odd (5)) then
Put_Line ("True");
else
Put_Line ("False");
end if;
Put_Line ("Testing if ""6 and then 5"" are odd");
if (Is_Odd (6) and then Is_Odd (5)) then
Put_Line ("True");
else
Put_Line ("False");
end if;
Put_Line ("Testing if ""6 or else 5"" are odd");
if (Is_Odd (6) or else Is_Odd (5)) then
Put_Line ("True");
else
Put_Line ("False");
end if;
end Short_Circuit;
W przykładzie widać też użycie podwójnego znaku "" dla zaznaczenia " w łańcuchu. Umożliwia to obycie się bez skomplikowanych oraz podatnych na błędy zasad escape'owania znaków. W C taka składnia byłaby niemożliwa albowiem C dopuszcza napisać "łańcuch 1" "łańcuch 2" (z rozdzielającymi spacjami albo bez), co oznacza to samo co "łańcuch 1łańcuch 2" oraz jest przydatne w preprocessingu.
Oto przykład programu wyświetlającego zawartość plików na ekran. Jako argumenty podawane z linii poleceń program przyjmuje nazwy plików. W razie podania błędnej wzniesie flagę błędu.
with Ada.Text_Io;
use Ada.Text_Io;
with Ada.Integer_Text_Io;
use Ada.Integer_Text_Io;
with Ada.Command_Line;
use Ada.Command_Line;
with Ada.Strings.Unbounded;
use Ada.Strings.Unbounded;
procedure Cat is
Plik : File_Type;
Litera : Character;
LiczbaArgumentow : Natural;
Nazwa : Unbounded_String;
begin
if (Argument_Count /= 0) then
LiczbaArgumentow := Argument_Count;
Put ("Podales do programu: ");
Put (Command_Name);
Put (" argumenty");
New_Line;
for ThisArgument in 1 .. LiczbaArgumentow loop
Put ( "Numer argumentu: ");
Put (ThisArgument);
Put (" jest nim: ");
Put (Argument(ThisArgument));
New_Line;
end loop;
for ThisArgument in 1 .. LiczbaArgumentow loop
Nazwa := To_Unbounded_String (Argument (ThisArgument));
Open (Plik, In_File, To_String (Nazwa));
New_Line;
Put ("Nastepny plik o nazwie: ");
Put (Argument (ThisArgument));
New_Line (2);
loop
exit when End_Of_File (Plik);
Get (Plik, Litera);
Put (Litera);
if End_Of_Line (Plik) then
New_Line;
end if;
end loop;
Close (Plik);
end loop;
else
Put ("Nie podales argumentow");
end if;
end Cat;
Program wykorzystuje z biblioteki Ada.Command_Line, która służy do obsługi linii poleceń.