SlideShare a Scribd company logo
This slide intentionally left
blank
There is nothing to read here
Обработка коллекций
наизнанку:
много функций,
один аргумент
Вадим Винник
Мотивация
● Парадигма функционального программирования проникает в C++:
○ operator(), функциональные объекты;
○ оптимизация хвостовой рекурсии;
○ λ-функции;
○ std::function, std::bind;
○ std::transform, std::accumulate - аналоги fmap и foldl/foldr;
○ template metaprogramming - позволяет моделировать классы типов;
● Не просто пополнение новыми инструментами, а парадигмальный сдвиг!
● Понятия и методы ФП остаются малознакомыми широкому сообществу.
● Цель доклада - продемонстрировать логику программирования,
тривиальную для ФП, но безумную с точки зрения традиций ООП.
● Показать, сколь проста её реализация на языке C++.
3
Немного программологии: интенсиональность
● Сущности в программировании выступают в трёх ролях:
○ просто сущности;
○ средства построения сущностей;
○ средства применения средств построения (в частности, средства управления
средствами построения).
● Эта не имманентная характеристика сущности, а внешняя.
● Определяется не сущностью самой по себе, а способом её
использования в конкретном контексте.
● Сущности в программировании - интенсиональны.
● Пример - функция:
○ чаще всего выступает средством построения объектов данных;
○ но в может и сама выступать объектом построения.
4
Немного программологии: композиционность
● Композиции строят более сложные программные сущности из
относительно простых.
○ Чаще всего имеют в виду композиции программ, но не менее важны композиции
данных, данных с программами и т.д.
● Обычно их относят к интенсиональному типу средств построения.
● Не менее важно рассматривать их и как средства применения и, в
частности, управления применением:
○ циклическая композиция управляет выполнением оператора-тела, который выступает
средством построения объектов данных;
○ объект, реализующий идиому RAII, управляет применением заданного действия.
● Композицию можно даже относить к интенсиональному типу 1
(гомоиконичность, LISP), но это далеко уводит от темы доклада.
5
Немного программологии: композиционность
● Всякое ответвление программирования характеризуется своим набором
композиций.
● Эти композиции:
○ выступают инструментами сочленения более сложных единиц из простых;
○ управляют применением частей в составе целого в процессе его работы.
● Именно композиции определяют суть и дух всякого программирования.
● Суть функционального программирования - не в чистоте функций и
отказе от разрушающего присваивания.
● Напротив: чистота функций - средство для поддержки композиций ФП.
6
Проникновение ФП в C++
● Импорт композиций ФП в среду языка C++ и сложившейся вокруг него
культуры программирования.
● Композиции, нашедшие широкое применение в ФП, для человека,
привычного к ООП, могут выглядеть странно и пугающе.
● Композиции ФП часто основаны на λ-исчислении, комбинаторах и теории
категорий (функторы, монады).
● Обобщённая цель доклада: показать, как выгод, которые в ФП
достигаются с помощью монад, можно добиться штатными средствами
языка С++, не упоминая монады в явном виде.
7
Вместо тысячи слов
fmap
x1 x2 xn
f
y1 y2 yn
fsum
f1 f2 fn
x
y
8
Пример
● Пусть дана совокупность функций каждая из которых может дать
искомый результат или неудачу.
● Например:
○ Попытаться извлечь параметр hostname из файла настроек в текущей директории;
○ Попытаться извлечь hostname из настроек в домашней директории пользователя;
○ Попытаться извлечь hostname из глобального файла настроек;
○ Взять hostname по умолчанию, прошитый в программе.
● Каждая, кроме последней, может окончиться неудачей: отсутствует
файл или в файле нет такого параметра.
● Чтобы получить правильный hostname, нужно пытаться применять эти
функции в том же порядке одну за другой до первой удачи.
9
● Если T - тип, то вместо std::optional<T> будем писать T? (возможно, T).
● Специальный объект “отсутствие” (std::nullopt) обозначим ⊥ (дно).
● Рассматриваем функции типа A1,…, Am → T?.
● Функция ⟘ (пустая) - для любых кортежей x правильного типа ⟘(x) = ⊥.
● Всюду определённые функции: t(x) ≠ ⊥ для любых x (Tot).
● Отношение порядка: f ≼ g (“f есть подфункция g”), если для любых x
из f(x) ≠ ⊥ следует g(x) = f(x).
● Функция ⟘ - наименьшая, а любая всюду определённая t -
максимальная (но не наибольшая) относительно порядка ≼.
● Одноточечная функция: p[a, y](x) = y, если x = a; иначе p[a, y](x) = ⊥.
● Совместимость: f ≈ g, если из f(x) ≠ g(x) следует f(x) = ⊥ или g(x) = ⊥.
Немного обозначений для краткости
10
Сумма функций: определение
● Пусть дана совокупность функций f1,…, fn типа A1,…, Am → T?.
● Их сумма h = ∑[f1,…, fn] = f1 ⊕…⊕ fn есть функция того же типа.
● Если fk(x) = ⊥ для всех k ∊ {1, …, n}, то h(x) = ⊥.
● Иначе h(x) = fk(x), где k ∊ {1, …, n} - наименьшее такое число, что
○ fk(x) ≠ ⊥,
○ fi(x) = ⊥ для всех i ∊ {1, …, k-1}.
● Неформально говоря: сумма функций по очереди пробует применять
все функции-слагаемые до первой удачи.
● Сумма функций терпит неудачу, если неудачу терпят все слагаемые.
11
Свойства суммы функций
● Некоммутативность: (p[a, y] ⊕ p[a, z])(a) = y, но (p[a, z] ⊕ p[a, y])(a) = z.
● Коммутативность при условии: если f ≈ g, то f ⊕ g = g ⊕ f.
● Ассоциативность: (f ⊕ g) ⊕ h = f ⊕ (g ⊕ h).
● Левый нуль: ⟘ ⊕ f = f.
● Правый нуль: f ⊕ ⟘ = f.
● Идемпотентность: f ⊕ g ⊕ g = f ⊕ g
○ в программировании работает только для чистых функций.
● Неподвижность максимума слева: если t ∊ Tot, то t ⊕ f = t.
● Сохранение максимума справа: если t ∊ Tot, то (f ⊕ t) ∊ Tot.
● Монотонность: f ≼ f ⊕ g.
● Поглощение меньшего большим: если f ≼ g, то f ⊕ g = g.
12
Рекуррентное определение суммы функций
● База (сумма из 0 слагаемых есть 0):
∑ [ ] = ⟘.
● Шаг: выразить сумму n слагаемого через сумму n-1 слагаемых (n > 0):
h = ∑ [f1,…, fn] - это такая функция, что для любого x:
● Если f1(x) = y ≠ ⊥, то h(x) = y.
● В противном случае h(x) = g(x), где
g = ∑ [f2,…, fn].
13
Реализация
https://github.com/vadimvinnik/xfunctional
14
template <typename R, typename ...Args>
struct default_constf {
using value_t = R;
static R make(Args...) { return {}; }
};
template <typename R, typename ...Args>
struct constf {
using value_t = R;
template <R Value>
static constexpr R make(Args...) { return Value; }
};
template <typename R, typename ...Args>
class constf_t {
R const value_;
public:
using value_t = R;
explicit constf_t(R const& value) : value_(value) {}
R operator()(Args const&...) const { return value_; }
};
Вспомогательные
функции-константы
создаются на этапе
выполнения
создаются на этапе
компиляции
15
template <typename R, typename ...Args>
class single_point_t {
R const value_;
std::tuple<Args...> const args_;
public:
using value_t = R;
using maybe_t = std::optional<R>;
single_point_t(R const& value, Args const&... args) :
value_(value),
args_(args...)
{}
maybe_t operator() (Args ...args) const {
return args_ == std::make_tuple(args...)
? maybe_t {value_}
: std::nullopt;
}
};
одноточечная функция
p[a, y]
16
template <typename R, typename ...Args>
struct fsum {
using maybe_t = std::optional<R>;
using funcptr_t = maybe_t(*)(Args...);
static funcptr_t make() {
return &(default_constf<maybe_t, Args...>::make);
}
template <typename F, typename ...Fs>
static auto make(F f, Fs ...fs) {
return [f, fs...](Args ...args) -> maybe_t {
maybe_t const r = f(args...);
return r.has_value()
? r
: make(fs...)(args...);
};
}
строит сумму функций на
этапе компиляции
прямая реализация
рекуррентного
определения
17
// continued:
// template <typename R, typename ...Args>
// struct fsum {
template <typename I>
static maybe_t exec(I from, I to, Args ...args) {
while (from != to) {
maybe_t const r = (*from)(args...);
if (r.has_value())
return r;
++from;
}
return std::nullopt;
}
};
вычисление значения
суммы функций на этапе
выполнения
18
using sum_t = xfunctional::fsum<number_t, std::string>;
auto string_to_number = sum_t::make(
decimal_to_number,
english_numeral_to_number,
roman_to_number);
assert(string_to_number("2019") == 2019);
assert(string_to_number("twelve") == 12);
assert(string_to_number("XIV") == 14);
assert(string_to_number("sieben") == std::nullopt);
пример использования
19
using sum_t = xfunctional::fsum<int>;
int count = 0;
auto chain = sum_t::make(
[&count]() { ++count; return std::nullopt; },
[&count]() { ++count; return std::nullopt; },
[&count]() { ++count; return std::nullopt; },
[&count]() { ++count; return 7; },
[&count]() { ++count; return std::nullopt; },
[&count]() { ++count; return 3; }
);
auto const value = chain();
assert(value == 7);
assert(count == 4);
демонстрация хода
вычислений
20
using func_t = xfunctional::single_point_t<std::string, int>;
using sum_t = xfunctional::fsum<std::string, int>;
auto int_to_string = sum_t::make(
func_t { "zero" , 0 },
func_t { "one" , 1 },
func_t { "two" , 2 },
func_t { "zero2", 0 }, // !
func_t { "three", 3 }
);
assert(int_to_string(0) == "zero");
assert(int_to_string(2) == "two");
assert(int_to_string(3) == "three");
assert(int_to_string(4) == std::nullopt);
окончание по первому
успеху
21
Итоги и дальнейшие вопросы
● Связь с шаблонами “Chain of Responsibility” и “Composite”.
● Этот код работает на production.
● Для ряда практических задач стиль ФП - наиболее адекватное средство
выражения их естественной логики.
● Если функция f имеет побочные эффекты, то бесконечная сумма
∑ [f, f, …] представляет собой… что?
● Предел бесконечной монотонной последовательности и заодно
неподвижная точка операции ⊕f - это цикл!
● А теперь вывернем наизнанку! Применять следующую функцию к
результату предыдущей до первой неудачи.
● Получим монаду Maybe - но это уже совсем другая история.
22
} // the talk

