I.
Wprowadzenie do  języków zapytań (1)
II.
Wprowadzenie do  języków zapytań (2)
III.
Pojęcia obiektowości w bazach danych (1)
IV.
Pojęcia obiektowości w bazach danych (2)
V.
Podstawy semantyczne języków zapytań
VI.
Modele składu obiektów
VII.
Stos środowisk, rezultaty zapytań, funkcja nested
VIII.
Język SBQL (Stack-Based Query Language) (1)
IX.
X.
Dalsze własności SBQL
XI.
Operatory order by i group by
XII.
Przetwarzanie struktur nieregularnych
XIII.
Rozszerzenie języków zapytań o konstrukcje imperatywne
  Wstęp
  1. Konstrukcje deklaratywne i imperatywne
  2. Zasada korespondencji
  3. Elementarne konstrukcje językowe w językach imperatywnych
  Podsumowanie
  Zadania
XIV.
Procedury, procedury funkcyjne, metody, reguły zakresu
XV.
Parametry procedur i metod, procedury rekurencyjne, optymalizacja poprzez modyfikację zapytań

 

1. Konstrukcje deklaratywne i imperatywne

Założeniem języków zapytań jest deklaratywność, czyli wyrażanie bezpośrednio celu wyszukiwania, a nie operacji prowadzących do tego celu. Deklaratywność jest często wiązana ze specyficznymi systemami opartymi na programowaniu w logice, takimi jak Prolog lub Datalog. Zwolennicy tego rodzaju podejścia twierdzą niekiedy, że tylko wyrażenia logiki matematycznej (i pochodne) są w pełni deklaratywne. Tego rodzaju opinie będziemy uważać za koniunkturalne próby zbudowania fałszywego stereotypu mającego na celu wywyższenia danego paradygmatu naukowego nad inne. W istocie, jakakolwiek specyficzna składnia lub semantyka, nawet jeżeli jest budowana na gruncie logiki matematycznej, nie ma w tym zakresie przewagi z definicji.

Deklaratywność wynika z psychologii, odczuć użytkownika języka, a nie z jakichkolwiek tworów formalnych. Przykładowo, zarówno algebra relacji, jak i SQL są  uważane za języki deklaracyjne, mimo że ich semantyka jest objaśniana w sposób operacyjny. W istocie, 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ą pielęgnację. Deklaratywność oznacza więc minimalizowanie tych elementów w wyrażeniach języka, które odnoszą się do środowiska komputerowego, oraz maksymalizowanie tych elementów, które odnoszą się do dziedziny przedmiotowej i modelowania pojęciowego tej dziedziny zachodzącego w umyśle projektanta lub programisty. 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; i odwrotnie.

Z technicznego punktu widzenia konstrukcje deklaratywne nie mogą (lub raczej nie powinny) zmieniać stanu.

Zmiany stanu (np. stanu bazy danych) 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 [Mant93]. Obecność tego rodzaju konstrukcji zmusza do odpowiedzi na pytanie, czy twórcy tego rodzaju koncepcji w swojej misji zbudowania stereotypu "programowania deklaracyjnego" nie posuwają zbyt daleko, poza granicę zwyczajnej uczciwości w przedstawianiu faktów takimi, jakimi one naprawdę są. Konsekwencje obecności tego rodzaju symboli w programach logicznych są następujące:

  • Powstały w ten sposób system nie jest wyrażalny w języku logiki matematycznej, przynajmniej tej, która legła u podstaw tej koncepcji.

  • Kolejność formuł "logicznych" staje się istotna, wbrew początkowym założeniom.

  • Większość spośród tysięcy aksjomatów, wniosków i twierdzeń matematycznych przyjętych lub udowodnionych przy tej okazji staje się niewiarygodna ze względu na fundamentalną zmianę podstawowych założeń.


W istocie, języki określane jako deklaratywne osiągają efekt w postaci zmiany stanu poprzez tzw. efekty uboczne, tj. pewne funkcje lub konstrukcje syntaktyczne, które oprócz wyniku dostarczanego do programu (który często jest drugorzędny) wykonują pewne akcje na danych. Istnieją zróżnicowane opinie co do stosowania efektów ubocznych jako paradygmatu w programowaniu. Wiele języków programowania korzysta szeroko z efektów ubocznych, co niektórzy specjaliści krytykują. Języki stosujące efekty uboczne dokonują niejawnego podziału warstwy semantycznej na semantykę "oficjalną", czyli taką, która wynika z przyjętego paradygmatu, np. programowania w logice, oraz "nieoficjalną", która jest zestawem efektów ubocznych zastosowanych w tym języku. Przykładem tego rodzaju hybrydy jest język Prolog.

Przy konstrukcji rozszerzeń zdefiniowanego przez nas języka SBQL będziemy starali się trzymać czystości rozdzielenia tej części języka, która nie może zmienić stanu obiektów (czyli "czystych" deklaratywnych zapytań), oraz części, która będzie zajmować się zmianami stanu (czyli części imperatywnej). Generalnie, będziemy stosowali zasadę, zgodnie z którą efekty uboczne w zapytaniach są niewskazane. Mamy do tego dwa ważne powody:

  • Poprzez efekty uboczne wyrażenia/zapytania stają się mniej czytelne, błędogenne oraz bardziej kłopotliwe podczas zmian oprogramowania;

  • Zastosowanie efektów ubocznym może w niektórych przypadkach zakłócić mechanizmy optymalizacji zapytań. Ze względu na efekty uboczne optymalizacja może stać się niemożliwa, lub co gorsze, może prowadzić do efektów różnych semantycznie od tych, które były założone przez programistę.


Nie możemy też zabronić użycia efektów ubocznych w zapytaniach. Wynika to z faktu, że programista może wewnątrz zapytania wywołać funkcję lub metodę, natomiast w ramach definiowanego przez nas języka nie będziemy dzielić  funkcji i metod na te, które mają efekty uboczne i te, które ich nie mają. Wobec tego programista będzie mógł użyć w zapytaniu np. takiej metody, która oprócz zwrócenia wyniku ma efekty uboczne np. w postaci zmiany stanu obiektów bazy danych. Istnieje wiele zadań, w których stosowanie efektów ubocznych jest koniecznością. Np. funkcja obliczająca zarobek netto jako efekt uboczny może zapisywać do pewnego dziennika, kto i kiedy obliczał tę funkcję. Zastosowania efektów ubocznych w zapytaniach powinny być w pełni świadome, w sytuacji całkowitej pewności, że nie zakłóci to zastosowanych mechanizmów optymalizacyjnych i nie doprowadzi do wyniku niezgodnego z intencją programisty.

Będziemy przyjmować, że dotychczas zdefiniowane przez nas zapytania w SBQL są częścią deklaratywną konstruowanego przez nas języka. Część deklaratywna nie będzie z definicji posiadać efektów ubocznych, ale nie będziemy zabraniać zastosowania efektów ubocznych w zapytaniach poprzez umieszczenie w nich funkcji lub metod, które tego rodzaju efekty posiadają. Zapytania mogą służyć do wyznaczania zmian w bazie danych poprzez specjalne konstrukcje, które będziemy nazywać imperatywnymi. Podział całości języka na część deklaratywną i imperatywną będzie wynikać ze składni.

Copyrights © 2006 PJWSTK
Materiały zostały opracowane w PJWSTK w projekcie współfinansowanym ze środków EFS.