Obiektowe języki zapytań

Slides:



Advertisements
Podobne prezentacje
© K.Subieta. Obiektowe języki zapytań 13, Folia 1 czerwiec 2004 Obiektowe języki zapytań Wykładowca: Kazimierz Subieta Polsko-Japońska Wyższa Szkoła Technik.
Advertisements

Języki i środowiska programowania systemów rozproszonych, Wykład 10, Slajd Języki i środowiska programowania systemów rozproszonych Wykładowca:
Proces doboru próby. Badana populacja – (zbiorowość generalna, populacja generalna) ogół rzeczywistych jednostek, o których chcemy uzyskać informacje.
1 TREŚĆ UMOWY O PRACĘ : Umowa o pracę określa strony umowy, rodzaj umowy, datę jej zawarcia oraz warunki pracy i płacy, w szczególności: 1) rodzaj pracy,
Równowaga chemiczna - odwracalność reakcji chemicznych
OBOWIĄZKI INFORMACYJNE BENEFICJENTA Zintegrowane Inwestycje Terytorialne Aglomeracji Wałbrzyskiej.
GRUPY I ZESPOŁY © dr E.Kuczmera-Ludwiczyńska, mgr D.Ludwiczyński.
PRACA Z APLIKACJAMI SYSTEM PRZEMIESZCZANIA oraz NADZORU WYROBÓW AKCYZOWYCH EMCS PL 1.
© Kazimierz Duzinkiewicz, dr hab. inż. Katedra Inżynierii Systemów Sterowania 1 Metody optymalizacji - Energetyka 2015/2016 Metody programowania liniowego.
Excel 2007 dla średniozaawansowanych zajęcia z dnia
Metodologia tworzenia strategii wg Mirosława Gębskiego Euroinvestment.
 Czasem pracy jest czas, w którym pracownik pozostaje w dyspozycji pracodawcy w zakładzie pracy lub w innym miejscu wyznaczonym do wykonywania pracy.
Literary Reference Center Przewodnik
EWALUACJA PROJEKTU WSPÓŁFINANSOWANEGO ZE ŚRODKÓW UNII EUROPEJSKIE J „Wyrównywanie dysproporcji w dostępie do przedszkoli dzieci z terenów wiejskich, w.
EWALUACJA JAKO ISTOTNY ELEMENT PROJEKTÓW SYSTEMOWYCH Sonia Rzeczkowska.
Zmienne losowe Zmienne losowe oznacza się dużymi literami alfabetu łacińskiego, na przykład X, Y, Z. Natomiast wartości jakie one przyjmują odpowiednio.
Algorytmy Informatyka Zakres rozszerzony
Opodatkowanie spółek Podziały Spółek. Podziały spółek Rodzaje podziałów wg KSH Przewidziane są cztery sposoby podziału: 1) podział przez przejęcie, który.
KOSZTY W UJĘCIU ZARZĄDCZYM. POJĘCIE KOSZTU Koszt stanowi wyrażone w pieniądzu celowe zużycie majątku trwałego i obrotowego, usług obcych, nakładów pracy.
Menu Jednomiany Wyrażenia algebraiczne -definicja Mnożenie i dzielenie sum algebraicznych przez jednomian Mnożenie sum algebraicznych Wzory skróconego.
Optymalna wielkość produkcji przedsiębiorstwa działającego w doskonałej konkurencji (analiza krótkookresowa) Przypomnijmy założenia modelu doskonałej.
Metody sztucznej inteligencji - Technologie rozmyte i neuronowe 2015/2016 Perceptrony proste nieliniowe i wielowarstwowe © Kazimierz Duzinkiewicz, dr hab.
Definiowanie i planowanie zadań typu P 1.  Planowanie zadań typu P  Zadania typu P to zadania unikalne służące zwykle dokonaniu jednorazowej, konkretnej.
Sieci przepływowe: algorytmy i ich zastosowania.
1 Definiowanie i planowanie zadań budżetowych typu B.
Renata Maciaszczyk Kamila Kutarba. Teoria gier a ekonomia: problem duopolu  Dupol- stan w którym dwaj producenci kontrolują łącznie cały rynek jakiegoś.
Wprowadzenie do baz danych. Terminologia Specyfika baz danych (1) 1.Trwałość danych –Długi czas życia – kilka, kilkadziesiąt, kilkaset lat –Niezależność.
Budżetowanie kapitałowe cz. III. NIEPEWNOŚĆ senesu lago NIEPEWNOŚĆ NIEMIERZALNA senesu strice RYZYKO (niepewność mierzalna)
Test analizy wariancji dla wielu średnich – klasyfikacja pojedyncza
Programowanie Obiektowe – Wykład 1
O ochronie danych osobowych
Schematy blokowe.
Informacja o maturze w 2018 roku
Wyznaczanie miejsc zerowych funkcji
Wytwarzanie oprogramowania sterowane przypadkami testowymi
DEFINICJA I ZASTOSOWANIE W JĘZYKU HASKELL
Podstawowe polecenia systemu
On-the-Fly Garbage Collection
Rachunki zdań Tautologiczność funkcji
Liczby pierwsze.
Części składowe treści pisma
Hermeneutyka i hermeneutyczne ujęcie prawa
ALGORYTMY I STRUKTURY DANYCH
Akademia C# lab. 9 Zdarzenia i delegaty.
Moje szczęście.
Podstawy automatyki I Wykład /2016
Programowanie obiektowe
Optymalizacja programów Open-Source
Materiały pochodzą z Platformy Edukacyjnej Portalu
Kurs języka C++ – wykład 13 ( )
Inżynieria Oprogramowania Laboratorium
Git - system kontroli wersji
Języki programowania.
Jak dostosować witrynę internetową usługi Microsoft SharePoint Online
Wyrok NSA z dnia 29 listopada 2017 r., II FSK 1633/17
Obiektowe języki zapytań
Koszyk danych.
Podstawy informatyki Zygfryd Głowacz.
Strukturalne wzorce projektowe
Zmienne i typy danych w C#
Proste obliczenia w arkuszu kalkulacyjnym
FORMUŁOWANIE HIPOTEZ STATYSTYCZNYCH
Implementacja rekurencji w języku Haskell
Znajdowanie liczb pierwszych w zbiorze
REGRESJA WIELORAKA.
Język C++ Operatory Łukasz Sztangret Katedra Informatyki Stosowanej i Modelowania Prezentacja przygotowana w oparciu o materiały Danuty Szeligi i Pawła.
Wyrok WSA w Bydgoszczy z dnia 27 października 2016 r., I SA/Bd 613/16
Program na dziś Wprowadzenie Logika prezentacji i artykułu
Autor: Magdalena Linowiecka
Obiektowe języki zapytań
Zapis prezentacji:

