Оз (язык программирования) - Oz (programming language)

Унция
Парадигма мультипарадигма : логическая , функциональная , императивная , объектно-ориентированная , ограниченная , распределенная , параллельная
Разработано Герт Смолка, его ученики
Разработчик Консорциум Моцарта
Впервые появился 1991 ; 30 лет назад  ( 1991 )
Стабильный выпуск
Оз 1.4.0 (финал), Моцарт 2.0.1 / 5 сентября 2018 года ; 2 года назад  ( 2018-09-05 )
Печатная дисциплина динамичный
Лицензия MIT X11
Веб-сайт Моцарт .github .io
Основные реализации
Система программирования Моцарта
Диалекты
Оз, Моцарт
Под влиянием
Эрланг , Лисп , Пролог
Под влиянием
Алиса , Скала

Oz - это многопарадигмальный язык программирования , разработанный в Лаборатории систем программирования при Католическом университете Лувена для обучения языку программирования. У него есть канонический учебник: « Концепции, методы и модели компьютерного программирования» .

Oz был впервые разработан Гертом Смолкой и его учениками в 1991 году. В 1996 году разработка Oz продолжилась в сотрудничестве с исследовательской группой Сейфа Хариди и Питера Ван Роя из Шведского института компьютерных наук . С 1999 года Oz постоянно разрабатывается международной группой Mozart Consortium, которая первоначально состояла из Саарландского университета , Шведского института компьютерных наук и Католического университета Лувена . В 2005 году ответственность за управление разработкой Моцарта была передана основной группе, Совету Моцарта, с явной целью открыть развитие Моцарта для более широкого сообщества.

Система программирования Моцарта - это основная реализация Oz. Он выпущен Консорциумом Моцарта с открытым исходным кодом . Моцарт был портирован на Unix , FreeBSD , Linux , Windows и macOS .

Особенности языка

Oz содержит большинство концепций основных парадигм программирования , включая логическое, функциональное (как ленивое вычисление, так и активное вычисление ), императивное, объектно-ориентированное, ограниченное, распределенное и параллельное программирование. Oz имеет как простую формальную семантику (см. Главу 13 упомянутой ниже книги), так и эффективную реализацию. Oz - это язык, ориентированный на параллелизм , поскольку этот термин был введен Джо Армстронгом, главным разработчиком языка Erlang . Язык, ориентированный на параллелизм, делает параллелизм простым и эффективным. Oz поддерживает канонический язык графического интерфейса пользователя (GUI) QTk.

Помимо многопарадигмального программирования, основные сильные стороны Oz заключаются в программировании с ограничениями и распределенном программировании . Благодаря продуманному дизайну Oz может успешно реализовать прозрачную для сети модель распределенного программирования. Эта модель упрощает программирование открытых отказоустойчивых приложений на языке. Для программирования с ограничениями Оз вводит идею вычислительных пространств , которые позволяют определять пользовательские стратегии поиска и распределения, ортогональные области ограничений.

Обзор языка

Структуры данных

Oz основан на базовом языке с очень небольшим количеством типов данных, которые можно расширить до более практичных с помощью синтаксического сахара .

Базовые структуры данных:

  • Числа: с плавающей запятой или целое число (действительное целое число)
  • Записи: для группирования данных: circle(x:0 y:1 radius:3 color:blue style:dots) . Здесь термины x, y, радиус и т. Д. Называются элементами, а данные, связанные с элементами (в данном случае 0,1,3 и т. Д.), Являются значениями.
  • Кортежи: Записи с целочисленными особенностями в порядке возрастания: circle(1:0 2:1 3:3 4:blue 5:dots) .
  • Списки: простая линейная структура
'|'(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

Эти структуры данных являются значениями (константами), проверяются первым классом и динамически типом . Имена переменных в Oz начинаются с заглавной буквы, чтобы отличать их от литералов, которые всегда начинаются со строчной буквы.

Функции

Функции - это значения первого класса, позволяющие функциональное программирование более высокого порядка :

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

Функции могут использоваться как со свободными, так и со связанными переменными. Свободные значения переменных находятся с использованием статической лексической области видимости .

Программирование высшего порядка

Функции похожи на другие объекты Oz. Функция может быть передана как атрибут другим функциям или может быть возвращена функцией.

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]

Анонимные функции

Как и многие другие функциональные языки, Oz поддерживает использование анонимных функций (т.е. функций, не имеющих имени) с программированием более высокого порядка. Для их обозначения используется символ $.

Далее функция square определяется анонимно и передается, вызывая [1 4 9] просмотр.

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

Поскольку анонимные функции не имеют имен, невозможно определить рекурсивные анонимные функции.

Процедуры

Функции в Oz должны возвращать значение в последнем операторе, встречающемся в теле функции во время ее выполнения. В приведенном ниже примере функция Ret возвращает 5, если X> 0, и -5 в противном случае.

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

Но Oz также предоставляет возможность на случай, если функция не должна возвращать значения. Такие функции называются процедурами. Процедуры определяются с помощью конструкции "proc" следующим образом.

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

Приведенный выше пример не возвращает никакого значения, он просто печатает 5 или -5 в браузере Oz в зависимости от знака X.

Переменные потока данных и декларативный параллелизм

Когда программа встречает несвязанную переменную, она ждет значения. Например, ниже поток будет ждать, пока X и Y не будут привязаны к значению, прежде чем отобразить значение Z.

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

Значение переменной потока данных не может быть изменено после привязки:

X = 1
X = 2 % error

Переменные потока данных упрощают создание параллельных потоковых агентов:

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

Из-за того, как работают переменные потока данных, можно разместить потоки в любом месте программы и гарантировать тот же результат. Это очень упрощает параллельное программирование. Потоки очень дешевы: за один раз можно запустить 100 000 потоков.

Пример: сито пробного деления

В этом примере вычисляется поток простых чисел с использованием алгоритма пробного деления путем рекурсивного создания параллельных потоковых агентов, которые отфильтровывают непростые числа:

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

Лень

Оз по умолчанию использует нетерпеливую оценку , но ленивая оценка возможна. Ниже этот факт вычисляется только тогда, когда значение X необходимо для вычисления значения 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

Ленивое вычисление дает возможность хранить действительно бесконечные структуры данных в Oz. Мощь ленивого вычисления можно увидеть в следующем примере кода:

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}}

Приведенный выше код элегантно вычисляет все регулярные числа в бесконечном списке. Фактические числа вычисляются только тогда, когда они необходимы.

Параллелизм при передаче сообщений

Декларативная конкурентная модель может быть расширена за счет передачи сообщений с помощью простой семантики:

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

С помощью порта и потока можно определить асинхронные агенты:

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

Состояние и объекты

Снова появилась возможность расширить декларативную модель для поддержки государственного и объектно-ориентированного программирования с очень простой семантикой. Чтобы создать новую изменяемую структуру данных под названием Cells:

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

С помощью этих простых семантических изменений может поддерживаться вся объектно-ориентированная парадигма. С небольшим синтаксическим сахаром ООП становится хорошо интегрированным в Оз.

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

Скорость исполнения

Скорость выполнения программы, созданной компилятором Моцарта (версия 1.4.0, реализующая Oz 3), очень низкая. По набору тестов он в среднем примерно в 50 раз медленнее, чем у GNU Compiler Collection (GCC) для языка C, решая тестовые задачи.

Смотрите также

Рекомендации

Внешние ссылки