SlideShare a Scribd company logo
Async. programming with ranges
Corehard Autumn 2018
dr Ivan Čukić
ivan@cukic.co core-dev @ KDE
http://cukic.co www.kde.org
Iterators Ranges Push Pipes Going postal
About me
KDE development
Talks and teaching
Author of ”Functional Programming in C++” (Manning)
Functional programming enthusiast, but not a purist
2
Iterators Ranges Push Pipes Going postal
Disclaimer
Make your code readable. Pretend the next person
who looks at your code is a psychopath and they
know where you live.
Philip Wadler
3
ITERATORS
Iterators Ranges Push Pipes Going postal
Iterators
At the core of generic programming in STL.
5
Iterators Ranges Push Pipes Going postal
Iterators
std::vector<std::string> identifiers;
std::copy_if(
std::cbegin(tokens),
std::cend(tokens),
std::back_inserter(identifiers),
is_valid_identifier);
6
Iterators Ranges Push Pipes Going postal
Iterators
std::vector<std::string> identifiers;
std::copy_if(
std::istream_iterator<std::string>(std::cin),
std::istream_iterator<std::string>(),
std::back_inserter(identifiers),
is_valid_identifier);
7
Iterators Ranges Push Pipes Going postal
Example
8
Iterators Ranges Push Pipes Going postal
Example
8
Iterators Ranges Push Pipes Going postal
Example
8
Iterators Ranges Push Pipes Going postal
Example
8
Iterators Ranges Push Pipes Going postal
Example
template <typename It, typename Pred>
std::pair<It, It> move_selected(
It begin, It end, It destination,
Pred is_selected)
{
return {
std::stable_partition(begin, destination,
std::not_fn(is_selected)),
std::stable_partition(destination, end,
is_selected)
};
}
9
RANGES
Iterators Ranges Push Pipes Going postal
Problems with iterators
Example: Sum of squares
This should be separable into two subtasks:
squaring the values
summation
11
Iterators Ranges Push Pipes Going postal
Problems with iterators
std::vector<int> xs { ⋯ };
std::vector<int> squared(xs.size());
std::transform(std::cbegin(xs), std::cend(xs),
std::begin(squared),
[] (int x) { return x * x; });
return std::accumulate(std::cbegin(squared),
std::cend(squared),
0);
12
Iterators Ranges Push Pipes Going postal
Problems with iterators
std::vector<int> xs { ⋯ };
return std::transform_reduce(par,
std::cbegin(xs), std::cend(xs),
std::cbegin(xs),
0);
13
Iterators Ranges Push Pipes Going postal
Proxy iterators
template <typename Trafo, typename It>
class transform_proxy_iterator {
public:
auto operator*() const
{
return transformation(
*real_iterator);
}
private:
Trafo transformation;
It real_iterator;
};
14
Iterators Ranges Push Pipes Going postal
Ranges
[ iterator, sentinel )
Iterator:
*i – access the value
++i – move to the next element
Sentinel:
i == s – has iterator reached the end?
15
Iterators Ranges Push Pipes Going postal
Ranges
std::vector<int> xs { ⋯ };
accumulate(
transform(
xs,
[] (int x) { ⋯ }),
0);
16
Iterators Ranges Push Pipes Going postal
Ranges
std::vector<int> xs { ⋯ };
accumulate(
transform(
filter(
xs,
[] (int x) { ⋯ }),
[] (int x) { ⋯ }),
0);
17
Iterators Ranges Push Pipes Going postal
Ranges
std::vector<int> xs { ⋯ };
accumulate(
xs | filter([] (int x) { ⋯ })
| transform([] (int x) { ⋯ }),
0);
18
Iterators Ranges Push Pipes Going postal
Word frequency
1986: Donald Knuth was asked to implement a program for
the ”Programming pearls” column in the Communications
of ACM journal.
The task: Read a file of text, determine the n most
frequently used words, and print out a sorted list of those
words along with their frequencies.
19
Iterators Ranges Push Pipes Going postal
Word frequency
1986: Donald Knuth was asked to implement a program for
the ”Programming pearls” column in the Communications
of ACM journal.
The task: Read a file of text, determine the n most
frequently used words, and print out a sorted list of those
words along with their frequencies.
His solution written in Pascal was 10 pages long.
19
Iterators Ranges Push Pipes Going postal
Word frequency
Response by Doug McIlroy was a 6-line shell script that did
the same:
tr −cs A−Za−z ' n ' |
tr A−Z a−z |
sort |
uniq −c |
sort −rn |
sed ${1}q
20
Iterators Ranges Push Pipes Going postal
Functional thinking – data transformation
21
Iterators Ranges Push Pipes Going postal
With ranges
const auto words =
// Range of words
istream_range<std::string>(std::cin)
// Cleaning the input
| view::transform(string_to_lower)
| view::transform(string_only_alnum)
| view::remove_if(&std::string::empty)
// Sort the result
| to_vector | action::sort;
22
Iterators Ranges Push Pipes Going postal
With ranges
const auto results =
words
// Group repeated words
| view::group_by(std::equal_to<>())
// Count how many repetitions we have
| view::transform([] (const auto &group) {
return std::make_pair(
distance(begin(group), end(group),
*begin(group));
})
// Sort by frequency
| to_vector | action::sort;
23
Iterators Ranges Push Pipes Going postal
With ranges
for (auto value:
results | view::reverse // descending
| view::take(n) // we need first n results
) {
std::cout << value.first << ” ”
<< value.second << std::endl;
}
24
PUSH
Iterators Ranges Push Pipes Going postal
Ranges
[ iterator, sentinel )
Iterator:
*i – access the value
++i – move to the next element
Sentinel:
i == s – has iterator reached the end
26
Iterators Ranges Push Pipes Going postal
Ranges
[ iterator, sentinel )
Iterator:
*i – access the value BLOCKING!
++i – move to the next element
Sentinel:
i == s – has iterator reached the end
26
Iterators Ranges Push Pipes Going postal
Push iterators
Input Iterator Output
27
Iterators Ranges Push Pipes Going postal
Push iterators
Each push iterator can:
Accept values
Emit values
No need for the accepted and emitted values to be 1-to-1.
28
Iterators Ranges Push Pipes Going postal
Push iterators
Sources – push iterators that only emit values
Sinks – push iterators that only accept values
Modifiers – push iterators that both accept and emit
values
29
Iterators Ranges Push Pipes Going postal
Continuation
template <typename Cont>
class continuator_base {
public:
void init() { ⋯ }
template <typename T>
void emit(T&& value) const
{
std::invoke(m_continuation, FWD(value));
}
void notify_ended() const { ⋯ }
protected:
Cont m_continuation;
};
30
Iterators Ranges Push Pipes Going postal
Invoke
std::invoke(function, arg1, arg2, ...)
For most cases (functions, function objects, lambdas)
equivalent to:
function(arg1, arg2, ...)
But it can also invoke class member functions:
arg1.function(arg2, ...)
31
Iterators Ranges Push Pipes Going postal
Source
template <typename Cont>
class values_node: public continuator_base<Cont>, non_copyable {
⋯
void init()
{
base::init();
for (auto&& value: m_values) {
base::emit(value);
}
m_values.clear();
base::notify_ended();
}
⋯
};
32
Iterators Ranges Push Pipes Going postal
Source
33
Iterators Ranges Push Pipes Going postal
Creating a source
As far as the rest of the system is concerned, this node
creates the messages.
34
Iterators Ranges Push Pipes Going postal
Creating a sink
35
Iterators Ranges Push Pipes Going postal
Creating a transformation
36
Iterators Ranges Push Pipes Going postal
Creating a transformation
template <typename Cont>
class transform_node: public continuator_base<Cont>, non_copyable {
public:
⋯
template <typename T>
void operator() (T&& value) const
{
base::emit(std::invoke(m_transformation, FWD(value)));
}
private:
Traf m_transformation;
};
37
Iterators Ranges Push Pipes Going postal
Filtering
template <typename Cont>
class filter_node: public continuator_base<Cont>, non_copyable {
public:
⋯
template <typename T>
void operator() (T&& value) const
{
if (std::invoke(m_predicate, value) {
base::emit(FWD(value)));
}
}
private:
Predicate m_predicate;
};
38
PIPES
Iterators Ranges Push Pipes Going postal
Connecting the components
auto pipeline = source | transform(⋯)
| filter(⋯)
| join
| transform(⋯)
⋯
40
Iterators Ranges Push Pipes Going postal
AST
When the pipeline AST is completed and evaluated, then we
get proper pipeline nodes.
41
Iterators Ranges Push Pipes Going postal
Associativity
auto my_transformation = filter(⋯)
| join;
auto pipeline = source | transform(⋯)
| my_transformation 
| transform(⋯)
⋯
42
Iterators Ranges Push Pipes Going postal
Different pipes
Composing two transformations
transform(⋯) | filter(⋯)
Connecting a source to the continuation
source | transform(⋯)
Ending the pipeline
filter(⋯) | sink
Closing the pipeline
source | sink
43
Iterators Ranges Push Pipes Going postal
Different pipes
struct source_node_tag {};
struct sink_node_tag {};
struct transformation_node_tag {};
template <typename T>
class values {
public:
using node_category = source_node_tag;
};
44
Iterators Ranges Push Pipes Going postal
Different pipes
struct source_node_tag {};
struct sink_node_tag {};
struct transformation_node_tag {};
template <typename T>
class filter {
public:
using node_category = transformation_node_tag;
};
45
Iterators Ranges Push Pipes Going postal
Concepts
template <typename Left, typename Right>
auto operator| (Left&& left, Right&& right)
{
return ⋯;
}
Problem: Defines operator| on all types
46
Iterators Ranges Push Pipes Going postal
Concepts
template < typename Node
, typename Category = detected_t<node_category, Node>
>
f_concept is_node()
{
if constexpr (!is_detected_v<node_category, Node>) {
return false;
} else if constexpr (std::is_same_v<void, Category>) {
return false;
} else {
return true;
}
}
Note: Proper concepts will come in C++20. This uses the
detection idiom to simulate concepts.
47
Iterators Ranges Push Pipes Going postal
Concepts
template < typename Left
, typename Right
, f_require(
is_node<Left> && is_node<Right>
)
>
auto operator| (Left&& left, Right&& right)
{
return ⋯;
}
48
Iterators Ranges Push Pipes Going postal
Concepts
if constexpr (!is_source<Left> && !is_sink<Right>) {
⋯ create a composite transformation
} else if constexpr (is_source<Left> && !is_sink<Right>) {
⋯
} else if constexpr (!is_source<Left> && is_sink<Right>) {
⋯
} else {
⋯
}
49
Iterators Ranges Push Pipes Going postal
Concepts
if constexpr (!is_source<Left> && !is_sink<Right>) {
⋯
} else if constexpr (is_source<Left> && !is_sink<Right>) {
⋯ transformed source is also a source
} else if constexpr (!is_source<Left> && is_sink<Right>) {
⋯
} else {
⋯
}
49
Iterators Ranges Push Pipes Going postal
Concepts
if constexpr (!is_source<Left> && !is_sink<Right>) {
⋯
} else if constexpr (is_source<Left> && !is_sink<Right>) {
⋯
} else if constexpr (!is_source<Left> && is_sink<Right>) {
⋯ transformation with a sink is a sink
} else {
⋯
}
49
Iterators Ranges Push Pipes Going postal
Concepts
if constexpr (!is_source<Left> && !is_sink<Right>) {
⋯
} else if constexpr (is_source<Left> && !is_sink<Right>) {
⋯
} else if constexpr (!is_source<Left> && is_sink<Right>) {
⋯
} else {
⋯ the pipeline is complete, evaluate it
}
49
Iterators Ranges Push Pipes Going postal
Pipes
auto new_source = source | transform(⋯) | filter(⋯);
auto new_trafo = transform(⋯) | filter(⋯);
auto new_sink = filter(⋯) | sink;
auto pipeline = new_source | new_trafo | new_sink;
50
Iterators Ranges Push Pipes Going postal
Pipes
Easy implementation of reactive systems
Transparent handling of synchronous vs asynchronous
transformations
High-enough abstraction for more powerful idioms
51
GOING POSTAL
Iterators Ranges Push Pipes Going postal
Functional thinking – data transformation
53
Iterators Ranges Push Pipes Going postal
Functional thinking – data transformation
53
Iterators Ranges Push Pipes Going postal
Functional thinking – data transformation
53
Iterators Ranges Push Pipes Going postal
Distributed pipelines
auto pipeline =
system_cmd(”ping”s, ”localhost”s)
| transform(string_to_upper)
// Parse the ping output
| transform([] (std::string&& value) {
const auto pos = value.find_last_of('=');
return std::make_pair(std::move(value), pos);
})
// Extract the ping time from the output
| transform([] (std::pair<std::string, size_t>&& pair) {
auto [ value, pos ] = pair;
return pos == std::string::npos
? std::move(value)
: std::string(value.cbegin() + pos + 1, value.cend());
})
// Remove slow pings
| filter([] (const std::string& value) {
return value < ”0.145”s;
})
// Print out the ping info
| sink{cout};
54
Iterators Ranges Push Pipes Going postal
Distributed pipelines
auto pipeline =
system_cmd(”ping”s, ”localhost”s)
| transform(string_to_upper)
| voy_bridge(frontend_to_backend_1)
| transform([] (std::string&& value) {
const auto pos = value.find_last_of('=');
return std::make_pair(std::move(value), pos);
})
| transform([] (std::pair<std::string, size_t>&& pair) {
auto [ value, pos ] = pair;
return pos == std::string::npos
? std::move(value)
: std::string(value.cbegin() + pos + 1, value.cend());
})
| voy_bridge(backend_1_to_backend_2)
| filter([] (const std::string& value) {
return value < ”0.145”s;
})
| voy_bridge(backend_2_to_frontend)
| sink{cout};
55
Iterators Ranges Push Pipes Going postal
Live demo
56
Iterators Ranges Push Pipes Going postal
Answers? Questions! Questions? Answers!
Kudos (in chronological order):
Friends at KDE
Saša Malkov and Zoltán Porkoláb
спасибо Сергею и двум Антонам
MEAP – Manning Early Access Program
Functional Programming in C++
cukic.co/to/fp-in-cpp
57

More Related Content

What's hot

String notes
String notesString notes
String notes
Prasadu Peddi
 
Acm aleppo cpc training introduction 1
Acm aleppo cpc training introduction 1Acm aleppo cpc training introduction 1
Acm aleppo cpc training introduction 1
Ahmad Bashar Eter
 
Strings in c
Strings in cStrings in c
Strings in c
vampugani
 
The string class
The string classThe string class
The string class
Syed Zaid Irshad
 
Python data handling
Python data handlingPython data handling
Python data handling
Prof. Dr. K. Adisesha
 
Handling of character strings C programming
Handling of character strings C programmingHandling of character strings C programming
Handling of character strings C programming
Appili Vamsi Krishna
 
Strings part2
Strings part2Strings part2
Strings part2
yndaravind
 
C Programming Unit-3
C Programming Unit-3C Programming Unit-3
C Programming Unit-3
Vikram Nandini
 
Strings in c++
Strings in c++Strings in c++
Strings in c++
Neeru Mittal
 
String c
String cString c
strings
stringsstrings
strings
teach4uin
 
COM1407: Type Casting, Command Line Arguments and Defining Constants
COM1407: Type Casting, Command Line Arguments and Defining Constants COM1407: Type Casting, Command Line Arguments and Defining Constants
COM1407: Type Casting, Command Line Arguments and Defining Constants
Hemantha Kulathilake
 
C programming - String
C programming - StringC programming - String
C programming - String
Achyut Devkota
 
C string
C stringC string
Strinng Classes in c++
Strinng Classes in c++Strinng Classes in c++
Strinng Classes in c++Vikash Dhal
 
C++ string
C++ stringC++ string
C++ string
Dheenadayalan18
 
String in programming language in c or c++
 String in programming language  in c or c++  String in programming language  in c or c++
String in programming language in c or c++
Samsil Arefin
 

What's hot (20)

String notes
String notesString notes
String notes
 
Acm aleppo cpc training introduction 1
Acm aleppo cpc training introduction 1Acm aleppo cpc training introduction 1
Acm aleppo cpc training introduction 1
 
Strings in c
Strings in cStrings in c
Strings in c
 
The string class
The string classThe string class
The string class
 
14 strings
14 strings14 strings
14 strings
 
Python data handling
Python data handlingPython data handling
Python data handling
 
Handling of character strings C programming
Handling of character strings C programmingHandling of character strings C programming
Handling of character strings C programming
 
Strings part2
Strings part2Strings part2
Strings part2
 
C Programming Unit-3
C Programming Unit-3C Programming Unit-3
C Programming Unit-3
 
Strings in c++
Strings in c++Strings in c++
Strings in c++
 
Strings
StringsStrings
Strings
 
String c
String cString c
String c
 
strings
stringsstrings
strings
 
COM1407: Type Casting, Command Line Arguments and Defining Constants
COM1407: Type Casting, Command Line Arguments and Defining Constants COM1407: Type Casting, Command Line Arguments and Defining Constants
COM1407: Type Casting, Command Line Arguments and Defining Constants
 
C programming - String
C programming - StringC programming - String
C programming - String
 
C string
C stringC string
C string
 
Strinng Classes in c++
Strinng Classes in c++Strinng Classes in c++
Strinng Classes in c++
 
C++ string
C++ stringC++ string
C++ string
 
05 c++-strings
05 c++-strings05 c++-strings
05 c++-strings
 
String in programming language in c or c++
 String in programming language  in c or c++  String in programming language  in c or c++
String in programming language in c or c++
 

Similar to C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić

Chapter 4 - Classes in Java
Chapter 4 - Classes in JavaChapter 4 - Classes in Java
Chapter 4 - Classes in Java
Khirulnizam Abd Rahman
 
Lec 8 03_sept [compatibility mode]
Lec 8 03_sept [compatibility mode]Lec 8 03_sept [compatibility mode]
Lec 8 03_sept [compatibility mode]Palak Sanghani
 
Type header file in c++ and its function
Type header file in c++ and its functionType header file in c++ and its function
Type header file in c++ and its functionFrankie Jones
 
PYTHON
PYTHONPYTHON
PYTHON
JOHNYAMSON
 
Declare Your Language: Name Resolution
Declare Your Language: Name ResolutionDeclare Your Language: Name Resolution
Declare Your Language: Name Resolution
Eelco Visser
 
The TclQuadcode Compiler
The TclQuadcode CompilerThe TclQuadcode Compiler
The TclQuadcode Compiler
Donal Fellows
 
Csp scala wixmeetup2016
Csp scala wixmeetup2016Csp scala wixmeetup2016
Csp scala wixmeetup2016
Ruslan Shevchenko
 
Reactive Qt - Ivan Čukić (Qt World Summit 2015)
Reactive Qt - Ivan Čukić (Qt World Summit 2015)Reactive Qt - Ivan Čukić (Qt World Summit 2015)
Reactive Qt - Ivan Čukić (Qt World Summit 2015)
Ivan Čukić
 
Charles Sharp: Java 8 Streams
Charles Sharp: Java 8 StreamsCharles Sharp: Java 8 Streams
Charles Sharp: Java 8 Streams
jessitron
 
Reducing Redundancies in Multi-Revision Code Analysis
Reducing Redundancies in Multi-Revision Code AnalysisReducing Redundancies in Multi-Revision Code Analysis
Reducing Redundancies in Multi-Revision Code Analysis
Sebastiano Panichella
 
Creating the PromQL Transpiler for Flux by Julius Volz, Co-Founder | Prometheus
Creating the PromQL Transpiler for Flux by Julius Volz, Co-Founder | PrometheusCreating the PromQL Transpiler for Flux by Julius Volz, Co-Founder | Prometheus
Creating the PromQL Transpiler for Flux by Julius Volz, Co-Founder | Prometheus
InfluxData
 
python1.ppt
python1.pptpython1.ppt
python1.ppt
arivukarasi2
 
Python ppt
Python pptPython ppt
Python ppt
Anush verma
 
Automatic Task-based Code Generation for High Performance DSEL
Automatic Task-based Code Generation for High Performance DSELAutomatic Task-based Code Generation for High Performance DSEL
Automatic Task-based Code Generation for High Performance DSEL
Joel Falcou
 
Linq and lambda
Linq and lambdaLinq and lambda
Linq and lambda
John Walsh
 
C# 7.x What's new and what's coming with C# 8
C# 7.x What's new and what's coming with C# 8C# 7.x What's new and what's coming with C# 8
C# 7.x What's new and what's coming with C# 8
Christian Nagel
 
Visula C# Programming Lecture 6
Visula C# Programming Lecture 6Visula C# Programming Lecture 6
Visula C# Programming Lecture 6
Abou Bakr Ashraf
 
Constraint Programming in Haskell
Constraint Programming in HaskellConstraint Programming in Haskell
Constraint Programming in Haskell
David Overton
 

Similar to C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić (20)

Chapter 4 - Classes in Java
Chapter 4 - Classes in JavaChapter 4 - Classes in Java
Chapter 4 - Classes in Java
 
Lec 8 03_sept [compatibility mode]
Lec 8 03_sept [compatibility mode]Lec 8 03_sept [compatibility mode]
Lec 8 03_sept [compatibility mode]
 
Type header file in c++ and its function
Type header file in c++ and its functionType header file in c++ and its function
Type header file in c++ and its function
 
PYTHON
PYTHONPYTHON
PYTHON
 
Declare Your Language: Name Resolution
Declare Your Language: Name ResolutionDeclare Your Language: Name Resolution
Declare Your Language: Name Resolution
 
The TclQuadcode Compiler
The TclQuadcode CompilerThe TclQuadcode Compiler
The TclQuadcode Compiler
 
Csp scala wixmeetup2016
Csp scala wixmeetup2016Csp scala wixmeetup2016
Csp scala wixmeetup2016
 
8 - OOP - Syntax & Messages
8 - OOP - Syntax & Messages8 - OOP - Syntax & Messages
8 - OOP - Syntax & Messages
 
Reactive Qt - Ivan Čukić (Qt World Summit 2015)
Reactive Qt - Ivan Čukić (Qt World Summit 2015)Reactive Qt - Ivan Čukić (Qt World Summit 2015)
Reactive Qt - Ivan Čukić (Qt World Summit 2015)
 
Charles Sharp: Java 8 Streams
Charles Sharp: Java 8 StreamsCharles Sharp: Java 8 Streams
Charles Sharp: Java 8 Streams
 
Reducing Redundancies in Multi-Revision Code Analysis
Reducing Redundancies in Multi-Revision Code AnalysisReducing Redundancies in Multi-Revision Code Analysis
Reducing Redundancies in Multi-Revision Code Analysis
 
Creating the PromQL Transpiler for Flux by Julius Volz, Co-Founder | Prometheus
Creating the PromQL Transpiler for Flux by Julius Volz, Co-Founder | PrometheusCreating the PromQL Transpiler for Flux by Julius Volz, Co-Founder | Prometheus
Creating the PromQL Transpiler for Flux by Julius Volz, Co-Founder | Prometheus
 
python1.ppt
python1.pptpython1.ppt
python1.ppt
 
Python ppt
Python pptPython ppt
Python ppt
 
Automatic Task-based Code Generation for High Performance DSEL
Automatic Task-based Code Generation for High Performance DSELAutomatic Task-based Code Generation for High Performance DSEL
Automatic Task-based Code Generation for High Performance DSEL
 
Intro toswift1
Intro toswift1Intro toswift1
Intro toswift1
 
Linq and lambda
Linq and lambdaLinq and lambda
Linq and lambda
 
C# 7.x What's new and what's coming with C# 8
C# 7.x What's new and what's coming with C# 8C# 7.x What's new and what's coming with C# 8
C# 7.x What's new and what's coming with C# 8
 
Visula C# Programming Lecture 6
Visula C# Programming Lecture 6Visula C# Programming Lecture 6
Visula C# Programming Lecture 6
 
Constraint Programming in Haskell
Constraint Programming in HaskellConstraint Programming in Haskell
Constraint Programming in Haskell
 

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. Обработка списков на C++ в функциональном стиле - В...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
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. 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. Обработка списков на C++ в функциональном стиле - В...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
 
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. 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
 

Recently uploaded

DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
Kari Kakkonen
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
Prayukth K V
 
"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi
Fwdays
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
ThousandEyes
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Jeffrey Haguewood
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
Jemma Hussein Allen
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
Product School
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Product School
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Ramesh Iyer
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
Cheryl Hung
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
DianaGray10
 
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Inflectra
 
Search and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical FuturesSearch and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical Futures
Bhaskar Mitra
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
RTTS
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
Elena Simperl
 
PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
Ralf Eggert
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
Paul Groth
 

Recently uploaded (20)

DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
 
"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
 
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
 
Search and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical FuturesSearch and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical Futures
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
 
PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
 

C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić

  • 1. Async. programming with ranges Corehard Autumn 2018 dr Ivan Čukić ivan@cukic.co core-dev @ KDE http://cukic.co www.kde.org
  • 2. Iterators Ranges Push Pipes Going postal About me KDE development Talks and teaching Author of ”Functional Programming in C++” (Manning) Functional programming enthusiast, but not a purist 2
  • 3. Iterators Ranges Push Pipes Going postal Disclaimer Make your code readable. Pretend the next person who looks at your code is a psychopath and they know where you live. Philip Wadler 3
  • 5. Iterators Ranges Push Pipes Going postal Iterators At the core of generic programming in STL. 5
  • 6. Iterators Ranges Push Pipes Going postal Iterators std::vector<std::string> identifiers; std::copy_if( std::cbegin(tokens), std::cend(tokens), std::back_inserter(identifiers), is_valid_identifier); 6
  • 7. Iterators Ranges Push Pipes Going postal Iterators std::vector<std::string> identifiers; std::copy_if( std::istream_iterator<std::string>(std::cin), std::istream_iterator<std::string>(), std::back_inserter(identifiers), is_valid_identifier); 7
  • 8. Iterators Ranges Push Pipes Going postal Example 8
  • 9. Iterators Ranges Push Pipes Going postal Example 8
  • 10. Iterators Ranges Push Pipes Going postal Example 8
  • 11. Iterators Ranges Push Pipes Going postal Example 8
  • 12. Iterators Ranges Push Pipes Going postal Example template <typename It, typename Pred> std::pair<It, It> move_selected( It begin, It end, It destination, Pred is_selected) { return { std::stable_partition(begin, destination, std::not_fn(is_selected)), std::stable_partition(destination, end, is_selected) }; } 9
  • 14. Iterators Ranges Push Pipes Going postal Problems with iterators Example: Sum of squares This should be separable into two subtasks: squaring the values summation 11
  • 15. Iterators Ranges Push Pipes Going postal Problems with iterators std::vector<int> xs { ⋯ }; std::vector<int> squared(xs.size()); std::transform(std::cbegin(xs), std::cend(xs), std::begin(squared), [] (int x) { return x * x; }); return std::accumulate(std::cbegin(squared), std::cend(squared), 0); 12
  • 16. Iterators Ranges Push Pipes Going postal Problems with iterators std::vector<int> xs { ⋯ }; return std::transform_reduce(par, std::cbegin(xs), std::cend(xs), std::cbegin(xs), 0); 13
  • 17. Iterators Ranges Push Pipes Going postal Proxy iterators template <typename Trafo, typename It> class transform_proxy_iterator { public: auto operator*() const { return transformation( *real_iterator); } private: Trafo transformation; It real_iterator; }; 14
  • 18. Iterators Ranges Push Pipes Going postal Ranges [ iterator, sentinel ) Iterator: *i – access the value ++i – move to the next element Sentinel: i == s – has iterator reached the end? 15
  • 19. Iterators Ranges Push Pipes Going postal Ranges std::vector<int> xs { ⋯ }; accumulate( transform( xs, [] (int x) { ⋯ }), 0); 16
  • 20. Iterators Ranges Push Pipes Going postal Ranges std::vector<int> xs { ⋯ }; accumulate( transform( filter( xs, [] (int x) { ⋯ }), [] (int x) { ⋯ }), 0); 17
  • 21. Iterators Ranges Push Pipes Going postal Ranges std::vector<int> xs { ⋯ }; accumulate( xs | filter([] (int x) { ⋯ }) | transform([] (int x) { ⋯ }), 0); 18
  • 22. Iterators Ranges Push Pipes Going postal Word frequency 1986: Donald Knuth was asked to implement a program for the ”Programming pearls” column in the Communications of ACM journal. The task: Read a file of text, determine the n most frequently used words, and print out a sorted list of those words along with their frequencies. 19
  • 23. Iterators Ranges Push Pipes Going postal Word frequency 1986: Donald Knuth was asked to implement a program for the ”Programming pearls” column in the Communications of ACM journal. The task: Read a file of text, determine the n most frequently used words, and print out a sorted list of those words along with their frequencies. His solution written in Pascal was 10 pages long. 19
  • 24. Iterators Ranges Push Pipes Going postal Word frequency Response by Doug McIlroy was a 6-line shell script that did the same: tr −cs A−Za−z ' n ' | tr A−Z a−z | sort | uniq −c | sort −rn | sed ${1}q 20
  • 25. Iterators Ranges Push Pipes Going postal Functional thinking – data transformation 21
  • 26. Iterators Ranges Push Pipes Going postal With ranges const auto words = // Range of words istream_range<std::string>(std::cin) // Cleaning the input | view::transform(string_to_lower) | view::transform(string_only_alnum) | view::remove_if(&std::string::empty) // Sort the result | to_vector | action::sort; 22
  • 27. Iterators Ranges Push Pipes Going postal With ranges const auto results = words // Group repeated words | view::group_by(std::equal_to<>()) // Count how many repetitions we have | view::transform([] (const auto &group) { return std::make_pair( distance(begin(group), end(group), *begin(group)); }) // Sort by frequency | to_vector | action::sort; 23
  • 28. Iterators Ranges Push Pipes Going postal With ranges for (auto value: results | view::reverse // descending | view::take(n) // we need first n results ) { std::cout << value.first << ” ” << value.second << std::endl; } 24
  • 29. PUSH
  • 30. Iterators Ranges Push Pipes Going postal Ranges [ iterator, sentinel ) Iterator: *i – access the value ++i – move to the next element Sentinel: i == s – has iterator reached the end 26
  • 31. Iterators Ranges Push Pipes Going postal Ranges [ iterator, sentinel ) Iterator: *i – access the value BLOCKING! ++i – move to the next element Sentinel: i == s – has iterator reached the end 26
  • 32. Iterators Ranges Push Pipes Going postal Push iterators Input Iterator Output 27
  • 33. Iterators Ranges Push Pipes Going postal Push iterators Each push iterator can: Accept values Emit values No need for the accepted and emitted values to be 1-to-1. 28
  • 34. Iterators Ranges Push Pipes Going postal Push iterators Sources – push iterators that only emit values Sinks – push iterators that only accept values Modifiers – push iterators that both accept and emit values 29
  • 35. Iterators Ranges Push Pipes Going postal Continuation template <typename Cont> class continuator_base { public: void init() { ⋯ } template <typename T> void emit(T&& value) const { std::invoke(m_continuation, FWD(value)); } void notify_ended() const { ⋯ } protected: Cont m_continuation; }; 30
  • 36. Iterators Ranges Push Pipes Going postal Invoke std::invoke(function, arg1, arg2, ...) For most cases (functions, function objects, lambdas) equivalent to: function(arg1, arg2, ...) But it can also invoke class member functions: arg1.function(arg2, ...) 31
  • 37. Iterators Ranges Push Pipes Going postal Source template <typename Cont> class values_node: public continuator_base<Cont>, non_copyable { ⋯ void init() { base::init(); for (auto&& value: m_values) { base::emit(value); } m_values.clear(); base::notify_ended(); } ⋯ }; 32
  • 38. Iterators Ranges Push Pipes Going postal Source 33
  • 39. Iterators Ranges Push Pipes Going postal Creating a source As far as the rest of the system is concerned, this node creates the messages. 34
  • 40. Iterators Ranges Push Pipes Going postal Creating a sink 35
  • 41. Iterators Ranges Push Pipes Going postal Creating a transformation 36
  • 42. Iterators Ranges Push Pipes Going postal Creating a transformation template <typename Cont> class transform_node: public continuator_base<Cont>, non_copyable { public: ⋯ template <typename T> void operator() (T&& value) const { base::emit(std::invoke(m_transformation, FWD(value))); } private: Traf m_transformation; }; 37
  • 43. Iterators Ranges Push Pipes Going postal Filtering template <typename Cont> class filter_node: public continuator_base<Cont>, non_copyable { public: ⋯ template <typename T> void operator() (T&& value) const { if (std::invoke(m_predicate, value) { base::emit(FWD(value))); } } private: Predicate m_predicate; }; 38
  • 44. PIPES
  • 45. Iterators Ranges Push Pipes Going postal Connecting the components auto pipeline = source | transform(⋯) | filter(⋯) | join | transform(⋯) ⋯ 40
  • 46. Iterators Ranges Push Pipes Going postal AST When the pipeline AST is completed and evaluated, then we get proper pipeline nodes. 41
  • 47. Iterators Ranges Push Pipes Going postal Associativity auto my_transformation = filter(⋯) | join; auto pipeline = source | transform(⋯) | my_transformation  | transform(⋯) ⋯ 42
  • 48. Iterators Ranges Push Pipes Going postal Different pipes Composing two transformations transform(⋯) | filter(⋯) Connecting a source to the continuation source | transform(⋯) Ending the pipeline filter(⋯) | sink Closing the pipeline source | sink 43
  • 49. Iterators Ranges Push Pipes Going postal Different pipes struct source_node_tag {}; struct sink_node_tag {}; struct transformation_node_tag {}; template <typename T> class values { public: using node_category = source_node_tag; }; 44
  • 50. Iterators Ranges Push Pipes Going postal Different pipes struct source_node_tag {}; struct sink_node_tag {}; struct transformation_node_tag {}; template <typename T> class filter { public: using node_category = transformation_node_tag; }; 45
  • 51. Iterators Ranges Push Pipes Going postal Concepts template <typename Left, typename Right> auto operator| (Left&& left, Right&& right) { return ⋯; } Problem: Defines operator| on all types 46
  • 52. Iterators Ranges Push Pipes Going postal Concepts template < typename Node , typename Category = detected_t<node_category, Node> > f_concept is_node() { if constexpr (!is_detected_v<node_category, Node>) { return false; } else if constexpr (std::is_same_v<void, Category>) { return false; } else { return true; } } Note: Proper concepts will come in C++20. This uses the detection idiom to simulate concepts. 47
  • 53. Iterators Ranges Push Pipes Going postal Concepts template < typename Left , typename Right , f_require( is_node<Left> && is_node<Right> ) > auto operator| (Left&& left, Right&& right) { return ⋯; } 48
  • 54. Iterators Ranges Push Pipes Going postal Concepts if constexpr (!is_source<Left> && !is_sink<Right>) { ⋯ create a composite transformation } else if constexpr (is_source<Left> && !is_sink<Right>) { ⋯ } else if constexpr (!is_source<Left> && is_sink<Right>) { ⋯ } else { ⋯ } 49
  • 55. Iterators Ranges Push Pipes Going postal Concepts if constexpr (!is_source<Left> && !is_sink<Right>) { ⋯ } else if constexpr (is_source<Left> && !is_sink<Right>) { ⋯ transformed source is also a source } else if constexpr (!is_source<Left> && is_sink<Right>) { ⋯ } else { ⋯ } 49
  • 56. Iterators Ranges Push Pipes Going postal Concepts if constexpr (!is_source<Left> && !is_sink<Right>) { ⋯ } else if constexpr (is_source<Left> && !is_sink<Right>) { ⋯ } else if constexpr (!is_source<Left> && is_sink<Right>) { ⋯ transformation with a sink is a sink } else { ⋯ } 49
  • 57. Iterators Ranges Push Pipes Going postal Concepts if constexpr (!is_source<Left> && !is_sink<Right>) { ⋯ } else if constexpr (is_source<Left> && !is_sink<Right>) { ⋯ } else if constexpr (!is_source<Left> && is_sink<Right>) { ⋯ } else { ⋯ the pipeline is complete, evaluate it } 49
  • 58. Iterators Ranges Push Pipes Going postal Pipes auto new_source = source | transform(⋯) | filter(⋯); auto new_trafo = transform(⋯) | filter(⋯); auto new_sink = filter(⋯) | sink; auto pipeline = new_source | new_trafo | new_sink; 50
  • 59. Iterators Ranges Push Pipes Going postal Pipes Easy implementation of reactive systems Transparent handling of synchronous vs asynchronous transformations High-enough abstraction for more powerful idioms 51
  • 61. Iterators Ranges Push Pipes Going postal Functional thinking – data transformation 53
  • 62. Iterators Ranges Push Pipes Going postal Functional thinking – data transformation 53
  • 63. Iterators Ranges Push Pipes Going postal Functional thinking – data transformation 53
  • 64. Iterators Ranges Push Pipes Going postal Distributed pipelines auto pipeline = system_cmd(”ping”s, ”localhost”s) | transform(string_to_upper) // Parse the ping output | transform([] (std::string&& value) { const auto pos = value.find_last_of('='); return std::make_pair(std::move(value), pos); }) // Extract the ping time from the output | transform([] (std::pair<std::string, size_t>&& pair) { auto [ value, pos ] = pair; return pos == std::string::npos ? std::move(value) : std::string(value.cbegin() + pos + 1, value.cend()); }) // Remove slow pings | filter([] (const std::string& value) { return value < ”0.145”s; }) // Print out the ping info | sink{cout}; 54
  • 65. Iterators Ranges Push Pipes Going postal Distributed pipelines auto pipeline = system_cmd(”ping”s, ”localhost”s) | transform(string_to_upper) | voy_bridge(frontend_to_backend_1) | transform([] (std::string&& value) { const auto pos = value.find_last_of('='); return std::make_pair(std::move(value), pos); }) | transform([] (std::pair<std::string, size_t>&& pair) { auto [ value, pos ] = pair; return pos == std::string::npos ? std::move(value) : std::string(value.cbegin() + pos + 1, value.cend()); }) | voy_bridge(backend_1_to_backend_2) | filter([] (const std::string& value) { return value < ”0.145”s; }) | voy_bridge(backend_2_to_frontend) | sink{cout}; 55
  • 66. Iterators Ranges Push Pipes Going postal Live demo 56
  • 67. Iterators Ranges Push Pipes Going postal Answers? Questions! Questions? Answers! Kudos (in chronological order): Friends at KDE Saša Malkov and Zoltán Porkoláb спасибо Сергею и двум Антонам MEAP – Manning Early Access Program Functional Programming in C++ cukic.co/to/fp-in-cpp 57