Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ПрограмЧ1-вторник.docx
Скачиваний:
2
Добавлен:
09.11.2019
Размер:
336.34 Кб
Скачать

Класифікація мов програмування

Мови П.

Характеристика

«Низького рівня»

(20-ті - 40-ві роки)

  • орієнтувались на чисельні розрахунки;

  • програми були лінійними послідовностями;

  • оптимізація під апаратну архітектуру комп’ютера;

  • називались язиками ассемблерами

«Високого рівня» (50-ті роки)

Імперативний підхід (50-ті роки…)

  • абстрагувались від конкретних деталей апаратного забезпечення;

  • програми були набором директив, звернених до комп'ютера;

  • давали можливість повторного використання раніше написаних програмних блоків /функцій, процедур/;

  • прикладом є мова Fortran, що реалізовує обчислювальні алгоритми. Інший приклад - мова APL, що трансформувалася в BPL і потім в C. Основні конструкції останнього залишаються незмінними ось вже декілька десятиліть і присутні в мові C#. Приклади інших імперативних мов програмування: ALGOL, COBOL, Pascal, Basic

.

Декларативний підхід (60-ті роки…)

  • програма є описом дій, які необхідно здійснити;

  • простіше і прозоріше формалізується математичними засобами;

  • менші трудовитрати. Зокрема, мова SML, була розроблена як засіб доказу теорем. Різні діалекти мови давали можливість повторного використання раніше написаних програмних блоків /функцій, процедур/;

  • високий рівень абстракції;

  • зокрема, Interlisp, Common Lisp, Scheme), виникли тому, що ядро і ідеологія мови виявилися ефективною при реалізації символьної обробки (аналізі текстів). Інші характерні приклади декларативних мов програмування: SML, Haskell, Ocaml, F#, Prolog.

Ф

ункціональний підхід. Логічний підхід. Об’єктно-орієнтований підхід

/С#,Visual Basic, Eiffel, Oberon/

Мови сценарії або скріпти на основі подійно керованої концепції /90 роки/

Мови підтримки паралельних обчислень

Підходи до програмування: -ранні неструктурні підходи; -структурний або модульний підхід (завдання розбивається на підзадачі, потім на алгоритми, складаються їх структурні схеми і здійснюється реалізація); ·- функціональний підхід; · -логічний підхід; · - об'єктно-орієнтований підхід; ·- мішаний підхід (деякі підходи можна комбінувати); ·- компонентно-орієнтований (програмний проект розглядається як багатокомпонентний, такий підхід прийнятий, зокрема, в .NET); ·- чисто об'єктний підхід (ідеальний з математичної точки зору варіант, який поки не реалізований практично).

1.2Функціональний підхід до програмування

Час появи теоретичних робіт, що обгрунтовують функціональний підхід, відноситься до 20-м - 30-м рокам XX сторіччя. Що стосується першої реалізації, то вона з'явилася в 50-х роках XX сторіччя у формі мови LISP, про яку мова піде далі. Нагадаємо, що найважливішою характеристикою функціонального підходу є та обставина, що всяка програма, розроблена на мові функціонального програмування, може розглядатися як функція, аргументи якої, можливо, також є функціями. Функціональний підхід породив ціле сімейство мов, родоначальником яких, як вже наголошувалося, стала мова програмування LISP. Пізніше, в 70-х роках, був розроблений первинний варіант мови ML, яка згодом розвинулася, зокрема, в SML, а також ряд інших мов таких як створений в 90-х роках, мова Haskell, і F#.

Важливою перевагою реалізації мов функціонального програмування є автоматизований динамічний розподіл пам'яті комп'ютера для зберігання даних. При цьому програміст позбавляється від необхідності контролювати дані, а якщо буде потрібно, може запустити функцію "збірки сміття" - очищення пам'яті від тих даних, які більше не знадобляться програмі.

Складні програми при функціональному підході будуються за допомогою агрегації функцій. При цьому текст програми є функцією, деякі аргументи якої можна також розглядати як функції. Таким чином, повторне використання коду зводиться до виклику раніше описаної функції, структура якої, на відміну від процедури імперативної мови, математично прозора. Оскільки функція є природним формалізмом для мов функціонального програмування, реалізація різних аспектів програмування, пов'язаних з функціями, істотно спрощується. Інтуїтивно прозорим стає написання рекурсивних функцій, тобто функцій, що викликають самих себе як аргумент. Природною стає і реалізація обробки рекурсивних структур даних. Завдяки реалізації механізму зіставлення із зразком, такі мови функціонального програмування як ML і Haskell добре використовувати для символьної обробки.

