Ada (informatyka)
Z Wikipedii
Ada to strukturalny, kompilowany, statycznie typowany język programowania opracowany przez Jean Ichbiaha i zespół z CII Honeywell Bull w latach 70. XX wieku. Język ten wygrał konkurs zorganizowany przez Departament Obrony - DoD USA, pokonując 19 innych projektów. Nazwa języka, nadana przez DoD, pochodzi od nazwiska lady Augusty Ady Lovelace, uważanej za pierwszą programistkę w historii.
[edytuj] Właściwości języka
Wiele cech Ady zaprojektowanych zostało w celu zminimalizowania szans popełnienia trudnych do wykrycia błędów.
Istnieją trzy standardy Ady: starszy Ada 83, nowszy Ada 95 (w którym dodano m.in. obsługę obiektów) oraz najnowszy Ada 2005. Istniała też Ada++.
Ada jest obsługiwana m.in. przez kompilator GNAT, oparty na GCC.
Ponieważ wiele rzeczy w Adzie jest zaprojektowane wbrew tradycji uniksowej, nie cieszy się ona popularnością wśród programistów uniksowych (w szczególności wśród programistów open source). Do nielicznych programów open source napisanych w Adzie należy wizualny debuger GNU Visual Debugger (GVD).
Istnieją warianty języka ADA (SPARK) posiadające funkcje formalnej weryfikacji oraz dowodzenie poprawności kodu. Dzięki swoim właściwościom język ADA jest wykorzystywany w dziedzinach, w których krytyczna jest stabilność kodu oraz brak błędów logicznych i programistycznych - w wojsku, medycynie, energetyce itd.
Oto prosty przykład (funkcja Ackermanna) kodu w Adzie demonstrujący kilka 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. Pozwala 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 występują pomyłki polegające na zapisie " = " zamiast właściwego " == " .
- Nie ma odpowiednika funkcji printf, uważanej za niebezpieczną. Chociaż funkcje " Put " i " 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 większość nowych języków.
- Składnie atrybutów to obiekt'atrybut (lub klasa'atrybut), zamiast bardziej tradycyjnych " . " 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ń i zwykle w większych wyrażeniach jest zapisywane jako ((klasa)(wartość)).
- Występuje rozróżnienie "procedur" (w nomenklaturze C: funkcje niezwracające wartości) i "funkcji" (w nomenklaturze C: funkcje zwracające wartość). Większość współczesnych języków nie zawiera tego rozróżnienia.
[edytuj] 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 występują 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, to 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 i podatnych na błędy zasad escape'owania znaków. W C taka składnia byłaby niemożliwa ponieważ C pozwala napisać "łańcuch 1" "łańcuch 2" (z rozdzielającymi spacjami lub bez), co oznacza to samo co "łańcuch 1łańcuch 2" i jest przydatne w preprocessingu. Ale co ważniejsze Ada nie ma innych użytecznych znaków specjalnych - \n, \t, \e itd.
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 korzysta z biblioteki Ada.Command_Line, która służy do obsługi linii poleceń.
ABAP • Ada • AWK • Asembler • C • C++ • C# • COBOL • Common Lisp • D • F# • Forth • Fortran • GAUSS • Icon • Java • JavaScript • Lisp • Lustre• Modula 2 • Ocaml • Oberon • Object Pascal • Objective-C • Pascal • Perl • PHP • PL/SQL • Python • REXX • Ruby • SAS 4GL • sh • Smalltalk • Snobol • SQL • Visual Basic • VB.NET • XUL
Akademickie: Comal • Eiffel • Haskell • Logo • MCPL • ML • Nemerle • Prolog • Scheme
Historyczne: ALGOL • APL • BASIC • Clipper • JAS • MUMPS • PLAN • PL/I • PL/M • SAKO • SAS (asembler) • Simula
Ezoteryczne: INTERCAL • Brainfuck • BeFunge • Unlambda • Malbolge • Whitespace • FALSE • HQ9+ • Shakespeare • Whirl • Ook