Obiektowe języki zapytań Wykładowca: Kazimierz Subieta Polsko-Japońska Wyższa Szkoła Technik Komputerowych, Warszawa subieta@pjwstk.edu.pl Instytut Podstaw Informatyki PAN, Warszawa subieta@ipipan.waw.pl Wykład 13: Rozszerzenie języków zapytań o konstrukcje imperatywne

Zapytania jako wyrażenia języka programowania W SBA zapytania pełnią rolę wyrażeń języka programowania. Zapytania będą również stosowane do nietrwałych danych. Inaczej mówiąc przyjęliśmy, że w naszym (hipotetycznym) języku programowania nie będzie innych wyrażeń niż zapytania. To założenie jest rewolucją w odniesieniu do języków zapytań. W SQL zapytania zagnieżdżone w język programowania mogły odwoływać się do zmiennych języka programowania poprzez specjalną składnię. Podział na wyrażenia i zapytania przyjmują języki czwartej generacji (4GL). PL/SQL system Oracle, pierwszy komercyjny język programowania w pełni zintegrowany z językiem SQL, również wprowadza podział na wyrażenia i zapytania. Powodem są ograniczenia i narzuty składniowe języka SQL, w którym nie da się bezpośrednio zapisać są tak prostych wyrażeń jak 2+2, sin(x), itd. Jest jednak oczywiste, że wyrażenia i zapytania muszą mieć niepuste przecięcie, co stawia pod znakiem zapytania ten podział.

Referencje w wynikach zapytań Okolicznością większości języków zapytań, która ogranicza ich rolę jako wyrażeń, jest to, że zapytanie może zwrócić wartość, ale nie może zwrócić referencji do pewnej danej zapamiętanej w składzie. Uniemożliwia to wykorzystanie zapytań jako składowych zdań imperatywnych, takich jak podstawienie (update w SQL) lub usuwanie (delete w SQL). Oficjalnie, SQL również nie zwraca referencji, ale zrealizowanie w nim wymienionych zdań imperatywnych świadczy o tym, że praktyka (na szczęście) rozminęła się z przyjętą oficjalnie teorią. W SBQL ten problem nie występuje.

