o wyższości javy nad loglanem
DESCRIPTION
O wyższości Javy nad Loglanem. czyli o zasadach widoczności atrybutów i metod gdy w języku mamy i dziedziczenie i zawieranie modułów. Co oznacza identyfikator id ?. Znaczenie identyfikatora jest zasadniczą sprawą dla rozumienia programu. - PowerPoint PPT PresentationTRANSCRIPT
O wyższości Javy nad Loglanem
czylio zasadach widoczności atrybutów i
metod
gdy w języku mamy i dziedziczenie i zawieranie modułów
2
Co oznacza identyfikator id?
Znaczenie identyfikatora jest zasadniczą sprawą dla rozumienia programu.
W programie identyfikator idnt może występować wiele razy i w różnych znaczeniach.
Zacznijmy od zróżnicowania wystąpień idenyfikatora na wystąpienia definiujące czyli deklaracje identyfikatora, oraz na wystąpienia aplikacyjne.
Deklaracja określa rodzaj i typ identyfikatora np. zmienna typu integer, funkcja zwracająca wartośc boolowską o trzech argumentach typu real, etc.
Inne wystąpienia identyfikatora muszą być związane z odpowiednią deklaracją by wiadomo było co znaczą.
3
Dynamiczne czy statyczne wiązanie
Sprawa jest pozornie prosta, ale mechanizmy zawierania jednego modułu w drugim, dziedziczenia modułów i przekazywania parametrów mogą ją potężnie skomplikować.
Jeżeli pewien identyfikator idnt występuje w module M razem z deklaracją tego identyfikatora, to oczywiście znaczenie identyfikatora idnt jest opisane w deklaracji zawartej w tym module. Gorzej jest gdy moduł M nie zawiera deklaracji identyfikatora idnt. Czytelnik programu (człowiek) i kompilator powinni zastosować taki sam algorytm odszukiwania deklaracji identyfikatora.
W jednym z najwcześniejszych języków programowania, w LISPie poszukiwania odbywają się wzdłuż łańcucha dynamicznych ojców. Nie wchodząc na razie w szczegóły stwierdźmy, że znaczenie identyfikatora ustalane jest podczas wykonywania programu. Oznacza to niemożność przeprowadzenia analizy programu bez jego wykonania, gorzej różne wykonania tego samego programu mogą mieć różne znaczenia.
4
pouczająca historia
Język LISP wyszedł dziś z użycia, przywiązani do niego programiści posługują się dziś językiem SCHEME. Składnia tych dwu języków jest identyczna, różnica polega tylko i aż na statycznym wiązaniu wystąpień aplikacyjnych z deklaracjami funkcji. (Lisp i Scheme są językami programowania funkcyjnego.)
W języku Scheme znaczeniem nazwy funkcji nielokalnej jest ta którą znajduje się w module obejmującym moduł zawierający wystąpienie aplikacyjne identyfikatora funkcji.
W Lispie nazwa funkcji nielokalnej szukana jest w rekordzie aktywacji funkcji, która wywołała funkcję aktualnie wykonywaną. Czyli znaczenie zależy od historii obliczenia.
6
PrzykładProgram SDBinding; unit A: class; var x: integer; end A; unit B: A class; unit G: class; begin writeln(x) end G; unit C: A class; unit H: G class; begin writeln(x) end H; var gg: G, hh: H begin x := 2; gg := new G; hh := new H; end C; var cc: C begin x := 1; cc := new C End B;Var bb: BBegin bb := new BEnd
Co zostanie wydrukowane?
7
Drzewo zawierania modułów
main
A B
x G C
H
8
Las dziedziczenia modułów
main
A B
G C
H
9
Graf zawierania i dziedziczenia modułów
main
A B
x G C
H
10
Historia wykonania 1/6
main
Unit A: class; var x: integerend A
Unit B: A class; ...end B
Bb: b
Bb := new b
Na początku mamy jednostkę Dynamiczną rekord aktywacjiprogramu Main
11
Historia wykonania 2/6
main
Unit A: class; var x: integerend A
Unit B: A class; ...end B
Bb: B
Bb := new b
SLx : integer 1unit G: class; ...unit C: A class ...cc: C x := 1 Cc := new C
B
Teraz procesor wykonuje konstruktor obiektu bb klasy B
12
Historia wykonania 3/6
main
Unit A: class; var x: integerend A
Unit B: A class; ...end B
Bb: B
Bb := new b
SLx : integer = 1 Aunit G: class; ...unit C: A class ...cc: C x := 1 Cc := new C
B
SLx: integer = 2 Aunit H: G class ......Hh: Hgg: G
x := 2;gg := new G;hh := new H;
C
Teraz procesor wykonuje konstruktor obiektu cc klasy C
13
Historia wykonania 4/6
main
Unit A: class; var x: integerend A
Unit B: A class; ...end B
Bb: B
Bb := new b
SLx : integer = 1 Aunit G: class; ...unit C: A class ...cc: C x := 1 Cc := new C
B
SLx: integer = 2 Aunit H: G class ......Hh: Hgg: G
x := 2;gg := new G;hh := new H;
SL
writeln(x)
C
GSkąd odczytać x? Jeśli wg SL, to wydrukuje się 1
14
Historia wykonania 4a/6
main
Unit A: class; var x: integerend A
Unit B: A class; ...end B
Bb: B
Bb := new b
SLx : integer = 1 Aunit G: class; ...unit C: A class ...cc: C x := 1 Cc := new C
B
SLx: integer = 2 Aunit H: G class ......Hh: Hgg: G
x := 2;gg := new G;hh := new H;
SL DL
writeln(x)
C
GSkąd odczytać x? Wg DL wydrukuje się 2
15
Historia wykonania 5/6
main
Unit A: class; var x: integerend A
Unit B: A class; ...end B
Bb: B
Bb := new b
SLx : integer = 1 Aunit G: class; ...unit C: A class ...cc: C x := 1 Cc := new C
B
SLx: integer = 2 Aunit H: G class ......Hh: Hgg: G
x := 2;gg := new G;hh := new H;
SL
writeln(x)
SL
writeln(x); G
writeln(x)
H
GA co teraz? Ta instr. odziedziczona z G
16
Historia wykonania 6/6
main
Unit A: class; var x: integerend A
Unit B: A class; ...end B
Bb: B
Bb := new b
SLx : integer = 1 Aunit G: class; ...unit C: A class ...cc: C x := 1 Cc := new C
B
SLx: integer = 2 Aunit H: G class ......Hh: Hgg: G
x := 2;gg := new G;hh := new H;
SL
writeln(x)
SL
writeln(x); G
writeln(x)
H
G
A co teraz? Powinno być 2
17
Historia wykonania
program semiStaticBinding; unit A: class; var x: integer begin writeln(" w warstwie A, x= ",x) end A;
unit B: A class; unit G: class; begin writeln(" w warstwie G tego obiektu x= ",x:3) end G; unit C: A class; unit H: G class;begin writeln("w warstwie H tego obiektu x= ",x:3); end H; var gg: G, hh: H; begin x := 2; writeln(" w obiekcie klasy C wykonano x := 2"); writeln(" tworze obiekt klasy G, G zawarte w B "); gg := new G; writeln(" tworze obiekt klasy H, H zawarte w C, dziedziczy z G"); hh := new H; end C; var cc: C; begin x := 1; writeln(" w obiekcie klasy B wykonano x := 1"); writeln(" tworze obiekt klasy C, C dziedziczy z A, jest zawarte w B"); cc := new C; end B; var bb: b;begin writeln("This is semistatic semantic of inheritance: 1, 2, 2"); writeln(" tworze obiekt klasy B, B dziedziczy z A"); bb := new B; writeln(" end of example semiStatic semantic");end
Wykonanie tego programu daje
This is semistatic semantic of inheritance: 1, 2, 2
tworze obiekt klasy B, B dziedziczy z A
w warstwie A, x= 0
w obiekcie klasy B wykonano x := 1
tworze obiekt klasy C, C dziedziczy z A, jest zawarte w B
w warstwie A, x= 0
w obiekcie klasy C wykonano x := 2
tworze obiekt klasy G, G zawarte w B
w warstwie G tego obiektu x= 1
tworze obiekt klasy H, H zawarte w C, dziedziczy z G
w warstwie G tego obiektu x= 2
w warstwie H tego obiektu x= 2
end of example semistatic semantic
Obejrzyjmy teraz odpowiedni program w Javie
file:///c|/andrzej/progobi/staticbinding.java.sdw
Wyniki programu w Javie
Wyniki:
Wnioski• Java ma lepszą semantykę dziedziczenia
zagnieżdżonych klas – static binding,• Loglan prezentuje semantykę semi-static
binding,• w zastosowaniach różnicy nie widać (przykład jest
chyba bardziej skomplikowany niż potrzeby zastosowań)
• w 1993 prof. A. Kreczmar zbudował maszynę wirtualną Loglanu z semantyką static binding,
• są w Javie możliwości o jakich się programistom nie śniło!