- •Парадигми програмування
- •8.080401: Інформаційні управляючі системи та технології
- •Тема 1. Парадигма імперативного програмування Лекція 1. Огляд парадигм програмування
- •1.1 Базові поняття і визначення
- •1.2 Класифікація парадигм програмування
- •Парадигми
- •Объектно-ориентированные возможности
- •Функциональные возможности
- •1.3 Огляд парадигми імперативного програмування
- •1.4 Програмування, кероване подіями
- •1.5 Узгоджене програмування і паралельні обчислення
- •1.6. Підтримка різних парадигм програмування в ms.Net
- •Тема 2. Парадигма об’єктно-орієнтованого програмування Лекція 2. Об'єктно-орієнтоване програмування та його реалізація в c# на платформі ms.Net
- •2.1 Основні принципи об’єктно-орієнтованого програмування
- •2.2 Чисто об'єктно-орієнтовані і гібридні мови програмування
- •2.3. Реалізація принципів ооп в мові c#
- •Тема 3. Програмування за прототипом і сценарне програмування Лекція 3. Програмування за прототипом і сценарне програмування
- •3.1 Програмування за прототипом
- •3.2 Сценарне програмування
- •Тема 4. Парадигма компонентного програмування Лекція 4. Компонентне програмування як розвиток об’єктного
- •4.1 Основні ідеї компонентної розробки
- •4.2 Компонентна об'єктна модель com (Component Object Model).
- •4.3. Технологія ActiveX – основні можливості
- •Лекція 5. Компонентне програмування в .Net
- •5.1 Основні концепції платформи ms.Net
- •5.1.1 Структура fcl
- •5.1.2 Загально мовне середовище виконання – clr – динамічна складова ms.Net Framework
- •5.1.3. Система типів даних в Microsoft .Net
- •Управління типами в cts
- •5.2. Розробка компонентів на платформі .Net
- •5.3. Поняття збірки і маніфесту в .Net
- •1. Створення dll-бібліотеки
- •2. Створення консольного проекту для тестування функції з бібліотеки.
- •3. Підключення проекту бібліотеки до консольного проекту.
- •4. Встановлення стартового проекту.
- •5. Створення Windows-проекту в тому самому рішенні.
- •6. Робимо проект стартовим і запускаємо на виконання. Результат:
- •7. Документування коду
- •Лекція 6. Візуальне програмування
- •6.1. Парадигма візуального програмування
- •1. Підключення до сервера бд
- •2. Створення власної бд і таблиць
- •3. Заповнення таблиці тестовими даними
- •4. Створення Windows-застосунку (форми)
- •5. Зв'язування елементів форми з джерелом даних
- •7. Створення запитів до даних і їх відображення на формі у вигляді таблиці (Grid)
- •Тема 5. Парадигма декларативного програмування Лекція 7. Основи парадигми декларативного програмування
- •7.1 Основи парадигми декларативного програмування
- •7.2 Основи функціонального програмування
- •Основи Лісп
- •7.3 Основи логічного програмування
- •7.4 Основи Пролог
- •Лекція 8. Основи xml
- •8.1. Визначення і структура xml-документа
- •8.2. Створення xml-документа
- •8.2.1. Структура xml-документа
- •8.3. Способи відображення xml-документа
- •8.4. Правила створення коректного xml-документа
- •8.4.1. Визначення коректного документа
- •8.4.2. Складові частини коректно сформованого хмl-документа
- •8.4.3. Додавання елементів в документ
- •8.4.4. Типи вмісту елементу
- •Лекція 9. Робота з xml в .Net
- •9.1. Класи для роботи з xml .Net
- •9.2. Читання і запис потоків даних Xml
- •9.2.1. Використання класу XmlReader
- •9.2.2. Методи читання даних
- •9.2.3. Контроль типів даних при читанні Xml-документа
- •9.3. Створення xml-документа в Visual Studio
- •Лекція 10. Створення xml-документів в .Net
- •10.1. Використання класу XmlWriter - запис потоків даних Xml
- •10.2. Використання dom в .Net
- •10.2.1. Читання xml-документа за допомогою XmlNodeList
- •10.2.2. Вставка елементів (вузлів) в xml- документ
- •10.3. Обробка атрибутів
- •10.3.1. Витягання атрибутів за допомогою XmlReader
- •10.3.2. Вставка атрибутів в документ за допомогою XmlWriter
- •Лекція 11. Елементи функціонального програмування в c#
- •11.1. Елементи функціонального програмування в c#
- •11.2. Делегати
- •11.3. Лямбда-вирази і лямбда-функції
- •Приклади
- •Лекція 12. Мова linq
- •2. Linq: узагальнення і інтерфейси
- •3. Основні операції запиту
- •4. Перетворення даних з linq
- •12.1. Основи мови linq
- •1.1 Джерело даних
- •1.2. Запит
- •1.3. Виконання запиту
- •12.2. Linq: узагальнення і інтерфейси
- •12.2.1. Змінні iEnumerable в запитах linq
- •12.3. Основні операції запиту
- •12.3.1. Визначення джерела даних
- •12.3.2. Фільтрація
- •12.3.3. Впорядкування
- •12.3.4. Угрупування
- •12.3.5. З'єднання
- •12.3.6. Вибір (Проектування)
- •12.4. Перетворення даних з linq
- •12.4.1. З'єднання декількох вхідних послідовностей в одну вихідну
- •12.4.2. Вибір підмножини кожного вихідного елементу
- •12.4.3. Перетворення об'єктів, що знаходяться в пам'яті, в xml
- •12.4.4. Виконання операцій над вихідними елементами
- •12.5. Зв'язки типів в операціях запиту
- •12.5.1. Запити, що не виконують перетворення вихідних даних
- •12.5.2. Запити, що виконують перетворення вихідних даних
- •12.5. 3. Дозвіл компілятору визначати відомості про типа
- •12.6. Синтаксис запиту або синтаксис методу
- •12.6.1. Методи розширення стандартних операторів запитів
- •12.6.2. Лямбда-вирази
- •Тема 7. Парадигма агентно-орієнтованого програмування Лекція 13. Агентно-орієнтоване програмування
- •13.1 Основні поняття агентно-орієнтованої парадигми програмування
- •1. За архітектурою побудови агентів і їх властивостями:
- •За функціональним призначенням:
- •3. За здатністю до мобільності:
- •3Адачні агенти
- •13.2 Мультиагентні інформаційні системи
- •1. Формальна мова опису системи моделей (ментальної, соціальної):
- •2. Інструменти перетворення звичайних програм у відповідні агентні програми.
- •13.3. Приклади практичного застосування агентної парадигми
- •3Асоби пошуку в Інтернет
- •Тема 8. Парадигма теоретичного програмування Лекція 14. Основні парадигми теоретичного програмування
- •Основна література
- •Додаткова література
11.3. Лямбда-вирази і лямбда-функції
Функціональне програмування базується на лямбда численні, яке запропоноване Алонзо Черчем.
Вікипедія дає таке визначення:
Лямбда-числення (исчисление, лямбда-числення) — формальна система, розроблена американським математиком Алонзо Черчем, для формалізації і аналізу поняття обчислюваності.
лямбда-числення може розглядатися як сімейство прототипних мов програмування. Їх основна особливість полягає в тому, що вони є мовами вищих порядків. Тим самим забезпечується систематичний підхід до дослідження операторів, аргументами яких можуть бути інші оператори, а значенням також може бути оператор. Мови в цьому сімействі є функціональними, оскільки вони базуються на уявленні про функцію або оператор, включаючи функціональну аплікацію і функціональну абстракцію.
Базисом функціонального програмування є лямбда вирази і анонімні функції.
Анонімні функції дозволяють створити функції, в яких немає імені.
У контексті мов програмування під лямбда-функцією розуміють анонімну функцію. Тобто функцію, якій не зіставлено жодне ім'я, просто значення функціонального типа.
Анонімна функція – це оператор або вираз "inline", який можна використовувати кожного разу, коли очікується тип делегата. Її можна використовувати для ініціалізації іменованого делегата або підставити замість типу іменованого делегата як параметр методу.
Існує два типи анонімних функцій:
Лямбда-вирази
Анонімні методи
Лямбда-вираз — це анонімна функція, яка містить вирази і оператори і може використовуватися для створення делегатів або типів дерев виразів.
У всіх лямбда-виразах використовується лямбда-оператор =>, який читається як "переходить в". Ліва частина лямбда-оператора визначає параметри введення (якщо такі є), а права частина містить вираз або блок оператора.
Лямбда-вираз x => x * x читається як "x переходить в x x разів". Цей вираз може бути призначений типу делегата таким чином:
delegate int del(int i);
static void Main(string[] args)
{
del myDelegate = x => x * x;
int j = myDelegate(5); //j = 25
}
Оператор => має той самий пріоритет, що і оператор призначення (=) і є правоасоциативним.
Багато мов програмування підтримують роботу з анонімними функціями.
Приклади
С#
delegate(int x){return x +1; }
Pyton
lambda x: x + 1
Lisp
(lambda (x) (+ x 1))
PHP (http://blog.kron0s.com/anonymous-functions-in-php )
Змінні-функції
До того як сказати що-небудь про анонімні функції, поглянемо на концепцію PHP відому як змінні-функції. Вона полягає в тому, що якщо додати до змінної круглі дужки, то інтерпретатор PHP спочатку перевірить, чи не існує функції з ім'ям рівним значенню змінної і якщо вона є - виконати її. Це можна побачити на наступному прикладі:
function Hello($name)
{
echo "Привіт $name";
}
Ми можемо викликати цю функцію, використовуючи змінну, що зберігає її ім'я. І це може бути дуже корисно, якщо ім'я функції не визначене до моменту виконання.
$func = "Hello";
$func("Світ!");
// результат:
//Привіт, Світ!
Інший приклад, використовуючи клас і статичний метод:
<?php
class CHello
{
static function Hello($name)
{
echo "Привіт $name";
}
}
$func = "Hello";
CHello::$func("Світ!");
// результат:
// Привіт, світ!
?>
Анонімні або лямбда функції в php
Буває необхідно створити невелику локальну функцію, що складається всього з декількох рядків, наприклад, для зворотнього виклику. Безглуздо забруднювати глобальний простір імен такого роду одноразовими функціями. Набагато краще створити анонімну або лямбда функцію використовуючи create_function.
Розглянемо на прикладі:
<?php
$str = "Привіт, Світ!";
$lambda = create_function('$match', 'return "Друг!";');
$str = preg_replace_callback('/Мир/' $lambda, $str);
echo $str ;
?>
Тут ми створили маленьку безіменну (анонімну) функцію, яка викликається у функції preg_replace_callback. Хоча create_function дозволяє створити анонімні функції, це не частина мови, а "хак". PHP 5.3 підтримує по справжньому анонімні функції як частину мови. Ми створюємо безіменну функцію і призначаємо її змінній і потім просто використовуємо цю змінну як функцію.
Приклад:
<?php
$func = function($name)
{
echo "Привіт $name\n";
};
$func("Світ!");
$func("Олексій!");
// результат:
//Привіт, Світ!
//Привіт, Олексій!
?>
Зверніть увагу, що в кінці визначення функції є крапка з комою. Вона необхідна, оскільки таке визначення функції це твердження, а після визначення твердження завжди має бути крапка з комою. Ще один приклад:
<?php
$str = "Привіт, Світ!";
$func = function($match)
{
return "друг!";
};
$str = preg_replace_callback('/Мир/' $func, $str);
echo $str ;
?>
Анонімні і вкладені функції
PHP дозволяє вкладати функції всередину одна одної. Розглянемо на прикладі. Функція censorString приймає рядок як параметр і замінює потрібні слова в рядку на "*". Функція censorString визначає вкладену функцію replace, яка використовується при виклику preg_replace_callback. Враховуючи те, що функція replace використовується в нашій програмі лише у функції censorString, краще всього визначити її як вкладену, аби не забруднювати простір імен.
<?php
function censorString($string, $censor)
{
function replace($match)
{
return str_repeat("*", strlen($match[0]));
}
return preg_replace_callback('/'.$censor.'/', 'replace' $string);
}
echo censorString("Привіт, світ!", "світ");
echo censorString("Привіт, світ!", "Привіт");
// результат:
// Привіт ***!
// Fatal error: Cannot redeclare replace()
?>
При такому визначенні функції як в прикладі вище, вкладена функція не існує до тих пір, поки не почнеться виконуватися батьківська функція. Як тільки виконується батьківська функція (censorString), вкладена функція з'являється в глобальному просторі імен. Тепер ми можемо дістати доступ до вкладеної функції з будь-якого місця програми. Проблема полягає в тому, що при повторному виклику батьківської функції буде зроблена спроба передекларувати вкладену функцію, що викличе помилку, оскільки вона вже існує. Рішення в тому, аби використовувати вкладену функцію, як це показано нижче. (Зверніть увагу на крапку з комою в кінці вкладеної функції.)
<?php
function censorString($string, $censor)
{
$func = function($match)
{
return str_repeat("*", strlen($match[0]));
};
return preg_replace_callback('/'.$censor.'/', $func, $string);
}
echo censorString("Привіт, світ!", "світ");
echo censorString("Привіт світ!", "Привіт");
// результат:
// Привіт ***!
// ******, світ!
?>
Тепер вкладена функція з'являється лише на час виконання censorString. Отже, ми можемо повторно викликати функцію censorString без того, аби викликати помилку передекларації.
Інший спосіб визначити вкладену функцію:
<?php
function censorString($string, $censor)
{
return preg_replace_callback('/'.$censor.'/',
function($match)
{
return str_repeat("*"
strlen($match[0]));
},
$string);
}
echo censorString("Привіт, світ!", "світ");
echo censorString("Привіт, світ!", "Привіт");
// результат:
// Привіт ***!
// ******, світ!
?>
Замикання
Замикання це анонімна функція зі своїм контекстом. Коротше кажучи, це функція, яка знає про змінні, не визначені в ній. Розглянемо на простому прикладі. Скажімо, ми хочемо створити анонімну функцію, яка множить число на 5.
<?php
$mult = function($x)
{
return $x * 5;
};
echo $mult(2);
// результат:
// 10
?>
Якщо ми хочемо щоб число множилося на 7 замість 5, нам необхідно створити іншу функцію. Замість того щоб створювати декілька майже однакових функцій, створимо замикання, використовуючи конструкцію use, яка дає анонімній функції доступ до зовнішніх змінних і "замикає" їх в поточній функції.
<?php
$multiply = function($multiplier)
{
return function($x) use ($multiplier)
{
return $x * $multiplier;
};
};
// $mul5 тепер містить функцію, яка умножає аргумент на п'ять
$mult5 = $multiply(5);
// $mul7 тепер містить функцію, яка умножає аргумент на сім
$mult7 = $multiply(7);
echo $mult5(5);
echo $mult7(5);
// результат:
// 25
// 35
?>
Лямбда функції і замикання наближають PHP по функціональності до інших сучасних мов.