Jak to zostało zrobione w systemie Loqis? Loqis jest prawdopodobnie pierwszym w historii systemem, w którym zrealizowano pełny język programowania oparty na języku SBQL. Loqis nie wprowadza wyrażeń innych niż zapytania. Język programowania systemu Loqis posiada zestaw cech, których pełna kombinacja nie występuje w innym języku programowania: Pełna ortogonalna trwałość, czyli brak jakichkolwiek różnic syntaktycznych i semantycznych w dostępie i operacjach na nietrwałych i trwałych danych. Pełny relatywizm obiektów w powiązaniu z relatywizmem wyrażeń języka. Identyczne mechanizmy zakresu i wiązania dla obiektów indywidualnych i dla kolekcji. Brak podziału na zapytania i wyrażenia. Dowolne wyrażenie jest także zapytaniem. Wszelkie operatory występujące tradycyjnie w wyrażeniach mogą występować także w zapytaniach. Zapytania mogą zwracać zarówno wartości (dowolnie złożone) jak i referencje do obiektów. Wyniki zapytań w SBQL mogą być specyficznymi strukturami zbudowanymi z wartości, referencji i nazw.

Zastosowania zapytań w jęz. programowania Zapytania, jako wyrażenia języka programowania, będą używane we wszystkich kontekstach w których używane są wyrażenia, w szczególności w następujących: Jako składowa zdań imperatywnych, np. instrukcji podstawienia, usuwania, tworzenia i wstawiania. Jako parametry procedur, funkcji lub metod, przy zachowaniu klasycznych metod przekazywania parametrów znanych jako wołanie przez wartość (call- by-value) oraz wołanie przez referencję (call-by-reference). Jako składnik zdania return określającego wynik procedury lub metody funkcyjnej. Jako składnik iteratora znanego jako „for each ... do ...”, określający ilość pętli iteratora oraz element przetwarzany w każdym jego cyklu.

Czy taki język nie jest utopią? Jakie zagrożenia można wiązać z realizacją języka programowania o podanych własnościach? Niska wydajność. Ale: Wiele metod optymalizacyjnych wiązanych z modelem relacyjnym ma bezpośrednie odpowiedniki dla modeli obiektowych. Np. indeksy. Dla SBQL zostały odkryte nieznane wcześniej bardzo mocne metody optymalizacyjne oparte na przepisywaniu. Trudności z wypromowaniem nowego języka programowania. Ale: Java stała się szybko popularna, mimo że nie występują w niej cechy nieznane w poprzednich językach. (Jest nową kombinacją popularnych cech.) PHP w ciągu dwóch lat zdobył miliony zwolenników. Wiele rynkowych systemów jest wyposażana w języki o bardzo specyficznych nazwach i rozwiązaniach. Użytkownikom to nie przeszkadza. Świat badawczo-rozwojowy nie może zastopować badań i rozwoju z powodu potencjalnych trudności z powszechnym wdrożeniem.

Konstrukcje deklaratywne i imperatywne Założeniem języków zapytań jest deklaratywność, czyli wyrażanie bezpośrednio celu wyszukiwania. Deklaratywność jest wiązana z programowaniem w logice, np. językami Prolog lub Datalog. Zwolennicy tego podejścia twierdzą niekiedy, że tylko wyrażenia logiki matematycznej (i pochodne) są deklaratywne. Są to próby zbudowania fałszywego stereotypu. Pseudo-naukowe bzdury. Deklaratywność wynika z psychologii, odczuć użytkownika języka, a nie z jakichkolwiek tworów formalnych. Deklaratywność nie jest celem samym w sobie - ma o tyle znaczenie, o ile skraca czas tworzenia programu, czyni go bardziej zrozumiałym, oraz zapewnia łatwiejszą i mniej kosztowną jego pielęgnację. Kluczem do deklaratywności jest uzyskanie jak najprostszego odwzorowania pojęciowego pomiędzy rzeczywistym problemem w dziedzinie przedmiotowej, a zapisem bądź rozwiązaniem tego problemu w środowisku komputerowym.

Konstrukcje deklaratywne a zmiany stanu Konstrukcje deklaratywne nie mogą (nie powinny) zmieniać stanu. Stan jest pojęciem związanym z czasem i następstwem czynności. Zmiany stanu wymagają wprowadzenia konstrukcji imperatywnych. Twórcy koncepcji opartych na programowaniu w logice starają się retuszować ten oczywisty fakt poprzez różnorodne konstrukcje. Np. w systemie LDL zastosowano "mimikrę syntaktyczną" w postaci symbolu -, który przypomina negację, ale w istocie jest konstrukcją imperatywną, której semantyką jest usunięcie pewnej danej. Obecność tego rodzaju sztuczek stawia pytanie, czy w misji zbudowania fałszywego stereotypu „programowania deklaracyjnego” niektórzy naukowcy nie posuwają się zbyt daleko, poza granicę etyki naukowej, która zabrania oszukiwania czytelników, użytkowników (i samych siebie). Z reguły, zmiany stanu są przemycane w tego rodzaju koncepcjach i językach poprzez różnorodne efekty uboczne. Te "efekty uboczne" podkopują formalną podstawę programowania w logice; powodują, że tysiące twierdzeń i wniosków udowodnionych przez armię akademickich "teoretyków" można a priori skierować do składu śmieci.

