Oz (język programowania) - Oz (programming language)

Oz
Paradygmat wieloparadygmat : logika , funkcjonalność , imperatyw , obiektowość , ograniczenie , rozproszone , współbieżne
Zaprojektowany przez Gert Smolka, jego uczniowie
Deweloper Konsorcjum Mozarta
Po raz pierwszy pojawiły się 1991 ; 30 lat temu  ( 1991 )
Wersja stabilna
Oz 1.4.0 (wersja ostateczna), Mozart 2.0.1 / 5 września 2018 ; 2 lata temu  ( 05.09.2018 )
Dyscyplina typowania dynamiczny
Licencja MIT X11
Stronie internetowej mozart .github .io
Główne wdrożenia
System programowania Mozarta
Dialekty
Oz, Mozart
Wpływem
Erlang , Lisp , Prolog
Pod wpływem
Alice , Scala

Oz jest językiem programowania wieloparadygmatowym , opracowanym w Laboratorium Systemów Programowania na Université catholique de Louvain , do nauczania języków programowania. Ma kanoniczny podręcznik: Pojęcia, techniki i modele programowania komputerowego .

Oz został po raz pierwszy zaprojektowany przez Gerta Smolkę i jego uczniów w 1991 roku. W 1996 roku rozwój Oz był kontynuowany we współpracy z grupą badawczą Seif Haridi i Petera Van Roya w Szwedzkim Instytucie Informatyki . Od 1999 roku Oz jest nieustannie rozwijany przez międzynarodową grupę, Konsorcjum Mozarta, które pierwotnie składało się z Uniwersytetu Saary , Szwedzkiego Instytutu Informatyki i Université catholique de Louvain . W 2005 roku odpowiedzialność za zarządzanie rozwojem Mozarta została przeniesiona na podstawową grupę, Radę Mozarta, w wyraźnym celu otwarcia rozwoju Mozarta na szerszą społeczność.

System programowania Mozarta jest podstawową implementacją Oz. Został wydany na licencji open source przez Mozart Consortium. Mozart został przeniesiony na systemy Unix , FreeBSD , Linux , Windows i macOS .

Funkcje językowe

Oz zawiera większość pojęć z głównych paradygmatów programowania , w tym logiki, funkcji (zarówno leniwej oceny, jak i gorliwej oceny ), imperatywnej, obiektowej, ograniczonej, rozproszonej i współbieżnej. Oz ma zarówno prostą semantykę formalną (patrz rozdział 13 książki wspomnianej poniżej), jak i wydajną implementację. Oz jest językiem zorientowanym na współbieżność , ponieważ termin został wprowadzony przez Joe Armstronga, głównego projektanta języka Erlang . Język zorientowany na współbieżność sprawia, że ​​współbieżność jest łatwa w użyciu i wydajna. Oz obsługuje kanoniczny graficzny interfejs użytkownika (GUI) język QTk.

Oprócz programowania wieloparadygmatowego, główne atuty Oz to programowanie z ograniczeniami i programowanie rozproszone . Ze względu na faktyczny projekt, Oz jest w stanie z powodzeniem wdrożyć model rozproszonego programowania przejrzysty dla sieci. Model ten ułatwia programowanie otwartych, odpornych na błędy aplikacji w języku. W przypadku programowania z ograniczeniami Oz wprowadza koncepcję przestrzeni obliczeniowych , które umożliwiają definiowane przez użytkownika strategie wyszukiwania i dystrybucji ortogonalne do domeny z ograniczeniami.

Przegląd języka

Struktury danych

Oz jest oparty na podstawowym języku z bardzo małą liczbą typów danych, które można rozszerzyć na bardziej praktyczne za pomocą cukru syntaktycznego .

Podstawowe struktury danych:

  • Liczby: zmiennoprzecinkowe lub całkowite (liczba rzeczywista)
  • Zapisy: do grupowania danych: circle(x:0 y:1 radius:3 color:blue style:dots) . Tutaj terminy x, y, promień itp. Nazywane są cechami, a dane powiązane z cechami (w tym przypadku 0,1,3 itd.) Są wartościami.
  • Krotki: Nagrywa całkowitej wyposażony w kolejności rosnącej: circle(1:0 2:1 3:3 4:blue 5:dots) .
  • Listy: prosta struktura liniowa