More Related Content

What's hot

Алгоритмы и языки программирования
Алгоритмы и языки программированияАлгоритмы и языки программирования
Алгоритмы и языки программирования
Theoretical mechanics department
 
Лекция 2. Коллективные операции в MPI. Параллельные алгоритмы случайного блуж...
Лекция 2. Коллективные операции в MPI. Параллельные алгоритмы случайного блуж...Лекция 2. Коллективные операции в MPI. Параллельные алгоритмы случайного блуж...
Лекция 2. Коллективные операции в MPI. Параллельные алгоритмы случайного блуж...
Alexey Paznikov
 
Математическое обоснование S.O.L.I.D принципов
Математическое обоснование S.O.L.I.D принциповМатематическое обоснование S.O.L.I.D принципов
Математическое обоснование S.O.L.I.D принципов
etyumentcev
 
Запись вспомогательный алгоритмов на языка Паскаль
Запись вспомогательный алгоритмов на языка ПаскальЗапись вспомогательный алгоритмов на языка Паскаль
Запись вспомогательный алгоритмов на языка Паскаль
Andrey Dolinin
 
Конкурентные ассоциативные контейнеры
Конкурентные ассоциативные контейнерыКонкурентные ассоциативные контейнеры
Конкурентные ассоциативные контейнеры
corehard_by
 