Природно, мови функціонального програмування не позбавлені і деяких недоліків.

Часто до них відносять нелінійну структуру програми і відносно невисоку ефективність реалізації. Проте перший недолік достатньо суб'єктивний, а другий успішно подоланий сучасними реалізаціями, зокрема, рядом останніх трансляторів мови SML, включаючи і компілятор для середовища Microsoft .NET.

Для професійної розробки програмного забезпечення на мовах функціонального програмування необхідно глибоко розуміти природу функції. Відмітимо, що під терміном "функція" в математичній формалізації і програмній реалізації маються на увазі різні поняття. Так, математичною функцією f з областю визначення A і областю значень B називається безліч впорядкованих пар (a,b) A × B, таких, що якщо (a,b1) f и (a,b2) f, то b1 = b2.

У свою чергу, функцією в мові програмування називається конструкція цієї мови, що описує правила перетворення аргументу (так званого фактичного параметра) в результат.

Лямбда – числення. Для формалізації поняття "функція" була побудована математична теорія, відома під назвою лямбда - числення. Точніше це числення слід іменувати численням ламбда - конверсий. Під конверсією розуміється перетворення об'єктів числення (а в програмуванні - функцій і даних) з однієї форми в іншу. Початковим завданням в математиці було прагнення до спрощення форми виразів. У програмуванні саме це завдання не є таким істотним, хоча, як ми побачимо надалі, використання ламбда - числення як початковій формалізації може сприяти спрощенню виду програми, тобто вести до оптимізації програмного коду. Крім того, конверсії забезпечують перехід до знов введених позначень і, таким чином, дозволяють представляти наочну область компактнішому або детальнішому вигляді, або, кажучи математичною мовою, змінювати рівень абстракції по відношенню до наочної області. Цю можливість широко використовують також мови об'єктно-орієнтованого і структурно-модульного програмування в ієрархії об'єктів, фрагментів програм і структур даних. На цьому ж принципі заснована взаємодія компонентів додатку в .NET. Саме у цьому сенсі перехід до нових позначень є одним з найважливіших елементів програмування в цілому, і саме ламбда-численням (на відміну від багатьох інших розділів математики) є адекватний спосіб формалізації переобозначеній.

Систематизуємо еволюцію теорій, лежачих в основі сучасного підходу до лямбда - числення. Розглянемо еволюцію мов програмування, що розвиваються в рамках функціонального підходу. Ранні мови функціонального програмування, які беруть свій початок від класичної мови LISP (List Processing), були призначені, для обробки списків, тобто символьній інформації. При цьому основними типами були атомарний елемент і список з атомарних елементів, а основний акцент робився на аналізі вмісту списку. Розвитком ранніх мов програмування стали мови функціонального програмування з сильною типізацією, характерним прикладом тут є класичний ML, і його прямий нащадок SML. У мовах з сильною типізацією кожна конструкція (або вираз) повинна мати тип. При цьому в пізніших мовах функціонального програмування немає необхідності в явному приписуванні типу, і типи спочатку невизначених виразів, як в SML, можуть виводитися (до запуску програми), виходячи з типів пов'язаних з ними виразів.

Наступним кроком в розвитку мов функціонального програмування стала підтримка поліморфних функцій, тобто функцій з параметричними аргументами (аналогами математичної функції з параметрами). Зокрема, поліморфізм підтримується в мовах SML, Miranda і Haskell.

На сучасному етапі розвитку виникли мови функціонального програмування "нового покоління" з наступними розширеними можливостями: зіставлення із зразком (Scheme, SML, Miranda, Haskell), параметричний поліморфізм (SML) і так звані "ледачі" (в міру необхідності) обчислення (Haskell, Miranda, SML). Сімейство мов функціонального програмування є чисельним. Про це свідчить не стільки значний список мов, скільки той факт, що багато мов дали початок цілим напрямам в програмуванні. Нагадаємо, що LISP дав початок цілому сімейству мов: Scheme, Interlisp, COMMON Lisp і ін.