'|'(2 '|'(4 '|'(6 '|'(8 nil)))) % as a record.
2|(4|(6|(8|nil))) % with some syntactic sugar
2|4|6|8|nil % more syntactic sugar
[2 4 6 8] % even more syntactic sugar

Te struktury danych są wartościami (stałymi), pierwszą klasą i typem sprawdzanym dynamicznie . Nazwy zmiennych w Oz zaczynają się wielką literą, aby odróżnić je od literałów, które zawsze zaczynają się małą literą.

Funkcje

Funkcje są wartościami pierwszej klasy, umożliwiającymi programowanie funkcjonalne wyższego rzędu :

fun {Fact N}
   if N =< 0 then 1 else N*{Fact N-1} end
end
fun {Comb N K}
   {Fact N} div ({Fact K} * {Fact N-K}) % integers can't overflow in Oz (unless no memory is left)
end

fun {SumList List}
   case List of nil then 0
   [] H|T then H+{SumList T} % pattern matching on lists
   end
end

Funkcje mogą być używane zarówno ze zmiennymi swobodnymi, jak i związanymi. Wolne wartości zmiennych znajdują się za pomocą statycznego zakresu leksykalnego .

Programowanie wyższego rzędu

Funkcje są podobne do innych obiektów Oz. Funkcja może być przekazana jako atrybut do innych funkcji lub może zostać zwrócona w funkcji.

fun {Square N}  % A general function
   N*N
end

fun {Map F Xs}  % F is a function here - higher order programming
   case Xs
      of nil then nil
      [] X|Xr then {F X}|{Map F Xr}
   end
end

%usage
{Browse {Map Square [1 2 3]}}  %browses [1 4 9]

Funkcje anonimowe

Podobnie jak wiele innych języków funkcyjnych, Oz obsługuje funkcje anonimowe (tj. Funkcje, które nie mają nazwy) w programowaniu wyższego rzędu. Do ich oznaczenia używany jest symbol $.

Poniżej funkcja square jest definiowana anonimowo i przekazywana, powodując [1 4 9] jej przeglądanie.

{Browse {Map fun {$ N} N*N end [1 2 3]}}

Ponieważ funkcje anonimowe nie mają nazw, nie jest możliwe zdefiniowanie rekurencyjnych funkcji anonimowych.

Procedury

Funkcje w Oz powinny zwracać wartość w ostatniej instrukcji napotkanej w treści funkcji podczas jej wykonywania. W poniższym przykładzie funkcja Ret zwraca 5, jeśli X> 0, aw przeciwnym razie -5.

declare
fun {Ret X}
   if X > 0 then 5 else ~5 end
end

Ale Oz zapewnia również ułatwienie na wypadek, gdyby funkcja nie zwracała wartości. Takie funkcje nazywane są procedurami. Procedury są definiowane przy użyciu konstrukcji „proc” w następujący sposób

declare
proc {Ret X}
   if X > 0 then {Browse 5} else {Browse ~5} end
end

Powyższy przykład nie zwraca żadnej wartości, po prostu wypisuje 5 lub -5 w przeglądarce Oz w zależności od znaku X.

Zmienne przepływu danych i deklaratywna współbieżność

Gdy program napotka niezwiązaną zmienną, czeka na wartość. Na przykład poniżej wątek będzie czekał, aż X i Y zostaną powiązane z wartością, zanim zostanie wyświetlona wartość Z.

thread 
   Z = X+Y
   {Browse Z}
end
thread X = 40 end
thread Y = 2 end

Wartości zmiennej przepływu danych nie można zmienić po jej powiązaniu:

X = 1
X = 2 % error

Zmienne Dataflow ułatwiają tworzenie współbieżnych agentów strumieniowych:

fun {Ints N Max}
   if N == Max then nil
   else 
      {Delay 1000}
      N|{Ints N+1 Max}
   end
end

fun {Sum S Stream}
   case Stream
      of nil then S
      [] H|T then S|{Sum H+S T}
   end
end

local X Y in
   thread X = {Ints 0 1000} end
   thread Y = {Sum 0 X} end
   {Browse Y}