SBQL a konstrukcje imperatywne Przy rozszerzeniach SBQL będziemy starali się trzymać czystości rozdzielenia tej części języka, która nie może zmienić stanu obiektów (czyli deklaratywnych zapytań), oraz części, która będzie zajmować się zmianami stanu (czyli części imperatywnej). Efekty uboczne w zapytaniach będziemy uważać za niewskazane. Poprzez efekty uboczne wyrażenia stają się mniej czytelne, błędogenne oraz bardziej kłopotliwe podczas zmian oprogramowania; Efekty uboczne mogą zakłócić lub uniemożliwić optymalizację zapytań. Nie możemy też zabronić użycia efektów ubocznych w zapytaniach. Programista może wewnątrz zapytania wywołać funkcję lub metodę. Nie będziemy dzielić funkcji i metod w zależności od posiadania efektów ubocznych. Wprowadziłoby to zbytnią komplikację do języka i jego użycia. Efekty uboczne w zapytaniach powinny być stosowane w sytuacji pewności, że nie zakłóci to optymalizacji i nie doprowadzi do złego wyniku.

Zasada korespondencji correspondence principle Podstawowy drogowskaz przy konstruowaniu języka programowania. Zasada korespondencji mówi, że wraz z wprowadzeniem do języka pewnej cechy X należy precyzyjnie określić inne cechy języka w taki sposób, aby cecha X współdziałała z już istniejącymi konstrukcjami, została wtopiona w istniejące lub zmodyfikowane mechanizmy nazywania, typowania, zakresu i wiązania, oraz miała zapewnioną uniwersalną obsługę. Przykładowo, jeżeli cecha X jest dynamiczną tablicą, to odpowiednimi pytaniami są: czy może ona być składową zapisu (struktury, obiektu), czy może być parametrem procedury, czy może być zwrócona przez procedurę funkcyjną, jakie środki będą przewidziane do typizacji, wyszukiwania, aktualizacji, usuwania, dostawiania elementów; itd. Oddolny rozwój niektórych języków (np. SQL) jest przyczyną wielu przypadków łamania zasady korespondencji, co objawia się m.in. tym, że nowo dodawane cechy nie są gładko połączone ze starymi cechami.

Zasada korespondencji w środowisku wytwórczym Zasada korespondencji powinna być rozszerzona dalej, poza samą definicję języka. Jeżeli wprowadzamy cechę X, to ważne stają się odpowiedzi na pytania: Czy istnieje dostatecznie jasna pragmatyka cechy X, tj. sposób przełożenia konkretnej potrzeby w dziedzinie przedmiotowej na zastosowanie cechy X? Czy cecha X jest uwzględniona w metodyce projektowania aplikacji i/lub metodyce projektowania baz danych? Jeżeli nie, to cecha X stanie się cechą uboczną. Czy cecha X nie jest redundantna? Czy i jak cecha X będzie osiągalna z zewnętrznych interfejsów, nie bazujących na definiowanym przez nas języku, np. ODBC lub JDBC? Jak cecha X została udokumentowana i objaśniona na przykładach? Dokumentacja i przykłady są często lakoniczne, zbyt matematyczne lub infantylne. Czy cecha X jest błędogenna lub niebezpieczna dla powszechnego programisty, czy nie prowadzi do raf semantycznych? Jakie środki dydaktyczne będą zastosowane celem objaśnienia i zareklamowania użycia cechy X?

Elementarne imperatywne konstrukcje językowe Celem następnych slajdów jest omówienie tych konstrukcji imperatywnych, które mogą mieć znaczenie przy budowie języka programowania opartego o język zapytań. Ponieważ konstrukcje imperatywne istnieją w tysiącach różnorodnych języków programowania, wynajdywanie nowych rozwiązań jest niepotrzebne. Będziemy raczej oceniać popularne i powszechnie używane konstrukcje, takie jak if...then...else..., while...do..., itd., celem ustalenia ich przydatności i ewentualnych modyfikacji w przypadku języka programowania opartego na zapytaniach.

