Скачать презентацию Функциональное программирование I Парадигмы программирования Мотивация Модели вычислений Скачать презентацию Функциональное программирование I Парадигмы программирования Мотивация Модели вычислений

FP I (Intro, Turing Machine).pptx

  • Количество слайдов: 51

Функциональное программирование I Парадигмы программирования. Мотивация. Модели вычислений. Функциональное программирование I Парадигмы программирования. Мотивация. Модели вычислений.

Обзор курса • Парадигмы программирования и языки • Модели вычислений. Лямбдаисчисление, типы и F# Обзор курса • Парадигмы программирования и языки • Модели вычислений. Лямбдаисчисление, типы и F# • Примеры: символьные вычисления, language-oriented programming, DSL, backtracking, проектирование, эмуляция физики в играх.

Prerequisites Программирование: • Знакомство с императивным программированием: переменные, циклы, массивы, структуры, … • Базовое Prerequisites Программирование: • Знакомство с императивным программированием: переменные, циклы, массивы, структуры, … • Базовое знакомство с ООП: классы и объекты, поля, методы, конструкторы, свойства, инкапсуляция, наследование, полиморфизм (подтиповой и ad hoc)

 • Базовые структуры и алгоритмы обработки данных • Начальные знания языка программирования C# • Базовые структуры и алгоритмы обработки данных • Начальные знания языка программирования C# и платформы. Net Математика: • Классическая логика и логика первого порядка, наивная теория множеств • Начальные знания комбинаторики и дискретной теории вероятности • Индукция

Рекомендуемая литература “Introduction to functional programming” — John Harrison “A short introduction to the Рекомендуемая литература “Introduction to functional programming” — John Harrison “A short introduction to the Lambda Calculus”— Achim Jung “Types and Programming Languages”— Pierce “Lambda-Calculus and Combinators, an Introduction”— J. R. Hindley, J. P. Seldin “An Introduction to lambda-calculus and arithmetic with a decent selection of exercises”— H. Simmons, A. Schalk

“Functional Programming for the Real World” — Tomas Petricek, Jon Skeet “Programming F#”— Chris “Functional Programming for the Real World” — Tomas Petricek, Jon Skeet “Programming F#”— Chris Smith “Expert F# 2. 0” — Don Syme “F# for Scientists”— Jon Harrop “Algorithms: A Functional Programming Approach” — Rabhi, Lapalme “Functional Programming in C#” — Sturm Oliver Лекции Andrew Ng с ml-class. org “Real World Haskell” — Bryan O'Sullivan, Donald Bruce Stewart, John Goerzen

Почему программировать сложно? Программирование — это способ взаимодействия с компьютером. Компьютеры и люди различаются, Почему программировать сложно? Программирование — это способ взаимодействия с компьютером. Компьютеры и люди различаются, им нужен некий общий язык. Такой общий язык изначально конструировался как лёгкий для восприятия компьютером, лёгкий для перевода в машинные команды. Возможно, если язык будет ближе человеку, программировать будет проще?

Эволюция языков ASM Fortran, LISP Pascal, C, Scheme, . . . C++, Perl, Java, Эволюция языков ASM Fortran, LISP Pascal, C, Scheme, . . . C++, Perl, Java, C#, Python, . . .

 Старт Финиш Старт Финиш

Парадигмы программирования • Парадигмы программирования •

Императивное программирование • Императивное программирование •