end

Ze względu na sposób działania zmiennych przepływu danych możliwe jest umieszczenie wątków w dowolnym miejscu programu i zagwarantowanie, że będzie to miało ten sam wynik. To sprawia, że ​​programowanie współbieżne jest bardzo łatwe. Wątki są bardzo tanie: można mieć jednocześnie uruchomionych 100 000 wątków.

Przykład: Sito podziału próby

Ten przykład oblicza strumień liczb pierwszych przy użyciu algorytmu dzielenia próbnego przez rekurencyjne tworzenie współbieżnych agentów strumienia, które odfiltrowują liczby inne niż liczby pierwsze:

fun {Sieve Xs}
   case Xs of nil then nil
   [] X|Xr then Ys in
      thread Ys = {Filter Xr fun {$ Y} Y mod X \= 0 end} end
      X|{Sieve Ys}
   end
end

Lenistwo

Oz domyślnie używa gorliwej oceny , ale leniwa ocena jest możliwa. Poniżej fakt jest obliczany tylko wtedy, gdy potrzebna jest wartość X do obliczenia wartości Y.

fun lazy {Fact N}
   if N =< 0 then 1 else N*{Fact N-1} end
end
local X Y in
  X = {Fact 100} 
  Y = X + 1
end

Leniwa ocena daje możliwość przechowywania naprawdę nieskończonych struktur danych w Oz. Potęgę leniwej oceny można zobaczyć na poniższym przykładzie kodu:

declare
fun lazy {Merge Xs Ys}
   case Xs#Ys
   of (X|Xr)#(Y|Yr) then
      if X < Y then X|{Merge Xr Ys}
      elseif X>Y then Y|{Merge Xs Yr}
      else X|{Merge Xr Yr}
      end
   end
end

fun lazy {Times N Xs}
   case Xs
   of nil then nil
   [] X|Xr then N*X|{Times N Xr}
   end
end

declare H
H = 1 | {Merge {Times 2 H} {Merge {Times 3 H} {Times 5 H}}}
{Browse {List.take H 6}}

Powyższy kod elegancko oblicza wszystkie zwykłe liczby na nieskończonej liście. Rzeczywiste liczby są obliczane tylko wtedy, gdy są potrzebne.

Współbieżność przekazywania wiadomości

Deklaratywny model współbieżny można rozszerzyć o przekazywanie komunikatów za pomocą prostej semantyki:

declare
local Stream Port in
   Port = {NewPort Stream}
   {Send Port 1} % Stream is now 1|_ ('_' indicates an unbound and unnamed variable)
   {Send Port 2} % Stream is now 1|2|_ 
   ...
   {Send Port n} % Stream is now 1|2| .. |n|_
end

Za pomocą portu i wątku można zdefiniować agentów asynchronicznych:

fun {NewAgent Init Fun}
   Msg Out in
   thread {FoldL Msg Fun Init Out} end
   {NewPort Msg}
end

Stan i obiekty

Ponownie możliwe jest rozszerzenie modelu deklaratywnego w celu obsługi programowania stanowego i obiektowego z bardzo prostą semantyką. Aby utworzyć nową zmienną strukturę danych o nazwie Komórki:

local A X in
   A = {NewCell 0}
   A := 1  % changes the value of A to 1
   X = @A  % @ is used to access the value of A
end

Dzięki tym prostym zmianom semantycznym można wspierać cały paradygmat zorientowany obiektowo. Przy odrobinie cukru syntaktycznego OOP dobrze integruje się z Oz.

class Counter
   attr val
   meth init(Value)
      val:=Value
   end
   meth browse
      {Browse @val}
   end
   meth inc(Value)
      val :=@val+Value
   end
end

local C in
   C = {New Counter init(0)}
   {C inc(6)}
   {C browse}
end

Szybkość wykonania

Szybkość wykonywania programu utworzonego przez kompilator Mozarta (wersja 1.4.0 implementująca Oz 3) jest bardzo niska. W zestawie testów porównawczych jest średnio około 50 razy wolniejszy niż w przypadku kolekcji GNU Compiler Collection (GCC) dla języka C, rozwiązując zadania testowe.

Zobacz też

Bibliografia

Linki zewnętrzne