Operator tworzenia obiektu Może to być deklarowanie obiektu, czyli utworzeniem obiektu w momencie inicjacji pewnej abstrakcji programistycznej (np. metody). Może to być dynamiczne utworzenie obiektu na polecenie wydane explicite przez programistę - operator musi być dodatkowo parametryzowany miejscem składu i statusem trwałości. Operator powinien być makroskopowy. Operator powinien dawać możliwość utworzenia nowej danej elementarnej oraz nowej danej pointerowej wewnątrz określonego obiektu. Operator powinien dawać możliwość utworzenia nowego modułu, klasy, metody, perspektywy, procedury, ograniczenia, trygera, itd. Generalnie, dla dowolnego elementu składu obiektów powinna istnieć odmiana tego operatora pozwalająca na utworzenie tego elementu w określonym środowisku.

Referencje do środowisk na stosie ENVS Jeżeli utworzony został nowy obiekt, to istotne jest uaktualnienie stosu ENVS poprzez wstawienie tam – w razie potrzeby – odpowiedniego bindera do nowego obiektu. Dla każdego środowiska reprezentowanego przez sekcję stosu ENVS pamiętana jest także referencja (lub referencje) do środowiska (środowisk) składu obiektów, które były podstawą skonstruowania danej sekcji stosu. Następnie po utworzeniu obiektu porównuje się referencję do środowiska, wewnątrz którego został utworzony nowy obiekt, z referencjami do wszystkich środowisk reprezentowanych na stosie ENVS. Jeżeli dla danej sekcji referencje są identyczne, wówczas do tej sekcji wstawia się odpowiedni binder, patrz następny slajd. Przykładowo, jeżeli tworzymy lub wstawiamy nowy obiekt Stan z referencją i765 do wnętrza obiektu Pracownik z identyfikatorem i9, wówczas przeglądamy kolumnę „Referencje do środowisk” stosu ENVS, następnie znajdując tam również referencję i9 dostawiamy do tej sekcji w kolumnie „Bindery” binder Stan(i765 ). Czynność tę wykonujemy dla każdej sekcji, która zawiera referencję do środowiska i9.

ENVS z referencjami do środowisk Referencje do środowisk Bindery Środowsko pointera Referencje do lokalnych środowisk Referencja do obiektu Referencja do środowiska bazy danych - i127, i478 ......... i9 ibd Prac(i1) X(i127) Y(i128) N(5) I("Maria") ......... Nazwisko(i10) Zar(i11) Adres(i12) PracujeW(i16) Prac(i1) Prac(i5) Prac(i9) Dział(i17) Dział(i22) Przy optymalizowanej wersji stosu ENVS w istocie pamiętana jest tylko pierwsza kolumna, jeżeli zawiera referencje do środowisk, i druga kolumna w pozostałych przypadkach. To oznacza, że operacje, tworzenia, wstawiania lub usuwania obiektu nie wymagają w większości jakichkolwiek działań na stosie ENVS.

Instrukcja create Najprostszą formą syntaktyczną instrukcji tworzenia obiektu jest: zapytanie ::= instrukcja_create instrukcja ::= instrukcja_create instrukcja_create ::= create [gdzie] zapytanie; gdzie ::= local | temporary | permanent Zapytanie będące argumentem instrukcji create może zwrócić bag. Zostanie wówczas utworzonych tyle obiektów, ile elementów ma ten bag (w szczególności ani jednego, jeżeli bag jest pusty). Wynikiem instrukcji jest referencja (bag referencji) do utworzonych obiektów. Nazwy tworzonych obiektów oraz ich pod-obiektów są określone przez odpowiednie bindery będące wynikiem tego zapytania. Dla wszystkich referencji zwróconych przez to zapytanie jest wykonywana automatycznie dereferencja. Miejsce tworzenia obiektu jest ustalone przez kwalifikator gdzie.

Referencje w instrukcji create Poprzez dodanie nowej prostej konstrukcji do SBQL można również w ten sposób tworzyć obiekty pointerowe. Załóżmy składnię zapytanie ::= ref zapytanie i przyjmijmy, że w każdej sytuacji (nie tylko związanej z create) ref q zwraca referencję r (lub wiele referencji) zwróconą przez zapytanie q, która nie podlega dereferencji. Technicznie, referencja r jest opatrzona specjalną flagą, która zabrania użycia dereferencji i zabrania automatycznego wywołania procedury, funkcji lub metody poprzez referencję r z tą flagą. Jeżeli instrukcja create napotka referencję z taka flagą, wówczas tworzy obiekt pointerowy.

