ПАРАДИГМА ФУНКЦІОНАЛЬНОГО ПРОГРАМУВАННЯ 1 страница
1.1 Поняття парадигми програмування
Будемо розуміти під парадигмою програмування спосіб мислення і спосіб програмування, які не пов’язані з певною мовою програмування.
По-іншому під парадигмою програмування розуміють спільну для групи мов програмування обчислювальну модель.
Парадигма програмування характеризується: засобами опису даних, методами і ефективністю цих методів до розв’язку певних класів задач.
Для алгоритмічних мов обчислювальною моделлю є абстрактна машина Тьюринга-Поста, що описує алгоритми.
Обчислювальна модель об’єктно-орієнтованого програмування має тільки одну операцію – посилку об’єкту повідомлення. Повідомлення є також об’єктом і може мати параметри, що також є об’єктами.
Обчислювальну модель логічного програмування засновано на описі задачі сукупністю тверджень на формальній логічній мові та одержання розв’язку задачілогічним виводом у деякій формальній системі.
1.2 Парадигма функціонального програмування
Обчислювальна модель функціонального програмування заснована на лямбда-численні Черча.
Модель функціонального програмування розглядає кожну програму як вираз, а виконання програми як обчислення значення цього виразу.
Ця модель звичайно застосовується для задач, які важко сформулювати в термінах послідовних операцій.
Задачі штучного інтелекту майже завжди не можуть бути визначені в термінах послідовних операцій. Серед них треба відмітити задачі розпізнання образів, спілкування з користувачем на природній мові, реалізацію експертних систем, автоматизоване доведення теорем, символічні обчислення.
Використовуючи обчислювальну модель функціонального програмування, можна реалізовувати звичайне послідовне операторне (імперативне) програмування з привласнюванням значень змінним, операторами переходів і організації циклів. Сучасні діалекти LISP всі мають функції, що дозволяють реалізовувати операторний підхід.
Обчислювальна модель функціонального програмування також дозволяє реалізовувати об’єктно-орієнтований метод програмування, ситуаційне програмування, продукційне програмування і логічне програмування.
Першою мовою функціонального програмування була мова LISP. Мова LISP засновувалась на одній програмній конструкції - функції.
Програма на мові LISP являла собою визначення однієї складеної функції, побудованої методом суперпозиції з викликів інших функцій або виклику себе.
Користувач утворював своє визначення функції, використовуючи виклики стандартних означень функцій та виклики інших означень функцій користувача.
Виклик внутрішньої функції обчислював значення за своїми аргументами та повертав його, як аргумент для зовнішнього виклику функції. Таким чином, будувалась композиція функцій – одна складна функція. Вказаний метод в математиці називають методом суперпозиції. Результат виклику останньої, зовнішньої функції, являв собою результат роботи всієї програми.
Всі означення функцій користувача зберігались окремо одне від одного в середовищі LISP - виділеної та структурованій певним чином оперативній пам’яті. Це дозволяло динамічно викликати означення функцій з будь-якої функції користувача, а також рекурсивно викликати себе.
ТЕМА 2: ІСТОРІЯ ВИНИКНЕННЯ І РОЗВИТКУ МОВИ ПРОГРАМУВАННЯ ЛІСП
2.1 Виникнення мови Lisp
Основні ідеї, на яких базувалась мова програмування Lisp, були розвинені Джоном Маккарті у 1956 році.
В основу мови було покладено апарат математичної логіки лямбда – числення Черча. Це дозволило утворити просту та ясну для розуміння мову програмування.
У 1962 р. Джон Маккарті розробив мову програмування теоретичний Lisp.
Мову було розроблено для роботи з природною мовою, на якій експертна система спілкувалась з користувачем. Робота з природною мовою вимагає від мови програмування засобів структурування текстів, причому структуру тексту неможливо попередньо описати.
Списки дозволяли організовувати символьні дані довільної структури, яку не фіксовано попередньо. Тому, основним типом даних мови було обрано список. Назва мови розшифровується як List Procession (обробка списків).
Крім обробки традиційних типів даних(чисел, рядків), функції мови LISP використовувались для утворення та обробки типу даних – списків.
Сьогодні Lisp залишається найбільш поширеною функціональною мовою. За роки свого існування мова LISP породила множину діалектів. Не дивлячись на те, що майже всі вони носять назву виду «Some Lisp»(якийсь з LISP), різниця між ними значна. Тому діалекти вважають різними мовами.
2.2 Внесок MacLisp і Interlisp у розвиток мов Lisp- сімейства
Перший діалект Lisp 1.5 був утворений протягом 1960 – 1965 років. На початку 70-років найбільш відомими діалектами стали MacLisp і Interlisp.
Мова MacLisp розширювала можливості мови Lisp 1.5. У мові MacLisp стало можливим використовувати функції, що мали будь-яку кількість аргументів. Наприклад, для функції „+” стало можливо вказувати будь-яку кількість аргументів: (+ 1 5 7 9 2 5...).
У мові MacLisp з’явились функції для обробки збійних ситуацій; деякі функції мали власні спеціальні змінні, що керували їх роботою, або зберігали результати роботи.
Важливою особливістю MacLisp стало використання макровизначень(макросів), що дозволило переносить функції з одного діалекту мови LISP, в інший, розширяючи мову.
Перший діалект мови LISP мав лише інтерпретатор. У MacLisp з’явився перший хороший компілятор, а при розробці мови було зроблено акцент на швидкості виконання програм.
Діалект Interlisp вніс також багато важливих ідей в Lisp - програмування, організацію середовища та методологію програмування на мові LISP. Однією з Interlisp ідей була ідея циклу, що була реалізована макросом на Lisp - машинах та в MacLisp, а зараз і в Common Lisp.
Перші діалекти мови Лісп були створені на машинах IBM 704, IBM 7090, PDP-1, DEC PDP-6, і PDP-10.
Базовими комп’ютерами для розв’язку задач штучного інтелекту з використанням Lisp стали машини на базі процесору PDP-10. На них працювали в Массачусетському технологічному інституті, Стенфордському університеті, Карнегі Мелан університеті в 60-70 роках.
Проте, обмеження на кількість дослідників та на малий адресний простір, і як наслідок на розмір окремої програми, стимулювали у 1973 році розробку комп’ютера спеціального призначення - Lisp-машину. Машину було орієнтовано на виконання функцій Лісп програм. Іншим підходом до розв’язку проблеми стало використання комп’ютерів загального призначення з великим адресним простором(DEC VAX і S-1 Mark IIA).
2.3 Поява Lisp - машин
Концепцію Лісп – машини було розроблено наприкінці 60- років, на початку 70-років. Лісп - машину було реалізовано на міні комп’ютері Aльтo Пітером Деучта та Даніелем Бобровим, які використовували мікро код для інтерпретації коду символьної мови.
Наступними розвитком Лісп - машин став ряд D-машин, виготовлених компанією Xerox, на яких використовувалась мова Interlisp-D. Діалекти Ліспу у 80 – роках компілювали програми у D-код, який надалі інтерпретувався програмою інтерпретатором Ліспу.
Поступове розширення мови MacLisp стимулювало утворення компанії „Lisp Machine”(LMI). У 1981 році на ринку з’явились комерційні Лісп – машини від Xerox, „Lisp Machine” від Symbolics.
2.4 Сучасний стан розробок діалектів мови Lisp
Наприкінці 70-років компанія „Lisp Machine” розширює Lisp до більш сучасної мови. З’являються складні lambda - списки, узагальнена функція привласнювання setf, багатократні обчислення, і структури подібні існуючим у Common Lisp.
Вказані можливості є результатами експериментування з програмуванням стилів групи „Lisp Machine”. Джон Вайт та інші члени групи переносили ці особливості до MacLisp.
У 1980 члени групи під керівництвом Скотта Фахлман розпочали роботу над Lisp, що продовжується і зараз. Метою розробки є Scientific Personal Integrated Computing Environment (SPICE) - автоматизоване робоче місце. Одна з цілей проекту: спроектувати більш простий діалект ніж Lisp компанії „Lisp Machine”.
Група Macsyma під керівництвом Джона Вайта розпочала проект наприкінці 70-років, який назвала New Implementation Lisp (NIL) – новий інструмент Лісп для машин серії VAX. Одна із цілей NIL проекту виявлення багатьох проблем Lisp, які дратують користувачів, зберігаючи істотну сумісність з MacLisp.
Приблизно в то же час група дослідників в Стенфордському університеті та Національній лабораторії на ім’я Лоуренса в Лівер морі(Каліфорнія) під керівництвом Ричарда Р. Габріеля розпочала проект Lisp для переносу на S-1 Mark IIA суперкомп’ютер.
В 1969 р. Анзоні Херн і Мартін Гріс з університету штату Юта визначили Стандарт Lisp, як спільне ядро Lisp 1.5 та інших діалектів, щоб реалізувати REDUCE - символічну систему алгебри. На протязі 1970 року, група з Юта розробила спочатку переносний компілятор для Standard Lisp, що оптимізує програму, а потім розширила мову, відому зараз, як Portable Standard Lisp (PSL). У середині 1980 PSL розповсюдився приблизно на дюжину видів комп’ютерів.
Сьогодні мови PSL, Franz Lisp та MacLisp - мають подібні діалекти для Unix машин. З’явились також перші приклади широко відомих діалектів Lisp для багатьох платформ апаратних засобів комп’ютерів.
Одна з найважливіших подій в житті мови Lisp відбулась у другій половині 1970 року: була розроблена мова програмування Scheme у Массачусетському технологічному інституті(МІЕ). Її розробили Джеральд Дж. Сассман Гуй L., Стил Дж. Мова є простим діалектом мови Lisp.
Мова Scheme принесла в Lisp деякі ідеї з програмування семантики мови. Дж. Сассман був одним з головних новаторів, що вніс прогресивні ідеї в Lisp технологію цих років.
Головним достоїнством мови Scheme була лексична простота(мале ядро) та замкненість, першокласне розширення та спрощений синтаксис (ніякого розділення вічок обчислення та вічок функцій).
Деякі з цих достоїнств мали великий вплив на проект Common Lisp.
Пізніше, з 1970 року, концепції програмування, орієнтовані на об’єкт, стали мати сильний вплив на Lisp. Деякі ідеї об’єктно-орієнтованої мови Smalltalk використовувались у декількох широко відомих системах програмування.
Мова Flavors, що орієнтована на об’єкти, мала систему програмування з багатократною спадкоємністю. Вона була розвита для Lisp-машин компанією Howard Cannon та іншими компаніями.
В Xerox досвід роботи з Smalltalk і Knowledge Representation Language (Мовою Представлення Знань - KRL), що направлявся розвитком Lisp Object Oriented Programming System (LOOPS) і пізніше Common LOOPS, дозволив також реалізовувати об’єктно – орієнтовану концепцію програмування для Lisp-машин.
Вказані системи мали вплив на проект Common Lisp Object System (CLOS). Мова CLOS була розвита у вище описаному напрямі, та була створена, як окрема мова „Common Lisp Object System Specification”. Проте, мову не можна рекомендувати, як специфікацію семантики об’єктно-орієнтованої системи.
Серед найбільш поширених сучасних діалектів мови Lisp треба відмітити ELISP, AUTOLISP, SCHEME.
На ELISP реалізовано текстовий редактор EMACS дуже популярний серед користувачів. Редактор відкритий для модифікування і дозволяє компонувати з ним програми розроблювачів.
Мова AUTOLISP розширена для програми AUTODESK AUTOCAD, яка дуже часто застосовується для розв’язку інженерних задач.
Мова SCHEME часто використовується у вищих навчальних закладах для знайомства з функціональною парадигмою програмування на початкових курсах. Мова легка при вивченні її специфікації. Мову також використовують для досліджень у області мов програмування.
2.5 Поява стандарту Common Lisp
З 1980 компанії Symbolics та LMI розвивали мову Lisp для Lisp-машин; групи реалізації апаратних засобів ЕОМ розвивали NIL, Franz Lisp, і PSL; Xerox розвивав Interlisp; а SPICE проект розвивав MacLisp-подібний діалект Lisp, що називався SpiceLisp.
У квітні 1981, після зустрічі відносно розколотого Lisp - товариства, Symbolics, SPICE проект, NIL проект, и S-1 Lisp проект, об’єднуються разом, щоб визначити Common Lisp.
Стандарт Common Lisp був розроблений, як опис сімейства мов. Первинний вплив на Common Lisp мали мови: Lisp компанії „Machine Lisp”, MacLisp, NIL, S-1 Lisp, Spice Lisp, Scheme.
Як ми бачили наприкінці 80-років існувало багато лабораторій та компаній із своїми реалізаціями мови LISP. Щоб уникнути розбіжностей у мовах, була сформована технічна робоча група, щоб розробити проект для ANSI Common Lisp Standard.
Спершу проект очолювали Вайт і Габріель, далі розвивали його Скотт Фахлман, Даніель Вейнреб, Давид Мун, Стил і Габріель.
Цілі включали: сувору стандартизацію для мобільності мови, орієнтованої на об’єктні системи програмування, системи станів, ітеративні засоби обслуговування, способи спілкування з великими наборами символів.
У 1986 був випущений ANSI Common Lisp стандарт. Починаючи з цього моменту розвивають тільки Common Lisp стандарт. Причому пропозиції подаються у ANSI, який ретельно розглядає їх.
Сьогодні COMMON LISP активно розвивається, як більшість мов з відкритим кодом. Мову PRACTICAL COMMON LISP було створено у 2006 році.
ТЕМА 3: ПРИНЦИПИ ПОБУДОВИ ТА ФУНКЦІОНУВАННЯ МОВИ LISP
Сучасні діалекти мови LISP засновуються на спільних принципах.
3.1 Декларативність мови Lisp
На алгоритмічних мовах високого рівня програму подають у вигляді послідовності операторів. При компіляції кожний оператор реалізується фіксованим набором машинних команд, тобто формується алгоритм.
На декларативних мовах програмування не подають алгоритм розв’язку задачі, а описують укрупнені дії, які треба виконати, щоб розв’язати задачу. Компілятор, що формує на основі опису програму, реалізує ці дії своїм методом. Наприклад, розв’язок задачі на мові Пролог реалізується методом логічного виводу.
У мові LISP опис кожної укрупненої дії користувач подає визначенням функції, а зв’язок між функціями подається головною функцією користувача.
Сучасні діалекти мови LISP мають інтерпретатори і компілятори. Компілятор розглядає функції користувача, як опис задачі, і формує об’єктний код, використовуючи опис.
Для декларативних мов характерний «декларативний» підхід і до організації даних. Це означає, що поняття даного, ніяк не пов’язано з його подаванням в пам’яті комп’ютера, а визначається через операції, що виконуються над ним. В декларативних мовах найбільш розповсюджено абстрактні типи даних: дерева, списки, вектора, множини. Наприклад, для типу множина визначаються операції перетину, об’єднання, доповнення множин.
Назва мови LISP означає обробка списків(List Procession). Список основний тип даного у мові LISP.
3.2 LISP – мова функціонального програмування
В мові LISP базовою конструкцією програми є функція. Функція, використовує вхідні аргументи, обчислює результат і повертає його:
Приклад 1:
CL-USER> (+ 23 15)
У поодиноких випадках функція може не мати аргументів або мати довільне число аргументів, але функція завжди повертає результат обчислення.
Приклад 2:
CL-USER> (* 10 2 3 4)
По замовчанню аргументи функції обчислюються, якщо нема заперечення на їх обчислення. У випадку, коли аргументи є змінні, обчислюються значення змінних. Якщо аргумент константа, то він не обчислюється.
Приклад 3:
CL-USER> (setq R 3)
CL-USER> (* R 5)
У приклад 3 функція setq привласнює змінній R значення 3. Перед множенням обчислюється значення змінної R. Результат множення 15.
Аргументами можуть також бути виклики інших функцій. В цьому випадку аргументи зовнішньої функції переглядаються зліва направо: послідовно обчислюються значення аргументів, після чого обчислюється значення функції.
Як в математиці, для вкладених викликів функцій використовується принцип суперпозиції. Результати виконання функцій більш глибокого рівня стають вхідними аргументами зовнішньої функції. Рівень вкладеності функцій, може бути яким завгодно.
Приклад 4:
CL-USER> (* R (/ 10 5) )
У прикладі 4 змінна R зберігає своє значення 3. Другий аргумент перед множенням обчислюється. Результат роботи функції
„ / ” повертається на місце її виклику. Після чого виконується операція множення.
Приклад 5:
CL-USER> (setq L (+ 4 R))
Функція „+” додає 4 і 3, а результат 7 розміщує на місце її виклику. Після чого результат привласнюється змінній L. Результат привласнювання повертається.
Можна заперечити обчислювання значень змінних. Апостроф перед змінною означає функцію, що заперечує обчислення. Іншою формою запису функції є „QUOTE”. Знак «Q» наприкінці функції SETQ означає, що вона заперечує обчислення першого аргументу функції.
Приклад 6:
CL-USER>(SETQ M ‘R)
R
Функція QUOTE заперечує обчислення значення змінної R і повертає символ R.
Можна заперечити обчислення функції.
Приклад 7:
CL-USER> (setq N ‘(+ 3 5) )
(+ 3 5)
У прикладі 7 заперечене обчислення функції «+». Значенням змінної N є список, у якого 3 елемента: «+», «3», «5».
3.3 LISP - мова обробки списків
Базовим типом мови LISP є список. Список записується в круглих дужках. Елемент від елементу відділяється пропуском.
Ми записували виклик функції у формі списку. В список можуть вкладатися інші списки. Ми розглядали виклик функції, у якої аргумент також виклик функції.
У загальному вигляді виклик подається:
(ім’я_функції фактичний_параметр1, … ,фактичний_параметрN),
де фактичний параметр може бути змінною, константою або викликом іншої функції.
У формі списку записуються визначення функцій користувача:
(Defun ім’я_функції_користувача (формальні_параметри) тіло_функції )
Приклад 1:
(Defun SUM (X Y) (+ (* X X) (* Y Y) )
де Defun – ім’я функції, що компілює визначення функції користувача; формальні параметри задаються в формі списку; «тіло функції» представляє дії функції користувача.
Список застосовується також для запису складних даних довільної структури і довжини.
Приклад 2:
CL-USER> (SETQ N ‘(“понеділок” “вівторок” “середа” “четвер” “п’ятниця”))
(“понеділок” “вівторок” “середа” “четвер” “п’ятниця”)
Список має елементами рядки.
Приклад 3:
CL-USER> (setq M ‘( 1 (2 5) ( 5 3 6) ) )
(1 (2 5) ( 5 3 6) )
Список М містить 3 елементи: число 1; підсписок ( 2 5); підсписок (5 3 6).
Для того щоб мати доступ до змінної, достатньо назвати її ім’я. Тому між даними може бути встановлено зв’язок за іменами.
Приклад 4:
CL-USER> (setq M ‘( 3 4 6) N ‘( 7 9 1) )
(7 9 1)
CL-USER> (setq P (list M N) )
( (3 4 5) (7 9 1) )
Функція LIST утворює список з двох елементів. Попередньо обчислюються значення змінних M і N. В результаті буде одержаний список P з двох елементів:
Зв’язок за іменами дозволяє гнучко структурувати списки.
У мові LISP список є універсальною формою запису даних і програм.
3.4 Уніфікований підхід до даних і програм
Форми представлення програм і даних в мові LISP однакові – списки. Це дозволяє програмі оброблювати і перетворювати інші програми і навіть саму себе.
Ця властивість мови LISP дозволяє автоматично створювати програми, тобто реалізовувати системи, що самонавчаються.
В залежності від даних, що поступають у програмну систему, вона може створювати необхідну програму для обробки даних. Такий метод програмування називають «програмуванням, що керується даними».
Означення функції можна розглядати, як звичайний список символів, і корегувати його. Після чого виконати програмно компіляцію функції.
Приклад 1:
CL-USER> (setq D ‘(Defun Sum (X Y) ) (+ X Y) ) )
(Defun Sum (X Y) ) (+ X Y) ) )
CL-USER> (Eval D)
SUM
CL-USER>(SUM 2 3)
Функція Eval ініціює(обчислює) виконання функції Defun, а та компілює функцію Sum.
Дані, які записані в формі списку, можна застосовувати як виклик функції, при умові, що перший елемент функції є іменем функції. Тоді інші елементи списку будуть застосовуватись, як фактичні параметри функції.
Приклад 2:
CL-USER> (setq D ‘(den 23.12.06) )
(den 23.12.06) )
CL-USER> (Eval D)
«Так»
Функція Eval викликає функцію «den» для перевірки, чи є вказане число вихідним днем.
(Defun den (число) (перевірка вказаного числа на ознаку «вихідний»))
Всі змінні із своїми значеннями і визначення функцій мови LISP розташовуються у середовищі – оперативній пам’яті, що виділяється при роботі з системою програмування LISP.
В середовищі однаково зберігаються, як списки даних, так і визначення функцій. Середовище зберігає всі списки разом незалежно від їх призначення.
Зберігання даних і програм у єдиній пам’яті відкриває великі можливості для програмування.
Розміщення даних і програм у єдиній пам’яті було запропоновано фон Нейманом для реалізації універсальної обчислювальної машини ще в 40 роки.
У ті ж роки були висловлювана аналогічна ідея про створення універсальної обчислювальної машини Лебедєвим Сергієм Олексійовичем у Києві. Під його керівництвом була створена перша у СРСР лабораторія розробки обчислювальних машин.
3.5 Відкритість мови
Мова програмування, що має спеціальні засоби, які дозволяють модифікувати або розвивати мову, називається відкритою.
LISP відноситься до відкритих мов за наступними причинами:
- службові програми мови LISP (текстовий редактор, налагоджувач) створено на мові LISP. Це дозволяє користувачу змінювати їх для себе;
- за макрозасобами можна переносити функції з одного діалекту мови LISP, в інший діалект, розширюючи мову;
- за значенням керуючих змінних у середовищі LISP можна змінювати режим роботи певних стандартних функцій;
- функції інтерпретатору доступні для роботи користувача, що дозволяє йому писати функції нижнього рівня.
- LISP – мова відкрита для розширення. Вона дозволяє утворювати функції для реалізації об’єктно-орієнтованого методу програмування, ситуаційного програмування, продукційного програмування, логічного програмування, програмування, що керується даними.
3.6 Динамічна типізація змінних
В мові LISP немає об’яв типів для змінних. Лісп використовує динамічну типізацію змінних. Одній змінній можна привласнювати різні типи даних. У мові Лісп типи прив’язуються до даних.
Вказана властивість дозволяє будувати нові абстрактні типи даних для мов більш високого рівня.
Застосовуючи динамічну типізацію можна писати універсальні функції.
Приклад 1: Написати функцію, що вводить дане і визначає його тип.
CL-USER> (Defun universal () (setq M (READ)) (Type-of M) )
universal
CL-USER> (universal)
(INTEGER 0 16777215)
CL-USER> (universal)
"asd"
(SIMPLE-BASE-STRING 3)
Функції universal все одно, який тип даного вводиться і привласнюється змінній М. Функція повертає тип даного і кількість елементів, а для чисел діапазон типу.
Для сталої роботи програми перед виконанням дії можна контролювати тип даного функціями предикатами.
Приклад 2:
Якщо виконується функція «+», то нечислові аргументи викличуть переривання за помилкою.
CL-USER> (Defun S ( ) (setq K (Read) ) (+ 7 K))
S
CL-USER> (s)
"q"
Повідомлення :”Не число”.
Введемо контроль даного: додавання виконується тільки при умові, що в аргумент К вводиться число.
CL-USER> (defun S ( ) (setq K (Read) ) (If (Numberp K) (+ 7 K)(Print
“Не числовий аргумент”)) )
S
CL-USER> (s)
CL-USER> (s)
"q"
"Не число"
"Не число"
3.7 LISP - мова обробки символьної інформації
Для обробки символьної інформації в мові LISP існують рядкові функції та функції роботи із знаками.
Вказаними функціями можна під час роботи програми формувати ідентифікатори програми, змінювати їх. Мова Lisp дозволяє при роботі з природними мовами будь-яке слово, спец знак, цифру застосовувати як ім’я змінної.
Застосовуючи функції атрибутів і властивостей, можна для кожного слова визначати його граматичні і семантичні характеристики. Структуру речення можна подавати списками.
Інтелектуальні системи працюють з поняттями бази знань, що подаються твердженнями на природній мові. Роботу програми з символічними даними називають символічними обчисленнями.
3.8 LISP - рекурсивна мова
Означення функції користувача можна подавати двома способами: суворо функціональним та імперативним.
При суворо функціональному способі означення функції має тільки одну складну функцію.
При реалізації означення функції суворо функціональним способом операцій, що повторюються застосовують рекурсію. Рекурсія і суворо функціональний спосіб написання функцій дозволяють писати компактні, красиві функції.
Рекурсією зручно оброблювати рекурсивні дані.
При імперативному способі Лісп імітує послідовне виконання функцій. Такий спосіб програмування більш звичний, а цикли організуються стандартними функціями.
3.9 LISP – мова, що базується на Лямбда-численні
Функціональна форма запису визначення функції, виклику функції и обчислення значення функції взято з Лямбда – числення. Лямбда – числення є розділом математичної логіки.
Основою для запису визначення функції і виклику функції є Лямбда – вираз. Лямбда – вираз – це тіло функції с формальними параметрами, що записане без імені:
(LAMBDA (формальні параметри) тіло функції )
Форма виклику функції (Лямбда – виклик) визначається лямбда – механізмом. Форма виклику вказується в префіксній нотації:
(Лямбда - вираз аргумент1 … аргументN).
Підставляючи Лямбда – вираз у Лямбда – виклик одержимо загальний вираз Лямбда – виклику:
((LAMBDA (формальні параметри) тіло функції ) аргумент1 … аргументN)
Лямбда – вираз точно відображує параметризовані обчислення і дозволяє вільно робити вкладені виклики функцій, об’єднувати Лямбда – вирази з іншими формами і Лямбда – виразами.
Лямбда – виклик дозволяє функціям динамічно викликати одна одну або рекурсивно викликати себе безпосередньо або через інші функції. Виклики функцій можуть вкладатися один в другий формуючи складну функцію. Лямбда – вираз складної функції передбачає об’єднання Лямбда – викликів. Визначення функції може бути без імені.
3.9 Принцип модульності
Відомо, що складну проблему легше та швидше вирішити, якщо розділити проблему на 2 простіші проблеми. Принцип сформульований Г. Майерсом - принцип модульності, забезпечує можливість утворювати програми будь-якої складності.
Принцип модульності реалізовано у мовах всього Lisp- сімейства за рахунок того, що кожна програма складається з окремих функцій. Функції пов’язані у єдину програму викликами. По суті програма на мові Лісп – це ієрархічна структура з викликів функцій користувача.
У чітку структуру програми легко додати нову функцію або змінити існуючу. За рахунок модульності збільшується швидкість написання програми - ідея розроблювача прозоро відображується у кожній її функції. Це дозволяє також легко модифікувати програму. При налагоджуванні програми можна кожну функцію налагоджувати окремо. Модульність мови дозволяє розв’язувати складні здачі з максимальною надійністю і ефективністю.
ТЕМА 4: ВСТУП У COMMON LISP
4.1 Стандарт COMMON LISP
Простота і зрозумілість стандарту COMMON LISP, як для програмування, так і для реалізації мови, зробила його популярним.
Стандарт COMMON LISP описує спільне ядро реалізацій. Існують реалізації за стандартом COMMON LISP на машинах різних типів, що робить переносним програмне забезпечення. Однак переносність відноситься тільки до ядра мови.
Реалізації COMMON LISP мають відкритий код, що дозволяє легко розширювати мову, утворювати прототипи для реалізації системи за спіральною моделлю. У Інтернеті розроблено багато бібліотек для COMMON LISP різного призначення також відкритих для поповнення.
Засобами COMMON LISP легко реалізувати підхід, що орієнтовано на об’єкти. Для мов характерна динамічна типізація (змінні не фіксованого типу); гнучка система обробки умов виконання дій.
Швидкість реалізацій COMMON LISP може бути порівняна з швидкістю роботи програми на мові С, при наявності хорошого компілятору і застосуванні спеціальних додаткових об’яв.
4.2 Реалізації стандарту COMMON LISP
Будь-якому розроблювачу дозволяється розробити свою реалізацію мови COMMON LISP відповідно стандарту.
Завдяки вимогам стандарту програми користувача можна виконувати на інших реалізаціях COMMON LISP. Проте, кожна реалізація мови COMMON LISP розширює можливості мови, тобто виходить за стандарт.
Якщо можливості майбутньої системи вимагають розширення мови, то підбирають таку реалізацію мови, що забезпечує необхідні можливості.
У Інтернеті існує багато бібліотек з кодами Common Lisp, що розширюють стандарт у певному напрямку. Наприклад, для утворення графічного інтерфейсу.
Серед реалізацій Common Lisp є, як комерційні, так і безкоштовні. До комерційних реалізації відносяться: Allegro Common Lisp, Harlequin, Corman, Common Lisp – Controller, Ppcre_Common Lisp, Lispworks. До безкоштовних реалізацій відносяться: Gnucl, Clisp, Cmucl.
Дата добавления: 2016-09-20; просмотров: 1031;