Не стала виключенням і мова програмування F#, що вивчається нами, яка була створена на основі мови Ocaml і спочатку призначалась для логічних виводів, зокрема, докази теорем. Мова відрізняється строгою типізацією. Розвитком "класичного" ML стали відразу три сучасні мови з практично однаковими можливостями (параметричний поліморфізм, зіставлення із зразком, "ледачі" обчислення). Це мова SML, розроблена у Великобританії і США, CAML, створений групою французьких учених інституту INRIA, Sml/nj - діалект SML з New Jersey, а також російська розробка - mosml ("московський" діалект ML).

Близькість до математичної формалізації і початкова функціональна орієнтованість послужили причиною наступних переваг функціонального підходу:

• простота тестування і верифікації програмного коду на основі можливості

побудови строгого математичного доказу коректності програм;

• уніфікація представлення програми і даних (дані можуть бути

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

значення функції може проводитися в міру необхідності);

• безпечна типізація: неприпустимі операції з даними виключені;

• динамічна типізація: можливе виявлення помилок типізації під час виконання (відсутність цієї властивості в ранніх мовах функціонального програмування може приводити до переповнювання оперативної пам'яті комп'ютера);

• незалежність програмної реалізації від машинного представлення даних і системної архітектури програми (програміст зосереджений на деталях реалізації, а не на особливостях машинного представлення даних).

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

  • безпека програмного коду, тобто гарантія відсутності переповнювання пам'яті (у разі коректної написаної програми) і, відповідно, захисту від потенційної нестійкості роботи системи за допомогою штучного створення переповнювання (такі мови програмування як "класичний" C і C++ потенційно небезпечні);

  • статична типізація: всі помилки невідповідності типів виявляються вже на стадії контролю відповідності типів в ході трансляції (а не під час виконання програми, як в LISP і Scheme); виведення типів (немає необхідності явно указувати тип кожного виразу, при цьому результуючий програмний код стає легшим для читання, його легко зберігати і повторно використовувати).

До інших переваг мови функціонального програмування F# слід віднести параметричний поліморфізм (можливість обробляти аргументи абстрактного типу). При цьому трудовитрати на розробку програмного забезпечення скорочуються за рахунок універсальності функцій, що розробляються (скажімо, стає можливим написати уніфіковану функцію для впорядкування за збільшенням елементів списку, яка зможе упорядковувати і список з цілочисельних елементів, і список з символьних рядків).

Ще одним могутнім засобом, що полегшує символьну обробку (зокрема, декомпозицію і верифікацію програм), є механізм зіставлення із зразком. Обробка виняткових ситуацій, які описують хід виконання програми у разі виникнення тих або інших щодо рідкісних подій, а також теоретично цікавого механізму продовжень, створює можливість реалізації програмних систем, що взаємодіють з користувачем в реальному часі. Відмітимо, що реалізація переваг, які надають мови функціонального програмування, істотно залежить від вибору програмно-апаратної платформи. Функціональне програмування грунтується на простій моделі обчислень, що складається з трьох конструкцій: змінні, визначення функції і її застосування до якого-небудь аргументу. Ця модель, звана л-числення, була введена Alonzo Church в 1932, ще до появи перших комп'ютерів. У л-численні будь-яка функція є змінною, так що вона може бути використана як вхідний параметр іншої функції, або повернена як результат іншої. Теорія л-числення затверджує що все те, що обчислюване може бути представлено цим формалізмом. Проте, синтаксис цієї теорії дуже обмежений, щоб його можна було використовувати його як мова програмування. У зв'язку з цим до л-числення були додані базові типи (наприклад, цілі числа або рядки символів), оператори для цих типів, структури, що управляють, і оголошення дозволяють іменувати змінні або функції, і зокрема рекурсивні функції. У разі вибору програмної платформи технології .NET, практично незалежно від апаратної реалізації, програміст або керівник програмного проекту додатково отримує наступні переваги:

• інтеграція різних мов функціонального програмування (при цьому максимально використовуються переваги кожної з мов);

• інтеграція різних підходів до програмування на основі міжмовної інфраструктури Common Language Infrastructure, або CLI (зокрема, можливе використання C# для забезпечення переваг об'єктно-орієнтованого підходу і F# - функціонального);

• загальна уніфікована система типізації Common Type System, CTS (одноманітне і безпечне управління типами даних в програмі);

• багатоступінчата, гнучка система забезпечення безпеки програмного коду (зокрема, на основі механізму складок).