Przykłady tworzenia obiektów Instrukcja create tworzy w trwałym składzie obiekt pracownika Kowalskiego, po zatrudnieniu go w dziale marketingu. create permanent ( 2453456 as NrP, ”Kowalski” as Nazwisko, ”analityk” as Stan, 2350 as Zar, (ref Dział where Nazwa = “Marketing”) as PracujeW ) as Prac Instrukcja create tworzy lokalnie od zera do dowolnej liczby obiektów pointerowych z nazwą analityk, prowadzących do obiektów Prac. Następnie instrukcja for each każdemu w ten sposób wyselekcjonowanemu analitykowi podnosi zarobek o 100. create (ref Prac where Stan = ”analityk”) as analityk; for each analityk.Prac do Zar := Zar +100;

Przypisywanie obiektów do klas Kolejnym zagadnieniem, które należy rozstrzygnąć przy tworzeniu nowego obiektu jest podłączenie go do klasy. Można to zrobić poprzez dodatkową składnię związaną z instrukcją create, np.: instrukcja_create ::= create [gdzie] zapytanie as member of nazwaKlasy Przyjmujemy tu, że wszystkie klasy są bytami pierwszej kategorii dostępnymi do wiązania w środowisku, w którym wydana została ta instrukcja. Skutkiem jest wytworzenie specyficznego związku pointerowego pomiędzy utworzonym obiektem a jego bezpośrednią klasą, który jest używany przez procedurę eval dla załadowania binderów do wnętrza klasy wraz z binderami do wnętrza obiektu, tak jak to było objaśnione dla modeli M1 i M2.

Operator podstawienia (update w SQL) Operator podstawienia możemy zrealizować w klasycznym wariancie instrukcja ::= zapytanie := zapytanie Podstawienie ma postać l-value := r-value , gdzie l-value (lewa wartość) jest wyrażeniem zwracającym referencję, zaś r-value (prawa wartość) jest wyrażeniem zwracającym wartość. Operatora dokonuje zamiany bieżącej wartości obiektu posiadającego identyfikator zwrócony przez l-value na wartość określoną przez r-value. Operator podstawienia w wersji języka zapytań prowadzi do konieczności ustalenia następujących aspektów: Czy ma być makroskopowy, tj. czy l-value i r-value mogą być określane przez zapytania zwracające bagi lub sekwencje? Czy możliwe będzie podstawienie na obiekt złożony? Czy możliwe będzie podstawienie na obiekt pointerowy? Odpowiedzi na te pytania muszą być pozytywne, inaczej złamana będzie zasada korespondencji.

Podstawienie makroskopowe Przyjęcie składni q1 := q2 jest nieakceptowalne w sytuacji, gdy q1 i q2 zwracają bagi, ponieważ nie będzie wiadomo, która wartość ma być podstawiona na którą referencję. Taka składnia jest również nieakceptowalna w sytuacji, gdy q1 i q2 zwracają sekwencje, gdyż zmusza to programistę do starannej kontroli, czy rozmiar sekwencji i wzajemne dopasowanie poszczególnych ich elementów są w pełni spójne. Pozostają dwa rozwiązania: Nie dopuszczamy podstawienia makroskopowego: w konstrukcji q1 := q2 zapytanie q1 musi zwrócić dokładnie jedną referencję, zaś zapytanie q2 musi zwrócić dokładnie jedną wartość. Makroskopowość podstawienia będzie osiągnięta poprzez konstrukcję for each. Wprowadzamy nowy operator update z parametrem będącym pojedynczym zapytaniem. Zapytanie to zwraca bag struktur dwu-elementowych, gdzie pierwszy element każdej struktury jest traktowany jako l-value, zaś drugi element jest traktowany jako r-value. Rozwiązanie to zostało zaimplementowane w systemie Loqis.

Przykłady podstawienia Podwyższ o 100 zarobek wszystkim programistom: for each Prac where Stan = ”programista” do Zar := Zar + 100; Alternatywnie: update (Prac where Stan = ”programista”) . (Zar, Zar + 100); Podwyższ o 100 zarobek wszystkim programistom i zmień im stanowisko na ”inżynier”: for each Prac where Stan = ”programista” do { Zar := Zar + 100; Stan := ”inżynier”; }; Forma alternatywna wymaga wprowadzenia bagów z typologicznie niekompatybilnymi strukturami: update (Prac where Stan = ”programista”) . bag((Zar, Zar + 100), (Stan, ”inżynier”)); Rozwiązanie to może być nieakceptowalne od strony mocnej kontroli typów.