Задача: Посчитать сумму целых чисел от 1 до 10000. private static int Sum() { Задача: Посчитать сумму целых чисел от 1 до 10000. private static int Sum() { var sum = 0; for (var number = 1; number < 10000; number++) { sum = sum + number; } return sum; } Вопрос: Сколько раз будет изменено состояние программы в этом примере?

Ответ зависит от нашего понимания состояния. Если мы будем рассматривать состояние как значения всех Ответ зависит от нашего понимания состояния. Если мы будем рассматривать состояние как значения всех локальных переменных (не учитывая текущее значение instruction pointer’a и т. д. ), то мы можем сказать, что состояние было изменено 20000 раз.

Состояние как источник сложности Изменения состояний сложно анализировать, следовательно, сложно доказать корректность программы. Состояния Состояние как источник сложности Изменения состояний сложно анализировать, следовательно, сложно доказать корректность программы. Состояния трудно отслеживать: в любой нетривиальной программе происходят миллиарды изменений состояний — мы практически никогда не можем сказать, что на самом деле находится в некой переменной в конкретный момент времени.

 •

 •

Функциональное программирование — это парадигма программирования, представляющая программу как вычисление математической функции без использования Функциональное программирование — это парадигма программирования, представляющая программу как вычисление математической функции без использования изменяемых данных и состояний. ФП трактует функции как объекты первого класса — содержит конструкции, позволяющие работать с функциями также легко, как с любыми другими данными например, целыми числами.

Например, наш пример мы можем написать на функциональном языке следующим образом: let sum = Например, наш пример мы можем написать на функциональном языке следующим образом: let sum = List. sum [1. . 10000] sum — это не переменная, а поименованное значение. Обратите внимание: нам больше не нужна локальная переменная n, как и цикл.

Функциональное программирование избегает т. н. сайд-эффектов. Side effect — это свойство выражения/функции. Кроме возврата Функциональное программирование избегает т. н. сайд-эффектов. Side effect — это свойство выражения/функции. Кроме возврата некого результирующего значения, функции с сайд-эффектами меняют состояние, например: Ø изменяют значение глобальных переменных Ø изменяют значение переданных им аргументов Ø совершают ввод/вывод Ø вызывают другие выражения/функции с сайдэффектами.

Отсутствие/Выделение побочных эффектов: Ø Повышение надёжности программ Ø Облегчение параллельного программирования Ø Облегчение анализа Отсутствие/Выделение побочных эффектов: Ø Повышение надёжности программ Ø Облегчение параллельного программирования Ø Облегчение анализа программ и доказательства корректности. ФП является одним из вариантов т. н. декларативного программирования: мы описываем не то, как получить решение, а что такое решение.

Уравнение Беллмана let a. OS = [ for outcomes in (possible. Outcomes state) -> Уравнение Беллмана let a. OS = [ for outcomes in (possible. Outcomes state) -> List. fold (fun acc (state', probability) -> acc + probability * U. [state']) 0. outcomes ] if is. Terminal state |> not then U'. [state] <- reward state + gamma * (List. max a. OS)

Быстрая сортировка На Haskell: quicksort [] = [] quicksort (p: xs) = (quicksort lesser) Быстрая сортировка На Haskell: quicksort [] = [] quicksort (p: xs) = (quicksort lesser) ++ [p] ++ (quicksort greater) where lesser = filter (< p) xs greater = filter (>= p) xs На F#: let rec quicksort = function | [] -> [] | x: : xs -> let lesser = List. filter ((>) x) xs let greater = List. filter ((<=) x) xs (quicksort lesser) @ [x] @ (quicksort greater)

На C: void qsort(int a[], int lo, int hi) { int h, l, p, На C: void qsort(int a[], int lo, int hi) { int h, l, p, t; if (lo < hi) { l = lo; h = hi; p = a[hi]; do { while ((l < h) && (a[l] <= p)) l = l+1; while ((h > l) && (a[h] >= p)) h = h-1; if (l < h) { t = a[l]; a[l] = a[h]; a[h] = t; } } while (l < h); a[hi] = a[l]; a[l] = p; qsort( a, lo, l-1 ); qsort( a, l+1, hi ); } } Решения на Haskell и F# работают с любыми типами данных, для которых определено сравнение: автогенерализация. Решение на C работает только со списками целых чисел.

Вставка в AVL-дерево На C++: int insert(tree_node_t *tree , key_tne w_key, object_t *new_object) { Вставка в AVL-дерево На C++: int insert(tree_node_t *tree , key_tne w_key, object_t *new_object) { tree_node_t*t mp_node; int finished; if( tree->left == NULL ) { tree->left = (tree_node_t*)new_object; tree->key = ne w_key; tree->height= 0; tree->right = NULL; } else { create_stack(); tmp_node = tree; На F#: let rec add. Vertex. AVL v = function | AVLEmpty -> AVLNode(v, 1, AVLEmpty, AVLEmpty) | AVLNode(v', _, left, right) when v < v' -> let new. Left = add. Vertex. AVL v left let left. Root = get. Root new. Left let h. Root = (max (height new. Left) (height right)) + 1 while( tmp_node->right != NULL ) if (height new. Left - height right) = 2 then { push(tmp_node ); . . . 116 строк 24 строки

Hole in the Middle //инициализация var bmp = new Bitmap(width, height) using(var gr = Hole in the Middle //инициализация var bmp = new Bitmap(width, height) using(var gr = Graphics. From. Image(bmp)) { (. . . ) //основные действия } Функции высшего порядка: var bmp = Draw. Image(width, height, gr => { (. . . ) //основные действия });

Undo ООП — иерархия классов: Undo ООП — иерархия классов:

Выполнение команды: Выполнение команды:

Отмена команды: Отмена команды:

ФП (F#): type Op. Type = (Data. Type -> Data. Type) * Data. Type ФП (F#): type Op. Type = (Data. Type -> Data. Type) * Data. Type let performed. Ops = Stack() let undone. Ops = Stack() let execute operation data = let res = operation data performed. Ops. Push(operation, data) res let undo () = if performed. Ops. Count > 0 then undone. Ops. Push(performed. Ops. Pop()) Some (snd undone. Ops. Peek()) else None

Данный подход имеет некоторые дополнительные преимущества перед использованием ООП: • Можно легко создавать макросы Данный подход имеет некоторые дополнительные преимущества перед использованием ООП: • Можно легко создавать макросы и сложные операции с помощью композиции или pipelining’a простых операций • Можно создавать сложные структуры данных, содержащие операции, например для динамического построения меню.

Несколько фактов Долгие годы во многих университетах США и Европы функциональные языки преподаются как Несколько фактов Долгие годы во многих университетах США и Европы функциональные языки преподаются как первый язык программирования. Emacs написан большей частью на LISP используется в Auto. CAD. Ericsson разработала функциональный язык Erlang – разработка приложений, использующих параллельные вычисления, ускорилась в 5 -25 раз, длина программ сократилась в 2 -5 раз. Erlang так же используют T-Mobile, Nortel и Facebook.

2000—настоящее время: Бум ФП Большая часть серверного кода Twitter была переписана с языка Ruby 2000—настоящее время: Бум ФП Большая часть серверного кода Twitter была переписана с языка Ruby (ОО/динамический) на язык Scala (функциональный/ОО, статическая типизация) – таким образом разработчики решили проблемы, возникающие из-за активного роста числа пользователей сервиса. Microsoft разработала и включила в состав Visual Studio 2010 язык F# - диалект OCaml’a, функциональный/OO/модульный. Microsoft планирует использовать его для масштабируемых , асинхронных и реактивных приложений, использующих параллельные вычисления. Также F# можно использовать как скриптовый язык. Часть движка Bing была переписана на F#.

Языки, сочетающие ОО и ФП Ø Ø Ø Ø Erlang (1986) Perl (1987)* Python Языки, сочетающие ОО и ФП Ø Ø Ø Ø Erlang (1986) Perl (1987)* Python (1991) Ruby (1995) OCaml (1996) C# (2001) F# (2002) Groovy (2003) Boo (2003) Scala (2003) Nemerle (2006) ОО диалекты Haskell’a: O’Haskell, Haskell++, Mondrian В Common Lisp было включено объектное расширение CLOS, так что теперь он тоже сочетает обе парадигмы *Курсив – слабая поддержка ФП

FP’s Pros & Cons Pros Cons Скорость разработки Скорость и используемая память Облегчение поддержки FP’s Pros & Cons Pros Cons Скорость разработки Скорость и используемая память Облегчение поддержки Сложность начального обучения Надёжность и корректность Статическая типизация с выведением типов Краткость синтаксиса и кода Работа со сложными структурами данных Параллельные, реактивные и асинхронные приложения Интерпретатор + компилятор Чёткий математический базис Модульность LOP/DSLs

Map. Reduce “Our abstraction is inspired by the map and reduce primitives present in Map. Reduce “Our abstraction is inspired by the map and reduce primitives present in Lisp and many other functional languages. . Our use of a functional model with user-specified map and reduce operations allows us to parallelize large computations easily and to use reexecution as the primary mechanism for fault tolerance. ” Jeffrey Dean and Sanjay Ghemawat, “Map. Reduce: Simplified Data Processing on Large Clusters” Map 1 Input Reduce 1 Map 2 Reduce 2 . . . Map n . . . Reduce m Output

There’s no silver bullet ФП — далеко не лучший вариант, если вы хотите написать: There’s no silver bullet ФП — далеко не лучший вариант, если вы хотите написать: Ø GUI Ø ПО, критичное по скорости, но не масштабируемое (e. g. : система компьютерной алгебры для пользовательских машин)

Модели вычислений — это описание абстракции и набора допустимых операций для представления вычисления. Например: Модели вычислений — это описание абстракции и набора допустимых операций для представления вычисления. Например: машина Тьюринга, машина Поста, лямбда-исчисление, рекурсивные функции, … Модели вычислений используются в анализе алгоритмов и служат отправной точкой в дизайне языков программирования.

Машина Тьюринга — это абстрактное устройство с памятью, читающее и записывающее символы на бесконечную Машина Тьюринга — это абстрактное устройство с памятью, читающее и записывающее символы на бесконечную ленту. Действия устройства зависят от символа на ленте и состояния устройства. Алгоритм задаётся конечной таблицей, представляющей функцию перехода.

Пример: сложение чисел Задача: Необходимо сложить 2 числа, записанные на ленте. Ввод: Числа представлены Пример: сложение чисел Задача: Необходимо сложить 2 числа, записанные на ленте. Ввод: Числа представлены в виде последовательности единиц. Головка находится на первой единице первого числа. Числа разделены одной ячейкой со знаком «+» . Вывод: Головка находится на ячейке ленты, следующей за последней цифрой суммы.

\ \ 1 1 1 \ \ S = s 0 L = “ \ \ 1 1 1 \ \ S = s 0 L = “ 1” A = R Идём до пустой ячейки S = s 0 L = “” S = s 1 L = “ 1” A = R Ставим вместо неё единицу S = s 1 L = “ 1” A = R Идём до конца 2 ого числа S = s 1 L = “\” S = s 2 L = “\” A = L Возвращаемся к последней цифре 2 ого числа S = s 2 L = “ 1” S = FIN L = “\” A = None Стираем последнюю цифру \ \ 1 1 1 \ \ \ S – state, состояние устройства L – letter, символ на ленте A – action, действие, которое необходимо выполнить

Формальное определение • Формальное определение •

 •

 • s 0, `1`, R s 1, `1`, R s 1, `\` s • s 0, `1`, R s 1, `1`, R s 1, `\` s 2, `\`, L s 2, `1`

Задание #1 Напишите спецификацию машины Тьюринга, убирающей все пробелы из строки, кончающейся восклицательным знаком. Задание #1 Напишите спецификацию машины Тьюринга, убирающей все пробелы из строки, кончающейся восклицательным знаком. Например, для: H E L L O , W O R L D ! \ она вернёт: H E L W

Машина Тьюринга и императивное программирование Машина Тьюринга работает за счёт изменения состояния. Таким образом, Машина Тьюринга и императивное программирование Машина Тьюринга работает за счёт изменения состояния. Таким образом, это, по сути, модель императивного программирования. Стоит, однако, отметить, что машина Тьюринга мощнее реальных компьютеров — у неё есть бесконечная память.

Недетерминированная машина Тьюринга • Недетерминированная машина Тьюринга •

Результат мы получим, когда одна из этих машин завершится. Любую НМТ можно выразить как Результат мы получим, когда одна из этих машин завершится. Любую НМТ можно выразить как ДМТ с тремя лентами, первая из которых всегда содержит начальную входную строку, вторая используется для эмуляции одного из текущих вычислений НМТ, а третья — для представления пути в дереве вычислений, приведшего к вычислению на второй. Такую трёхленточную ДМТ можно легко свести к обычной одноленточной.

Таким образом, ДМТ может посчитать всё то же, что и НМТ, но медленнее. Это Таким образом, ДМТ может посчитать всё то же, что и НМТ, но медленнее. Это сводится к самому главному нерешённому вопросу в теоретической информатике: равны ли классы сложности P и NP? Существует также универсальная машина Тьюринга, могущая эмулировать любую машину Тьюринга. Её можно построить, что и было сделано Тьюрингом. Таким образом, впервые была получена модель компьютера с хранимой программой.