2017 01-27-titanic
2017 01-27-titanic2017 01-27-titanic
2017 01-27-titanic
Iurii Zhidkov
 
Лекция 4. Производные типы данных в стандарте MPI
Лекция 4. Производные типы данных в стандарте MPIЛекция 4. Производные типы данных в стандарте MPI
Лекция 4. Производные типы данных в стандарте MPI
Alexey Paznikov
 
19 pascal urok_3
19 pascal urok_319 pascal urok_3
19 pascal urok_3Ann Eres
 
Лекция 8: Многопоточное программирование: Intel Threading Building Blocks
Лекция 8: Многопоточное программирование: Intel Threading Building BlocksЛекция 8: Многопоточное программирование: Intel Threading Building Blocks
Лекция 8: Многопоточное программирование: Intel Threading Building BlocksMikhail Kurnosov
 
Лекция 6. Параллельная сортировка. Алгоритмы комбинаторного поиска. Параллель...
Лекция 6. Параллельная сортировка. Алгоритмы комбинаторного поиска. Параллель...Лекция 6. Параллельная сортировка. Алгоритмы комбинаторного поиска. Параллель...
Лекция 6. Параллельная сортировка. Алгоритмы комбинаторного поиска. Параллель...
Alexey Paznikov
 
Языки программирования
Языки программированияЯзыки программирования
Языки программированияpaulsmirnov
 
Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!
Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!
Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!
Yandex
 
Лекция 3. Виртуальные топологии в MPI. Параллельные алгоритмы в стандарте MPI...
Лекция 3. Виртуальные топологии в MPI. Параллельные алгоритмы в стандарте MPI...Лекция 3. Виртуальные топологии в MPI. Параллельные алгоритмы в стандарте MPI...
Лекция 3. Виртуальные топологии в MPI. Параллельные алгоритмы в стандарте MPI...
Alexey Paznikov
 
Python: ввод и вывод
Python: ввод и выводPython: ввод и вывод
Python: ввод и вывод
Theoretical mechanics department
 
Метапрограммирование в C++11/14 и C++17. Новые инструменты - новые проблемы.
Метапрограммирование в C++11/14 и C++17. Новые инструменты - новые проблемы.Метапрограммирование в C++11/14 и C++17. Новые инструменты - новые проблемы.
Метапрограммирование в C++11/14 и C++17. Новые инструменты - новые проблемы.
Roman Orlov
 
паскаль
паскальпаскаль
паскаль
Гимназия
 