Podstawienie na daną pointerową Podstawienie na daną pointerową można zdefiniować przy pomocy wprowadzonego już kwalifikatora ref, który informuje, że chodzi o referencję. Przenieś wszystkich programistów do działu Nowaka: for each Prac where Stan = ”programista” do PracujeW := ref Dział where (Szef.Prac.Nazwisko) = ”Nowak”; Alternatywnie: update (Prac where Stan = ”programista”) . (PracujeW, ref (Dział where (Szef.Prac.Nazwisko) = ”Nowak”));

Podstawienie na obiekt złożony Podstawienie na obiekt złożony przypomina instrukcję create. Identyfikator obiektu, na który się podstawia, nie ulega zmianie. Wszystkie pod-obiekty tego obiektu są usuwane, następnie tworzone są nowe pod-obiekty na podstawie prawej strony podstawienia. Powinna ona zawierać strukturę z binderami; bindery wyznaczają nazwy tworzonych pod-obiektów. Wstaw nowe dane Nowaka: (Prac where Nazwisko = ”Nowak”) := ( 4536 as NrP, ”Nowak” as Nazwisko, ”analityk” as Stan, 2500 as Zar, ( ”Radom” as Miasto, ”Nowa” as Ulica, 76 as NrDomu) as Adres, ( ref Dział where Nazwa = „Magazyn”) as PracujeW );

