Практика мультипарадигмального программирования, 06 лекция (от 02 апреля)
Материал из eSyr's wiki.
(Содержимое страницы заменено на «== From Ebaums Inc to MurkLoar. == We at EbaumsWorld consider you as disgrace of human race. Your faggotry level exceeded any imaginab...») |
(Отмена правки № 1308 участника 85.25.141.60 (обсуждение)) |
||
Строка 1: | Строка 1: | ||
- | == | + | [[Практика мультипарадигмального программирования, 05 лекция (от 26 марта)|Предыдущая лекция]] | [[Практика мультипарадигмального программирования, 07 лекция (от 09 апреля)|Следующая лекция]] |
- | + | ||
- | + | = Библиотечное моделирование отдельных возможностей = | |
- | + | ||
+ | Вот чего-то не хватает в языке, пишем мы на каком-то языке программирования. Если всего хватает, то о многостилевом программировании и речи и идёт, и мы других языков не знаем или не используем. Мультипарадигмальность возникает, когда хочется чего-то ещё, а в языке этого нет. Например, регулярные выражения. Вот в тикле они есть, а в Си нет. Можем мы сделать их в Си? Да, есть не одна библиотека для этого. Являются ли нерег выражения парадигмой? Есть минимум два источникам, в которых они так обозначаются. Влияют ли они на мышление? Да. | ||
+ | |||
+ | Вот берём мы функцию с pattern и regexp. Если мы дерём библиотеку с этой функцией, значит ли это, что у нас в языке появились регвыр? Да, но не в языке, а в системе программирования. Мы внесли парадигму за счёт библиотечного расширения. Но регекспы штука узкая. | ||
+ | |||
+ | Есть С++. Там есть темплейты и прочая. Есть ибиблиотеки, которые вносят новые парадигмы в С++. Во-первых, функция как объект. Во-вторых, лямбда-исчисление. | ||
+ | |||
+ | <div style="comment">ВМиК уникальный факультет — тут почти все знают нормальный алгоритм Маркова, но не знают, что такое лямбда-исчисление. Присутствующие люди правильно сделали, что пришли на спецкурс и теперь знают, что такое лямбда-исчисление.</div> | ||
+ | |||
+ | Но основная проблема в том, что невозможно сделать замыкание, ибо С++ не может работать с именами переменных. | ||
+ | |||
+ | Функтоид — класс, для которого перекрыт (). То есть это класс, который не функция, но объект этоо класса может выступать как функция. Можно сделать композицию (f ∘ g). | ||
+ | |||
+ | Какие есть библиотеки: | ||
+ | * boost::lambda — законченная документация, непонятная | ||
+ | * FAC++T! — непонятная документация | ||
+ | * FC++ — наиболее известное из них, и по ней есть законченная документация | ||
+ | |||
+ | Кроме того, первые две завязаны на STL, он торчит изо всех щелей, последняя же использует STL, но может и без него. | ||
+ | |||
+ | == FC++ == | ||
+ | FC++ явно создавали люди, которые очень любят haskell. Ибо есть хедер, который содержит инклюд всех хедеров, и он называется prelude (так называется стандартная библиотека haskell) | ||
+ | #include "prelude.h" | ||
+ | Но хаскелисты говорят, что это какой-то неправильный хаскель, хотя там многое от хаскеля реализовано. | ||
+ | |||
+ | Чем знаменит haskell: | ||
+ | * Чисто функциональный | ||
+ | * Язык со строгой типизацией | ||
+ | * Карринг | ||
+ | |||
+ | FC++ более-менее соостветствует идеологии хаскеля. Ещё один важный момент — хаскель язык ленивый, что позволяет работать с бесконечными списками. И если в FC++ использовать их структуры данных, то декларируется, что они ленивые, и что они тоже могут быть бесконечными | ||
+ | |||
+ | === Примеры === | ||
+ | List<int> lr = cons(x, cons(y, cons(t, NIL))); | ||
+ | Получается список, в качестве метки конца списка используется NIL. получается список из ццелых чисел. В хаскеле мы написали что-то вроде такого: | ||
+ | x::y::z::nil | ||
+ | Естественно, cons — темпелйт, и можно записать так: | ||
+ | cons<int>(x ...) | ||
+ | Вместо инта может быть любой тип, для которого определена операция сравнения (и, наверное, копирования) | ||
+ | |||
+ | Что можно сделать с этим списком: | ||
+ | * head | ||
+ | * tail | ||
+ | (аналоги car и cdr в лиспе) | ||
+ | |||
+ | Коль скоро есть функция, можно создать ещё одну функцию: | ||
+ | List<int> res = compose(tail, tail)(li); | ||
+ | Создаём новую функцию как суперпозицию двух функций tail и tail. Но tail ни разу не функция, а темплейт, и compose это макрос. В результат получаем выражение, и к нему применяем операцию вызову функции. Причём применяем их к функтоиду. | ||
+ | |||
+ | Можно работать с бесконечными структурами данных: вот есть же опять свтроенная функция: enumFrom(1); — функция, которая строит бесконечный список целых чисел, начиная с указанного. Что такое бесконечная структура — некоторые данные, а потом указания, как строить дальше. Результатом enumFrom является выражение, которое вполне можно присваивать: | ||
+ | List<int> i = enumFrom(1); | ||
+ | |||
+ | Что можно сделать: например, можно сделать | ||
+ | List<int> evens = filter(even, i); | ||
+ | Функция even — булева, проверяет на чётность. Это обыкновенная функция на С++: | ||
+ | bool even(int x) | ||
+ | { | ||
+ | return x%2 == 0; | ||
+ | } | ||
+ | А filter это уже темплейт, который умеет фильтровать: | ||
+ | filter<T> (bool(*)(T), T) {...} | ||
+ | |||
+ | Получаем список из всех существующих чётных чисел. Конечно, все не хранятся. Хранится первая и указания, как вычислить. Есть функция take (как в хаскеле) — взять n первых элементов. | ||
+ | List<int> e3 = take(3, evens); //взять первые три элемента списка | ||
+ | Тогда они и будут вычислены. | ||
+ | |||
+ | Есть функция map: | ||
+ | map(function, list) | ||
+ | Хаскель: | ||
+ | map: (a → b) → [a] → [b] | ||
+ | |||
+ | Люди пытались сделать то, что они хотели иметь из хаскеля. | ||
+ | |||
+ | Люди продемонстрировали факт: для темплейтов есть более интересные применения, чем для построения контейнерных классов. | ||
+ | |||
+ | Ложка дёгтя: сколько есть знакомых хаскелистов, все говорили при виде FC++, говорили, что писать на этом не будут. | ||
+ | |||
+ | Но всего хаскеля не передать, ибо в хаскеле есть ещё что-то: замыкание, монады. Как-то пытаются монады эмулировать, но это не то. | ||
+ | |||
+ | Монада — это какое-то хитрое преобразование из функции в функцию, причём без изменения профиля. Это вещь, которая работает с бесконечными списками, преобразует их. Зачем это нужно — в хаскеле в их виде оформлен ввод-вывод. | ||
+ | |||
+ | Чтобы понять монады, надо написать что-то мерьёзное. И тут начинаются проблемы. Мануал по хаскелю разделён на две части. Одна понятная, другая имеет заход из математики, но непонятно, как из этого что-то делать. | ||
+ | |||
+ | {{Практика мультипарадигмального программирования}} | ||
+ | {{Lection-stub}} |
Версия 17:59, 3 февраля 2008
Предыдущая лекция | Следующая лекция
Библиотечное моделирование отдельных возможностей
Вот чего-то не хватает в языке, пишем мы на каком-то языке программирования. Если всего хватает, то о многостилевом программировании и речи и идёт, и мы других языков не знаем или не используем. Мультипарадигмальность возникает, когда хочется чего-то ещё, а в языке этого нет. Например, регулярные выражения. Вот в тикле они есть, а в Си нет. Можем мы сделать их в Си? Да, есть не одна библиотека для этого. Являются ли нерег выражения парадигмой? Есть минимум два источникам, в которых они так обозначаются. Влияют ли они на мышление? Да.
Вот берём мы функцию с pattern и regexp. Если мы дерём библиотеку с этой функцией, значит ли это, что у нас в языке появились регвыр? Да, но не в языке, а в системе программирования. Мы внесли парадигму за счёт библиотечного расширения. Но регекспы штука узкая.
Есть С++. Там есть темплейты и прочая. Есть ибиблиотеки, которые вносят новые парадигмы в С++. Во-первых, функция как объект. Во-вторых, лямбда-исчисление.
Но основная проблема в том, что невозможно сделать замыкание, ибо С++ не может работать с именами переменных.
Функтоид — класс, для которого перекрыт (). То есть это класс, который не функция, но объект этоо класса может выступать как функция. Можно сделать композицию (f ∘ g).
Какие есть библиотеки:
- boost::lambda — законченная документация, непонятная
- FAC++T! — непонятная документация
- FC++ — наиболее известное из них, и по ней есть законченная документация
Кроме того, первые две завязаны на STL, он торчит изо всех щелей, последняя же использует STL, но может и без него.
FC++
FC++ явно создавали люди, которые очень любят haskell. Ибо есть хедер, который содержит инклюд всех хедеров, и он называется prelude (так называется стандартная библиотека haskell)
#include "prelude.h"
Но хаскелисты говорят, что это какой-то неправильный хаскель, хотя там многое от хаскеля реализовано.
Чем знаменит haskell:
- Чисто функциональный
- Язык со строгой типизацией
- Карринг
FC++ более-менее соостветствует идеологии хаскеля. Ещё один важный момент — хаскель язык ленивый, что позволяет работать с бесконечными списками. И если в FC++ использовать их структуры данных, то декларируется, что они ленивые, и что они тоже могут быть бесконечными
Примеры
List<int> lr = cons(x, cons(y, cons(t, NIL)));
Получается список, в качестве метки конца списка используется NIL. получается список из ццелых чисел. В хаскеле мы написали что-то вроде такого:
x::y::z::nil
Естественно, cons — темпелйт, и можно записать так:
cons<int>(x ...)
Вместо инта может быть любой тип, для которого определена операция сравнения (и, наверное, копирования)
Что можно сделать с этим списком:
- head
- tail
(аналоги car и cdr в лиспе)
Коль скоро есть функция, можно создать ещё одну функцию:
List<int> res = compose(tail, tail)(li);
Создаём новую функцию как суперпозицию двух функций tail и tail. Но tail ни разу не функция, а темплейт, и compose это макрос. В результат получаем выражение, и к нему применяем операцию вызову функции. Причём применяем их к функтоиду.
Можно работать с бесконечными структурами данных: вот есть же опять свтроенная функция: enumFrom(1); — функция, которая строит бесконечный список целых чисел, начиная с указанного. Что такое бесконечная структура — некоторые данные, а потом указания, как строить дальше. Результатом enumFrom является выражение, которое вполне можно присваивать:
List<int> i = enumFrom(1);
Что можно сделать: например, можно сделать
List<int> evens = filter(even, i);
Функция even — булева, проверяет на чётность. Это обыкновенная функция на С++:
bool even(int x) { return x%2 == 0; }
А filter это уже темплейт, который умеет фильтровать:
filter<T> (bool(*)(T), T) {...}
Получаем список из всех существующих чётных чисел. Конечно, все не хранятся. Хранится первая и указания, как вычислить. Есть функция take (как в хаскеле) — взять n первых элементов.
List<int> e3 = take(3, evens); //взять первые три элемента списка
Тогда они и будут вычислены.
Есть функция map:
map(function, list)
Хаскель:
map: (a → b) → [a] → [b]
Люди пытались сделать то, что они хотели иметь из хаскеля.
Люди продемонстрировали факт: для темплейтов есть более интересные применения, чем для построения контейнерных классов.
Ложка дёгтя: сколько есть знакомых хаскелистов, все говорили при виде FC++, говорили, что писать на этом не будут.
Но всего хаскеля не передать, ибо в хаскеле есть ещё что-то: замыкание, монады. Как-то пытаются монады эмулировать, но это не то.
Монада — это какое-то хитрое преобразование из функции в функцию, причём без изменения профиля. Это вещь, которая работает с бесконечными списками, преобразует их. Зачем это нужно — в хаскеле в их виде оформлен ввод-вывод.
Чтобы понять монады, надо написать что-то мерьёзное. И тут начинаются проблемы. Мануал по хаскелю разделён на две части. Одна понятная, другая имеет заход из математики, но непонятно, как из этого что-то делать.
Практика мультипарадигмального программирования
Календарь
пн | пн | пн | пн | пн | |
Февраль
| 12 | 19 | |||
Март
| 12 | 19 | 26 | ||
Апрель
| 02 | 09 | 16 |