What's hot (20)

Алгоритмы и языки программирования
Алгоритмы и языки программированияАлгоритмы и языки программирования
Алгоритмы и языки программирования
 
82
8282
82
 
Лекция 2. Коллективные операции в MPI. Параллельные алгоритмы случайного блуж...
Лекция 2. Коллективные операции в MPI. Параллельные алгоритмы случайного блуж...Лекция 2. Коллективные операции в MPI. Параллельные алгоритмы случайного блуж...
Лекция 2. Коллективные операции в MPI. Параллельные алгоритмы случайного блуж...
 
87
8787
87
 
Математическое обоснование S.O.L.I.D принципов
Математическое обоснование S.O.L.I.D принциповМатематическое обоснование S.O.L.I.D принципов
Математическое обоснование S.O.L.I.D принципов
 
структура программы
структура программыструктура программы
структура программы
 
Запись вспомогательный алгоритмов на языка Паскаль
Запись вспомогательный алгоритмов на языка ПаскальЗапись вспомогательный алгоритмов на языка Паскаль
Запись вспомогательный алгоритмов на языка Паскаль
 
Конкурентные ассоциативные контейнеры
Конкурентные ассоциативные контейнерыКонкурентные ассоциативные контейнеры
Конкурентные ассоциативные контейнеры
 
2017 01-27-titanic
2017 01-27-titanic2017 01-27-titanic
2017 01-27-titanic
 
Лекция 4. Производные типы данных в стандарте MPI
Лекция 4. Производные типы данных в стандарте MPIЛекция 4. Производные типы данных в стандарте MPI
Лекция 4. Производные типы данных в стандарте MPI
 
лекция 16
лекция 16лекция 16
лекция 16
 
19 pascal urok_3
19 pascal urok_319 pascal urok_3
19 pascal urok_3
 
Лекция 8: Многопоточное программирование: Intel Threading Building Blocks
Лекция 8: Многопоточное программирование: Intel Threading Building BlocksЛекция 8: Многопоточное программирование: Intel Threading Building Blocks
Лекция 8: Многопоточное программирование: Intel Threading Building Blocks
 
Лекция 6. Параллельная сортировка. Алгоритмы комбинаторного поиска. Параллель...
Лекция 6. Параллельная сортировка. Алгоритмы комбинаторного поиска. Параллель...Лекция 6. Параллельная сортировка. Алгоритмы комбинаторного поиска. Параллель...
Лекция 6. Параллельная сортировка. Алгоритмы комбинаторного поиска. Параллель...
 
Языки программирования
Языки программированияЯзыки программирования
Языки программирования
 
Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!
Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!
Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!
 
Лекция 3. Виртуальные топологии в MPI. Параллельные алгоритмы в стандарте MPI...
Лекция 3. Виртуальные топологии в MPI. Параллельные алгоритмы в стандарте MPI...Лекция 3. Виртуальные топологии в MPI. Параллельные алгоритмы в стандарте MPI...
Лекция 3. Виртуальные топологии в MPI. Параллельные алгоритмы в стандарте MPI...
 
Python: ввод и вывод
Python: ввод и выводPython: ввод и вывод
Python: ввод и вывод
 
Метапрограммирование в C++11/14 и C++17. Новые инструменты - новые проблемы.
Метапрограммирование в C++11/14 и C++17. Новые инструменты - новые проблемы.Метапрограммирование в C++11/14 и C++17. Новые инструменты - новые проблемы.
Метапрограммирование в C++11/14 и C++17. Новые инструменты - новые проблемы.
 
паскаль
паскальпаскаль
паскаль
 

Similar to Обработка коллекций наизнанку: как применить много функций к одному аргументу. Вадим Винник. Corehard Spring 2019

Обработка коллекций. Единая суть и множество проявлений
Обработка коллекций. Единая суть и множество проявленийОбработка коллекций. Единая суть и множество проявлений
Обработка коллекций. Единая суть и множество проявлений
corehard_by
 
Лекция №2. Алгоритмические проблемы. Стандартные схемы программ. Предмет "Тео...
Лекция №2. Алгоритмические проблемы. Стандартные схемы программ. Предмет "Тео...Лекция №2. Алгоритмические проблемы. Стандартные схемы программ. Предмет "Тео...
Лекция №2. Алгоритмические проблемы. Стандартные схемы программ. Предмет "Тео...Nikolay Grebenshikov
 
Back to the future: Функциональное программирование вчера и сегодня
Back to the future: Функциональное программирование вчера и сегодняBack to the future: Функциональное программирование вчера и сегодня
Back to the future: Функциональное программирование вчера и сегодня
Alexander Granin
 
Николай Паламарчук "Functional Programming basics for PHP developers"
Николай Паламарчук "Functional Programming basics for PHP developers"Николай Паламарчук "Functional Programming basics for PHP developers"
Николай Паламарчук "Functional Programming basics for PHP developers"
Fwdays
 