Podstawienie zawartości innego obiektu Drobnym problemem technicznym jest definicja dereferencji dla złożonego obiektu. Struktura binderów odwzorowująca obiekt 1:1 jest pomysłem na taką dereferencję. Przykładowo: Na obiekt pracownika Doe podstaw dane pracownika Poe: (Prac where Nazwisko=”Doe”) := (Prac where Nazwisko=”Poe”) Obiekt: < i9 , Prac , { < i10, Nazwisko, ”Poe” >, < i11, Zar, 900 >, < i12, Adres, { < i13, Miasto, ”Radom” >, < i14, Ulica, ”Wolska” >, < i15, NrDomu, 12 > } >, < i16, PracujeW, i22 > } > Dereferencja deref(i9 ): struct{ Nazwisko( ”Poe” ), Zar( 900 ), Adres( struct{ Miasto(”Radom”), Ulica(”Wolska”), NrDomu(12)}, PracujeW ( ref i22 ) }

Operator wstawiania Operator wstawiania obiektu powinien umożliwiać wstawianie makroskopowe, w stylu klauzuli insert języka SQL. Ma wstawić pewien obiekt jako podobiekt innego obiektu. Wybrany obiekt jest przesuwany z dotychczasowego środowiska do określonego środowiska. Powinien on działać na wszystkich typach obiektów, włączając obiekty złożone, klasy, metody, perspektywy, itd. Np. jeżeli dowolny obiekt analityka nie ma atrybutu Zar, to wstaw mu do środka taką daną z wartością 1000. for each (Prac where Stan = ”analityk” and count(Zar) = 0) as p do { insert ( p, create 1000 as Zar ); } Dla wszystkich obiektów pracowników wstaw pod-obiekt zarabiał z konkatenacją aktualnej daty i aktualnego zarobku danego pracownika. insert (Prac as p) . ( p, create ((string)Date º (string)(p.Zar)) as zarabiał);

Operator usuwania Operator usuwania powinien umożliwiać usuwanie makroskopowe, w stylu klauzuli delete języka SQL. Dotyczy obiektów tworzonych (nie deklarowanych) przez programistę i oznacza usunięcie obiektu z określonego środowiska. Operator usuwania powinien dotyczyć wszystkich rodzajów obiektów, w tym obiektów atomowych, pointerowych, złożonych., klas, metod, perspektyw, itd. Niektórzy lansują pogląd, że operator usuwania nie powinien być dostępny programiście, gdyż może prowadzić do tzw. zwisających pointerów. Programista usuwa pointery do obiektu, natomiast usunięcie samego obiektu załatwia automatyczny odśmiecacz (garbage collector). Ten pogląd jest powierzchowny, wynikający z niezrozumienia problemu. Pozostawienie obiektu, który już nie powinien istnieć, jest tak samo błędogenne jak zwisający pointer. Należy usuwać obiekty z automatycznym usunięciem/wyzerowaniem prowadzących do nich pointerów.

Inne operatory elementarne Operator deklaracji stałej lub makrosa. Można go uważać za operator tworzenia obiektu niemodyfikowalnego. Istotą tego operatora jest to, że wszelkie operacje związane z tym operatorem są wykonywane podczas kompilacji. Deklaracja ma np. postać: constant <nazwa> = <tekst>; gdzie <tekst> jest w zasadzie dowolnym tekstem (tzw. makrosem) który zastąpi po kompilacji każde użycie <nazwa>. Operator zmiany nazwy obiektu lub utworzenia nowego aliasu dla obiektu. Dotyczy raczej szczególnych sytuacji i jest możliwy wyłącznie w przypadku gdy nazwy obiektów są pierwszej kategorii programistycznej. Operator zmiany nazwy powinien być makroskopowy. Operatory dotyczące zdarzeń: wygenerowanie zdarzenia, przechwycenie zaistniałego zdarzenia.

Operatory warunkowe i przełączania Operator warunkowy: if <warunek> then <program1> else <program2> if <warunek> then <program> Wariant dla wyrażeń: if <warunek> then <zapytanie1> else <zapytanie2> Operator przełączania: posiada wiele wariantów, np. case <wyrażenie> do <etykieta 1>: <program 1>, <etykieta 2>: <program 2>, ... <etykieta n>: <program n> else <program n+1> Semantycznie, obliczane jest <wyrażenie>; jeżeli wyrażenie zwróci wartość <etykieta i> wówczas wykonywany jest <program i>. Jeżeli <wyrażenie> nie zwróciło wartości równej jakiejkolwiek etykiecie, wówczas wykonywany jest <program n+1>. Fraza else jest zwykle opcyjna.

Operatory pętli while <warunek> do <program> Operator powtarza wyliczenie wyrażenia <warunek> i wykonanie bloku <program> aż do momentu, kiedy <warunek> będzie nieprawdziwy. Jeżeli <warunek> jest na samym początku nieprawdziwy, wówczas <program> nie jest wykonywany ani razu. repeat <program> until <warunek> Najpierw następuje wykonanie bloku <program>, następnie wyliczenie wyrażenia <warunek>; jeżeli jest prawdziwy, to sterowanie jest przekazywane dalej, w przeciwnym przypadku powtarzane jest wykonanie bloku <program>, z ponownym wyliczeniem wyrażenia <warunek>. Modyfikacja tych operatorów polega na wprowadzeniu specjalnej instrukcji break, której wykonanie wewnątrz <program> powoduje przekazanie sterowania do instrukcji znajdującego się za tą konstrukcją. loop <program> przerwanie pętli wymaga użycia instrukcji break.

Operator for each Składnia: for each <zapytanie> do <program> Semantyka: przyjmujemy zasadę operatorów nie-algebraicznych Dla każdego e zwróconego przez <zapytanie>, ENVS jest podwyższany o nested(e). W modelach M1, M2, M3, jeżeli e zawiera referencje do obiektów, to na ENVST są wkładane sekcje z binderami do wnętrza odpowiednich klas. Następnie wykonywany jest <program>. Po zakończeniu wykonania <program> ENVS wraca do poprzedniego stanu. Cykl ten jest powtarzany dla wszystkich elementów zwróconych przez <zapytanie>. Tak jak w operatorach nie-algebraicznych, "zmienna iteracyjna" jest definiowana przez operator as i nie musi wystąpić. Przykłady: for each Prac where Stan = "asystent" do Zar := Zar + 100; for each (Prac where Stan = "asystent") as p do { p.Zar := p.Zar + 100; p.Stan := "starszy asystent"};

Iteratory niższego poziomu Występują w postaci spójnej rodziny operatorów lub metod, niekiedy hermetyzowanej w postaci klasy lub szablonu. Służą do sekwencyjnego przetwarzania elementów kolekcji. Typowym przykładem są kursory znane z języka SQL lub iteratory. Klasyczny zestaw takich operatorów jest następujący (z dokładnością do nazw operatorów): getFirst, getNext, getPrior , wyjątek NoMoreElements Zwykle takie metody zwracają referencję do bieżącego elementu, która dalej jest przetwarzana przy pomocy standardowych metod (nie dotyczy to SQL). Iteratory niższego poziomu można zastąpić konstrukcją for each, ale nie zawsze. Istnieją zadania, których nie można zrealizować przy pomocy for each; klasycznym przykładem jest algorytm zlania (merging) dwóch posortowanych zbiorów w jeden posortowany zbiór. Problem z iteratorami niższego poziomu polega na tym, że wymagają one wprowadzenia pojęcia „elementu bieżącego”. To prowadzi do trudności z zagnieżdżonym wywoływaniem iteratorów, w szczególności z rekurencją.