Oz (мова програмування)

Oz - навчальний мову програмування високого рівня, в якому поєднані функціональна, процедурна, декларативна семантики.


1. Історія розробки

Розробку мови програмування Oz розпочав у 1991 році професор Gert Smolka зі своїми студентами з лабораторії систем програмування Лувенського католицького університету в Бельгії. У 1996 році до процесу розробки підключилися Seif Haridi і Peter Van Roy зі Шведського інституту інформатики (Swedish Institute of Computer Science), які використовували цю мову в своєму класичному підручнику Concepts, Techniques, and Models of Computer Programming [1]. З 1999 до 2005 року мова розвивалася під керівництвом міжнародної науково-дослідної групи (Mozart Consortium), що складається з трьох університетів: Університет землі Саар (Saarland University), Шведський інститут інформатики (Swedish Institute of Computer Science) та Лувенский католицький університет.

Високоякісна відкрита реалізація мови Oz - Mozart включає IDE на основі розширення редактора Emacs, компілятор, відладчик, профайлер і інші утиліти.

Управління розробкою системи програмування Mozart в 2005 року було передано групі розробників (Mozart Board) з метою залучення більш широкого кола дослідників. Ця система випущена групою Mozart Consortium під вільною ліцензією і згодом перенесена (портирована) на більшість популярних операційних систем, у тому числі Unix, FreeBSD, Linux, Microsoft Windows і Mac OS X.


2. Особливості мови

Мова програмування Oz включає в себе більшість концепцій популярних парадигм програмування, у тому числі логічного, функціонального (причому як ледачі, так і "енергійні" обчислення), імперативного, об'єктно-орієнтованого, програмування з обмеженнями, розподіленого і паралельного програмування. З одного боку, Oz володіє простою формальною семантикою, а з іншого - для нього створена ефективна програмна реалізація.

До основних переваг цієї мови відноситься підтримка мультіпарадігменного програмування, програмування в обмеженнях, а також розподілене програмування. Так, на рівні мовних конструкцій підтримується просте і природне розпаралелювання і розподіл обчислень по мережі, що дозволяє легко створювати відмовостійкі додатка. Для реалізації програмування в обмеженнях в мові Oz вводиться концепція обчислювальних просторів (computation spaces), в якій відбувається пошук рішення. Це дозволяє вирішувати задач математичного програмування, і зокрема задач дискретної оптимізації.


3. Огляд мови

3.1. Структури даних

Ядро мови утворено декількома основними структурами даних, але може бути розширене за допомогою т.наз. синтаксичного цукру.

Основні структури даних:

  • Числа (цілі або з плаваючою комою)
  • Записи (для групування елементів даних): circle(x:0 y:1 radius:3 color:blue style:dots)
  • Списки (прості лінійні структури):
 '|' (2 '|' (4 '|' (6 '|' (8 nil)))) 2 | (4 | (6 | (8 | nil)))% синтаксичний цукор 2 | 4 | 6 | 8 | nil% ще більш короткий запис [2 4 6 8]% ефективне застосування синтаксичного цукру для реалізації лаконічного синтаксису 

Ці значення є константними сутностями першого роду (first class), типізація при цьому динамічна.


3.2. Функції

Функції є сутностями першого роду, що дозволяє застосовувати парадигму функціонального програмування:

 fun {Fact N}% факторіал if N = <0 then 1 else N * {Fact N-1} end end fun {Comb NK}% кількість сполучень {Fact N} div ({Fact K} * {Fact NK})% цілі числа можуть мати як завгодно велике значення end fun {SumList List}% сума елементів списку case List of nil then 0 [] H | T then H + {SumList T}% зіставлення зі зразком для списку end end 

3.3. Потокові змінні і декларативний паралелізм

Якщо програма виявляє незв'язану змінну, вона очікує до тих пір, поки змінної буде присвоєно значення:

 thread Z = X + Y% очікує до тих пір, поки змінні X і Y не отримають значення {Browse Z}% відображає значення 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 + ST} end end local XY in thread X = {Ints 0 1000} end thread Y = {Sum 0 X} end {Browse Y} end 

Завдяки тому, як працюють потокові змінні, в будь-якому місці програми можна використовувати потоки обчислення, які гарантовано повернуть один і той же результат, що робить паралельне програмування простим. Разом з тим потоки витрачають дуже мало системних ресурсів: як і в Ерланген, одночасно можна запустити 100000 потоків [2].


4. Приклади програм на мові Oz

4.1. Решето Ератосфена

У даному прикладі обчислюється потік простих чисел з використанням алгоритму решето Ератосфена. Для цього рекурсивно створюються паралельні потоки, які відсівають складені числа:

 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 

4.2. Ледачі обчислення

За замовчуванням, Oz використовує модель ледачих обчислень, але також підтримує і т.наз. енергійні обчислення:

 fun lazy {Fact N} if N = <0 then 1 else N * {Fact N-1} end end local XY in X = {Fact 100} Y = X + 1% оскільки потрібно значення X, воно обчислюється саме в цей момент end 

4.3. Передача повідомлень

Модель декларативного паралелізму може бути розширена з використанням механізму передачі повідомлень:

 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 

4.4. Стану та об'єкти

Модель декларативного паралелізму може бути розширена з метою підтримки концепції стану і об'єктно-орієнтованого програмування; для цього необхідно створити структуру даних Cells, значення якої може бути змінено:

 local AX 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 

4.5. Приклад програми на мові Oz, вирішальною ребус

Умова:

 ФУТ + БОЛ --- ГРА Де І = 0 і всі різні букви означають різні цифри. 

Рішення:

 local Fut Res in proc {Fut C} F # U # T # B # O # L # G # R # A = C in C ::: 0 # 9 {FD.distinct C} F \ =: 0 B \ = : 0 100 * F + 10 * U + T + 100 * B + 10 * O + L =: 100 * G + 10 * R + A {FD.distribute ff C} end {SearchAll Fut Res} {Browse Res} end 

покаже всі рішення даного ребуса у вигляді таблиці.

Примітки

  1. Concepts, Techniques, and Models of Computer Programming - vshabanov-ru.blogspot.com/2008/05/concepts-techniques-and-models-of.html
  2. Mozart-oz.org Concurrency - www.mozart-oz.org/documentation/tutorial/node8.html # chapter.concurrency