Лекция о языке программирования Haskell
Лекция о языке программирования HaskellЛекция о языке программирования Haskell
Лекция о языке программирования Haskell
husniyarova
 
Pyton – пробуем функциональный стиль
Pyton – пробуем функциональный стильPyton – пробуем функциональный стиль
Pyton – пробуем функциональный стиль
Python Meetup
 
Tech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVMTech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU
 
Как приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVMКак приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVM
Tech Talks @NSU
 
О-символика
О-символикаО-символика
О-символика
DEVTYPE
 
Tech Talks @NSU: Теоретические основы программирования: проекции Футамуры-Тур...
Tech Talks @NSU: Теоретические основы программирования: проекции Футамуры-Тур...Tech Talks @NSU: Теоретические основы программирования: проекции Футамуры-Тур...
Tech Talks @NSU: Теоретические основы программирования: проекции Футамуры-Тур...
Tech Talks @NSU
 
Подпрограммы
ПодпрограммыПодпрограммы
Подпрограммы
Colegiul de Industrie Usoara
 
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
Yandex
 
Discovering Lambdas in Java 8
Discovering Lambdas in Java 8Discovering Lambdas in Java 8
Discovering Lambdas in Java 8
Stfalcon Meetups
 
KL10TCH: Paver.js + T.js
KL10TCH: Paver.js + T.jsKL10TCH: Paver.js + T.js
KL10TCH: Paver.js + T.js
Денис Ольшин
 
Функциональное программирование с использованием библиотеки fp-ts | Odessa Fr...
Функциональное программирование с использованием библиотеки fp-ts | Odessa Fr...Функциональное программирование с использованием библиотеки fp-ts | Odessa Fr...
Функциональное программирование с использованием библиотеки fp-ts | Odessa Fr...
OdessaFrontend
 
ПВТ - осень 2014 - лекция 1 - Введение в параллельные вычисления
ПВТ - осень 2014 - лекция 1 - Введение в параллельные вычисленияПВТ - осень 2014 - лекция 1 - Введение в параллельные вычисления
ПВТ - осень 2014 - лекция 1 - Введение в параллельные вычисления
Alexey Paznikov
 
Haskell Type System with Dzmitry Ivashnev.
Haskell Type System with Dzmitry Ivashnev.Haskell Type System with Dzmitry Ivashnev.
Haskell Type System with Dzmitry Ivashnev.
Sergey Tihon
 
Характерные черты функциональных языков программирования
Характерные черты функциональных языков программированияХарактерные черты функциональных языков программирования
Характерные черты функциональных языков программированияAlex.Kolonitsky
 
Fields of Experts (доклад)
Fields of Experts (доклад)Fields of Experts (доклад)
Fields of Experts (доклад)
romovpa
 
Алгоритмы и структуры данных осень 2013 лекция 1
Алгоритмы и структуры данных осень 2013 лекция 1Алгоритмы и структуры данных осень 2013 лекция 1
Алгоритмы и структуры данных осень 2013 лекция 1Technopark
 

Similar to Обработка коллекций наизнанку: как применить много функций к одному аргументу. Вадим Винник. Corehard Spring 2019 (20)

Обработка коллекций. Единая суть и множество проявлений
Обработка коллекций. Единая суть и множество проявленийОбработка коллекций. Единая суть и множество проявлений
Обработка коллекций. Единая суть и множество проявлений
 
Лекция №2. Алгоритмические проблемы. Стандартные схемы программ. Предмет "Тео...
Лекция №2. Алгоритмические проблемы. Стандартные схемы программ. Предмет "Тео...Лекция №2. Алгоритмические проблемы. Стандартные схемы программ. Предмет "Тео...
Лекция №2. Алгоритмические проблемы. Стандартные схемы программ. Предмет "Тео...
 
Back to the future: Функциональное программирование вчера и сегодня
Back to the future: Функциональное программирование вчера и сегодняBack to the future: Функциональное программирование вчера и сегодня
Back to the future: Функциональное программирование вчера и сегодня
 
Николай Паламарчук "Functional Programming basics for PHP developers"
Николай Паламарчук "Functional Programming basics for PHP developers"Николай Паламарчук "Functional Programming basics for PHP developers"
Николай Паламарчук "Functional Programming basics for PHP developers"
 
Лекция о языке программирования Haskell
Лекция о языке программирования HaskellЛекция о языке программирования Haskell
Лекция о языке программирования Haskell
 
Pyton – пробуем функциональный стиль
Pyton – пробуем функциональный стильPyton – пробуем функциональный стиль
Pyton – пробуем функциональный стиль
 
Tech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVMTech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVM
 
Как приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVMКак приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVM
 
О-символика
О-символикаО-символика
О-символика
 
Tech Talks @NSU: Теоретические основы программирования: проекции Футамуры-Тур...
Tech Talks @NSU: Теоретические основы программирования: проекции Футамуры-Тур...Tech Talks @NSU: Теоретические основы программирования: проекции Футамуры-Тур...
Tech Talks @NSU: Теоретические основы программирования: проекции Футамуры-Тур...
 
Подпрограммы
ПодпрограммыПодпрограммы
Подпрограммы
 
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
 
Discovering Lambdas in Java 8
Discovering Lambdas in Java 8Discovering Lambdas in Java 8
Discovering Lambdas in Java 8
 
KL10TCH: Paver.js + T.js
KL10TCH: Paver.js + T.jsKL10TCH: Paver.js + T.js
KL10TCH: Paver.js + T.js
 
Функциональное программирование с использованием библиотеки fp-ts | Odessa Fr...
Функциональное программирование с использованием библиотеки fp-ts | Odessa Fr...Функциональное программирование с использованием библиотеки fp-ts | Odessa Fr...
Функциональное программирование с использованием библиотеки fp-ts | Odessa Fr...
 
ПВТ - осень 2014 - лекция 1 - Введение в параллельные вычисления
ПВТ - осень 2014 - лекция 1 - Введение в параллельные вычисленияПВТ - осень 2014 - лекция 1 - Введение в параллельные вычисления
ПВТ - осень 2014 - лекция 1 - Введение в параллельные вычисления
 
Haskell Type System with Dzmitry Ivashnev.
Haskell Type System with Dzmitry Ivashnev.Haskell Type System with Dzmitry Ivashnev.
Haskell Type System with Dzmitry Ivashnev.
 
Характерные черты функциональных языков программирования
Характерные черты функциональных языков программированияХарактерные черты функциональных языков программирования
Характерные черты функциональных языков программирования
 
Fields of Experts (доклад)
Fields of Experts (доклад)Fields of Experts (доклад)
Fields of Experts (доклад)
 
Алгоритмы и структуры данных осень 2013 лекция 1
Алгоритмы и структуры данных осень 2013 лекция 1Алгоритмы и структуры данных осень 2013 лекция 1
Алгоритмы и структуры данных осень 2013 лекция 1
 

More from corehard_by

C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
corehard_by
 
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
corehard_by
 
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений ОхотниковC++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
corehard_by
 
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр ТитовC++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
corehard_by
 
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
corehard_by
 
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья ШишковC++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
corehard_by
 
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
corehard_by
 
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
corehard_by
 
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
corehard_by
 
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
corehard_by
 
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
corehard_by
 
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел ФилоновC++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
corehard_by
 
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan ČukićC++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
corehard_by
 
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia KazakovaC++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
corehard_by
 
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон ПолухинC++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
corehard_by
 
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
corehard_by
 
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
corehard_by
 
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019
corehard_by
 
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019
corehard_by
 
Статичный SQL в С++14. Евгений Захаров ➠ CoreHard Autumn 2019
Статичный SQL в С++14. Евгений Захаров ➠  CoreHard Autumn 2019Статичный SQL в С++14. Евгений Захаров ➠  CoreHard Autumn 2019
Статичный SQL в С++14. Евгений Захаров ➠ CoreHard Autumn 2019
corehard_by
 

More from corehard_by (20)

C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
 
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
 
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений ОхотниковC++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
 
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр ТитовC++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
 
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
 
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья ШишковC++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
 
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
 
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
 
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
 
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
 
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
 
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел ФилоновC++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
 
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan ČukićC++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
 
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia KazakovaC++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
 
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон ПолухинC++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
 
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
 
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
 
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019
 
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019
 
Статичный SQL в С++14. Евгений Захаров ➠ CoreHard Autumn 2019
Статичный SQL в С++14. Евгений Захаров ➠  CoreHard Autumn 2019Статичный SQL в С++14. Евгений Захаров ➠  CoreHard Autumn 2019
Статичный SQL в С++14. Евгений Захаров ➠ CoreHard Autumn 2019
 

Обработка коллекций наизнанку: как применить много функций к одному аргументу. Вадим Винник. Corehard Spring 2019

  • 1. This slide intentionally left blank There is nothing to read here
  • 3. Мотивация ● Парадигма функционального программирования проникает в C++: ○ operator(), функциональные объекты; ○ оптимизация хвостовой рекурсии; ○ λ-функции; ○ std::function, std::bind; ○ std::transform, std::accumulate - аналоги fmap и foldl/foldr; ○ template metaprogramming - позволяет моделировать классы типов; ● Не просто пополнение новыми инструментами, а парадигмальный сдвиг! ● Понятия и методы ФП остаются малознакомыми широкому сообществу. ● Цель доклада - продемонстрировать логику программирования, тривиальную для ФП, но безумную с точки зрения традиций ООП. ● Показать, сколь проста её реализация на языке C++. 3
  • 4. Немного программологии: интенсиональность ● Сущности в программировании выступают в трёх ролях: ○ просто сущности; ○ средства построения сущностей; ○ средства применения средств построения (в частности, средства управления средствами построения). ● Эта не имманентная характеристика сущности, а внешняя. ● Определяется не сущностью самой по себе, а способом её использования в конкретном контексте. ● Сущности в программировании - интенсиональны. ● Пример - функция: ○ чаще всего выступает средством построения объектов данных; ○ но в может и сама выступать объектом построения. 4
  • 5. Немного программологии: композиционность ● Композиции строят более сложные программные сущности из относительно простых. ○ Чаще всего имеют в виду композиции программ, но не менее важны композиции данных, данных с программами и т.д. ● Обычно их относят к интенсиональному типу средств построения. ● Не менее важно рассматривать их и как средства применения и, в частности, управления применением: ○ циклическая композиция управляет выполнением оператора-тела, который выступает средством построения объектов данных; ○ объект, реализующий идиому RAII, управляет применением заданного действия. ● Композицию можно даже относить к интенсиональному типу 1 (гомоиконичность, LISP), но это далеко уводит от темы доклада. 5
  • 6. Немного программологии: композиционность ● Всякое ответвление программирования характеризуется своим набором композиций. ● Эти композиции: ○ выступают инструментами сочленения более сложных единиц из простых; ○ управляют применением частей в составе целого в процессе его работы. ● Именно композиции определяют суть и дух всякого программирования. ● Суть функционального программирования - не в чистоте функций и отказе от разрушающего присваивания. ● Напротив: чистота функций - средство для поддержки композиций ФП. 6
  • 7. Проникновение ФП в C++ ● Импорт композиций ФП в среду языка C++ и сложившейся вокруг него культуры программирования. ● Композиции, нашедшие широкое применение в ФП, для человека, привычного к ООП, могут выглядеть странно и пугающе. ● Композиции ФП часто основаны на λ-исчислении, комбинаторах и теории категорий (функторы, монады). ● Обобщённая цель доклада: показать, как выгод, которые в ФП достигаются с помощью монад, можно добиться штатными средствами языка С++, не упоминая монады в явном виде. 7
  • 8. Вместо тысячи слов fmap x1 x2 xn f y1 y2 yn fsum f1 f2 fn x y 8
  • 9. Пример ● Пусть дана совокупность функций каждая из которых может дать искомый результат или неудачу. ● Например: ○ Попытаться извлечь параметр hostname из файла настроек в текущей директории; ○ Попытаться извлечь hostname из настроек в домашней директории пользователя; ○ Попытаться извлечь hostname из глобального файла настроек; ○ Взять hostname по умолчанию, прошитый в программе. ● Каждая, кроме последней, может окончиться неудачей: отсутствует файл или в файле нет такого параметра. ● Чтобы получить правильный hostname, нужно пытаться применять эти функции в том же порядке одну за другой до первой удачи. 9
  • 10. ● Если T - тип, то вместо std::optional<T> будем писать T? (возможно, T). ● Специальный объект “отсутствие” (std::nullopt) обозначим ⊥ (дно). ● Рассматриваем функции типа A1,…, Am → T?. ● Функция ⟘ (пустая) - для любых кортежей x правильного типа ⟘(x) = ⊥. ● Всюду определённые функции: t(x) ≠ ⊥ для любых x (Tot). ● Отношение порядка: f ≼ g (“f есть подфункция g”), если для любых x из f(x) ≠ ⊥ следует g(x) = f(x). ● Функция ⟘ - наименьшая, а любая всюду определённая t - максимальная (но не наибольшая) относительно порядка ≼. ● Одноточечная функция: p[a, y](x) = y, если x = a; иначе p[a, y](x) = ⊥. ● Совместимость: f ≈ g, если из f(x) ≠ g(x) следует f(x) = ⊥ или g(x) = ⊥. Немного обозначений для краткости 10
  • 11. Сумма функций: определение ● Пусть дана совокупность функций f1,…, fn типа A1,…, Am → T?. ● Их сумма h = ∑[f1,…, fn] = f1 ⊕…⊕ fn есть функция того же типа. ● Если fk(x) = ⊥ для всех k ∊ {1, …, n}, то h(x) = ⊥. ● Иначе h(x) = fk(x), где k ∊ {1, …, n} - наименьшее такое число, что ○ fk(x) ≠ ⊥, ○ fi(x) = ⊥ для всех i ∊ {1, …, k-1}. ● Неформально говоря: сумма функций по очереди пробует применять все функции-слагаемые до первой удачи. ● Сумма функций терпит неудачу, если неудачу терпят все слагаемые. 11
  • 12. Свойства суммы функций ● Некоммутативность: (p[a, y] ⊕ p[a, z])(a) = y, но (p[a, z] ⊕ p[a, y])(a) = z. ● Коммутативность при условии: если f ≈ g, то f ⊕ g = g ⊕ f. ● Ассоциативность: (f ⊕ g) ⊕ h = f ⊕ (g ⊕ h). ● Левый нуль: ⟘ ⊕ f = f. ● Правый нуль: f ⊕ ⟘ = f. ● Идемпотентность: f ⊕ g ⊕ g = f ⊕ g ○ в программировании работает только для чистых функций. ● Неподвижность максимума слева: если t ∊ Tot, то t ⊕ f = t. ● Сохранение максимума справа: если t ∊ Tot, то (f ⊕ t) ∊ Tot. ● Монотонность: f ≼ f ⊕ g. ● Поглощение меньшего большим: если f ≼ g, то f ⊕ g = g. 12
  • 13. Рекуррентное определение суммы функций ● База (сумма из 0 слагаемых есть 0): ∑ [ ] = ⟘. ● Шаг: выразить сумму n слагаемого через сумму n-1 слагаемых (n > 0): h = ∑ [f1,…, fn] - это такая функция, что для любого x: ● Если f1(x) = y ≠ ⊥, то h(x) = y. ● В противном случае h(x) = g(x), где g = ∑ [f2,…, fn]. 13
  • 15. template <typename R, typename ...Args> struct default_constf { using value_t = R; static R make(Args...) { return {}; } }; template <typename R, typename ...Args> struct constf { using value_t = R; template <R Value> static constexpr R make(Args...) { return Value; } }; template <typename R, typename ...Args> class constf_t { R const value_; public: using value_t = R; explicit constf_t(R const& value) : value_(value) {} R operator()(Args const&...) const { return value_; } }; Вспомогательные функции-константы создаются на этапе выполнения создаются на этапе компиляции 15
  • 16. template <typename R, typename ...Args> class single_point_t { R const value_; std::tuple<Args...> const args_; public: using value_t = R; using maybe_t = std::optional<R>; single_point_t(R const& value, Args const&... args) : value_(value), args_(args...) {} maybe_t operator() (Args ...args) const { return args_ == std::make_tuple(args...) ? maybe_t {value_} : std::nullopt; } }; одноточечная функция p[a, y] 16
  • 17. template <typename R, typename ...Args> struct fsum { using maybe_t = std::optional<R>; using funcptr_t = maybe_t(*)(Args...); static funcptr_t make() { return &(default_constf<maybe_t, Args...>::make); } template <typename F, typename ...Fs> static auto make(F f, Fs ...fs) { return [f, fs...](Args ...args) -> maybe_t { maybe_t const r = f(args...); return r.has_value() ? r : make(fs...)(args...); }; } строит сумму функций на этапе компиляции прямая реализация рекуррентного определения 17
  • 18. // continued: // template <typename R, typename ...Args> // struct fsum { template <typename I> static maybe_t exec(I from, I to, Args ...args) { while (from != to) { maybe_t const r = (*from)(args...); if (r.has_value()) return r; ++from; } return std::nullopt; } }; вычисление значения суммы функций на этапе выполнения 18
  • 19. using sum_t = xfunctional::fsum<number_t, std::string>; auto string_to_number = sum_t::make( decimal_to_number, english_numeral_to_number, roman_to_number); assert(string_to_number("2019") == 2019); assert(string_to_number("twelve") == 12); assert(string_to_number("XIV") == 14); assert(string_to_number("sieben") == std::nullopt); пример использования 19
  • 20. using sum_t = xfunctional::fsum<int>; int count = 0; auto chain = sum_t::make( [&count]() { ++count; return std::nullopt; }, [&count]() { ++count; return std::nullopt; }, [&count]() { ++count; return std::nullopt; }, [&count]() { ++count; return 7; }, [&count]() { ++count; return std::nullopt; }, [&count]() { ++count; return 3; } ); auto const value = chain(); assert(value == 7); assert(count == 4); демонстрация хода вычислений 20
  • 21. using func_t = xfunctional::single_point_t<std::string, int>; using sum_t = xfunctional::fsum<std::string, int>; auto int_to_string = sum_t::make( func_t { "zero" , 0 }, func_t { "one" , 1 }, func_t { "two" , 2 }, func_t { "zero2", 0 }, // ! func_t { "three", 3 } ); assert(int_to_string(0) == "zero"); assert(int_to_string(2) == "two"); assert(int_to_string(3) == "three"); assert(int_to_string(4) == std::nullopt); окончание по первому успеху 21
  • 22. Итоги и дальнейшие вопросы ● Связь с шаблонами “Chain of Responsibility” и “Composite”. ● Этот код работает на production. ● Для ряда практических задач стиль ФП - наиболее адекватное средство выражения их естественной логики. ● Если функция f имеет побочные эффекты, то бесконечная сумма ∑ [f, f, …] представляет собой… что? ● Предел бесконечной монотонной последовательности и заодно неподвижная точка операции ⊕f - это цикл! ● А теперь вывернем наизнанку! Применять следующую функцию к результату предыдущей до первой неудачи. ● Получим монаду Maybe - но это уже совсем другая история. 22
  • 23. } // the talk