SlideShare a Scribd company logo
1 of 46
Download to read offline
Functional Microscope:
Lenses in С++
Alexander Granin
graninas@gmail.com
C++ Siberia, Novosibirsk
Me?
● C++, Haskell, C#
● C++ User Group Novosibirsk, 2014
● Talks, articles, FP evangelism...
● LambdaNsk - Novosibirsk FP-community
● Kaspersky Lab
struct Presentation
{
FP in C++?..
Functional Lenses
cpp_lenses library
};
4
FP in C++?..
С++ User Group Novosibirsk, 2014
FP concepts in C++
● Lambdas, closures, functions (almost pure)
● Immutability, POD-types
● Templates - pure functional language
● FTL - Functional Template Library
● Initialization lists
● for_each(), recursion
7
Functional Lenses
Lens 2 Lens 3Lens 1
8
Matryoshka
struct Account { Person person; };
struct Person { Address address; };
struct Address
{
std::string street;
int house;
int flat;
};
9
Mutable variables...
void setStreet(Account& account, const std::string& newStreet)
{
account.person.address.street = newStreet;
}
10
void setStreet(Account& account, const std::string& newStreet)
{
account.person.address.street = newStreet;
}
Mutable variables...
● Easy to break the client code
● Demetra law is violated
● Highly specific code
● Boilerplate
11
Mutable state...
void Account::setStreet(const std::string& newStreet)
{
this->person.address.street = newStreet;
}
12
Mutable state...
void Account::setStreet(const std::string& newStreet)
{
this->person.address.street = newStreet;
}
● Demetra law is violated
● Highly specific code
● Mixing of different layers
● SRP is violated
● Not a POD type
13
Account setStreet(Account account, const std::string& newStreet)
{
account.person.address.street = newStreet;
return account;
}
Immutable approach…
14
Account setStreet(Account account, const std::string& newStreet)
{
account.person.address.street = newStreet;
return account;
}
Immutable approach… Not so good.
● Easy to break the client code
● Demetra law is violated
● Highly specific code
● Boilerplate
Ok, Lenses!
auto lens = zoom(personLens, addressLens, streetLens);
auto newAccount = set(lens, oldAccount, std::string("New street"));
● “Focused” internal element of the structure
● Do something with the element from outside
● Hiding data structure realization
● Fully immutable, composable and reusable
Ok, Lenses!
auto lens = zoom(personLens, addressLens, streetLens);
auto newAccount = set(lens, oldAccount, std::string("New street"));
So, how does this work?
Open matryoshka, pull out matryoshka...
Account account = {...};
Person person = getPerson(account);
Address address = getAddress(person);
std::string street = getStreet(address);
std::string newStreet = "Churchill's " + street;
Address newAddress = setStreet(address, newStreet);
Person newPerson = setAddress(person, newAddress);
Account newAccount = setPerson(account, newPerson);
Person getPerson(const Account& account) {
return account.person;
}
Account setPerson(Account account, const Person& person) {
account.person = person;
return account;
}
getA(), setA()
auto getPerson = [](const Account& account) {
return account.person;
};
auto setPerson = [](Account account, const Person& person) {
account.person = person;
return account;
};
Getter, Setter
auto getPerson = [](const Account& account) {
return account.person;
};
auto setPerson = [](Account account, const Person& person) {
account.person = person;
return account;
};
Getter, Setter
std::function<Focus(Value)> getter;
std::function<Value(Value, Focus)> setter;
template <typename Value, typename Focus>
struct Lens {
std::function<Focus(Value)> getter;
std::function<Value(Value, Focus)> setter;
};
Lens<Account, Person> personLens = { getPerson, setPerson };
Lens = Getter + Setter
view
template <typename Value, typename Focus>
Focus view(const Lens<Value, Focus>& lens, const Value& value) {
return lens.getter(value);
}
Lens<Account, Person> personLens = { getPerson, setPerson };
Person person = view(personLens, someAccount);
set
template <typename Value, typename Focus>
Value set(const Lens<Value, Focus>& lens, const Value& value,
const Focus& newFocus) {
return l.setter(value, newFocus);
}
Lens<Account, Person> personLens = { getPerson, setPerson };
Person person = view(personLens, someAccount);
Account newAccount = set(personLens, account, Person(”Santa”, ”Claus”));
Lens composition is Lens too
Lens<Account, Person> personLens = { getPerson, setPerson };
Lens<Person, Address> addressLens = { getAddress, setAddress };
Lens<Address, std::string> streetLens = { getStreet, setStreet };
auto lens = zoom(personLens, addressLens, streetLens); // Magic zoom!
Account newAccount = set(lens, someAccount, std::string(”Churchill's”));
Lens composition is Lens too
Lens<Account, Person> personLens = { getPerson, setPerson };
Lens<Person, Address> addressLens = { getAddress, setAddress };
Lens<Address, std::string> streetLens = { getStreet, setStreet };
auto lens = zoom(personLens, addressLens, streetLens); // Magic zoom!
// getPerson, getAddress, setStreet, setAddress, setPerson
Account newAccount = set(lens, someAccount, std::string(”Churchill's”));
26
cpp_lens library
Manual lenses
template <typename Value, typename Focus>
Lens<Value, Focus> lens(const std::function<Focus(Value)>& getter,
const std::function<Value(Value, Focus)>& setter) {
Lens<Value, Focus> l;
l.getter = getter;
l.setter = setter;
return l;
}
auto personL = lens<Account, Person>(
[](const Account& a) { return a.person; },
[](Account a, const Person& p) { a.person = p; return a; });
Autolenses
struct Account {
Person person;
std::string login;
std::string password;
};
#define MK_LENS(A, B, member) Lens<A, B> member##L() { 
return lens<A, B> ( GETTER(A, member), SETTER(A, B, member)); }
MK_LENS(Account, Person, person) // personL()
MK_LENS(Account, std::string, login) // loginL()
MK_LENS(Account, std::string, password) // passwordL()
zoom
Lens<A, B> lens = aToB;
???<A, B, C> lens = zoom(aToB, bToC);
???<A, B, C, D> lens = zoom(aToB, bToC, cToD);
zoom (not generic) -> LensStack
Lens<A, B> lens = aToB;
LensStack<A, B, C> lens = zoom(aToB, bToC);
LensStack<A, B, C, D> lens = zoom(aToB, bToC, cToD);
template <typename A, typename B, typename C>
LensStack<A, B, C> zoom(...) { … }
template <typename A, typename B, typename C, typename D>
LensStack<A, B, C, D> zoom(...) { ... }
LensStack (not generic)
template <typename A, typename B, typename C = Id, typename D = Id>
struct LensStack {
Lens<A, B> lens1;
Lens<B, C> lens2;
Lens<C, D> lens3;
};
LensStack<A, B, C> lens = zoom(aToB, bToC); // OK
LensStack<A, B, C, D> lens = zoom(aToB, bToC, cToD); // OK
LensStack<A, B, C, D, E> lens = zoom(aToB, bToC, cToD, dToE); // Ooops!
LensStack: Variadic Templates + magic
template<typename L, typename... Tail>
struct LensStack<L, Tail...> : LensStack<Tail...>
{
typedef LensStack<Tail...> base_type;
LensStack(L lens, Tail... tail)
: LensStack<Tail...>(tail...)
, m_lens(lens) {}
base_type& m_base = static_cast<base_type&>(*this);
L m_lens;
};
Infix literal `to` combinator!
auto lens1 = addressL to houseL;
auto lens2 = personL to lens1;
auto lens3 = aL to bL to cL to dL to … to theLastOneLens;
auto lens = (a to b) to c; // OK, left-associative
auto lens = a to (b to c); // Error
`to`: proxy + overloading + reroll stack
struct Proxy {...} proxy;
template <typename L1, typename L2>
LensStack<Lens<L1, L2>> operator<(const Lens<L1, L2>& lens, const Proxy&)
{ return LensStack<Lens<L1, L2>>(lens); }
template <typename LS, typename L>
typename LS::template reroll_type<L> operator>(const LS& stack, const L& lens)
{ return stack.reroll(lens); }
// `Infix literal operator` trick
#define to < proxy >
set
auto lens = personL() to addressL() to houseL();
Account account1 = {...};
Account account2 = set(lens, account1, 20); // house == 20
set, over
auto lens = personL() to addressL() to houseL();
Account account1 = {...};
Account account2 = set(lens, account1, 20); // house == 20
std::function<int(int)> modifier = [](int old) { return old + 6; };
Account account3 = over(lens, account2, modifier); // house == 26
What about containers?
struct Car { std::string model; };
std::vector<Car> cars = { Car{"Ford Focus"}, Car{"Toyota Corolla"} };
toListOf *
struct Car { std::string model; };
std::vector<Car> cars = { Car{"Ford Focus"}, Car{"Toyota Corolla"} };
std::list<std::string> result = toListOf(folded<Car>() to modelL(), cars);
// result: {"Ford Focus", "Toyota Corolla"}
* toListOf() and folded<T>() is a hack now, sorry...
traversed
struct Account { Person person; };
struct Person { std::vector<Car> cars; };
struct Car { std::string model;
int number; };
auto toCarL = personL() to carsL() to traversed<Car>();
traversed + set
struct Account { Person person; };
struct Person { std::vector<Car> cars; };
struct Car { std::string model;
int number; };
auto toCarL = personL() to carsL() to traversed<Car>();
Account newAccount1 = set(toCarL to modelL(), oldAccount, std::string(“Toyota”));
traversed + over
struct Account { Person person; };
struct Person { std::vector<Car> cars; };
struct Car { std::string model;
int number; };
auto toCarL = personL() to carsL() to traversed<Car>();
Account newAccount1 = set(toCarL to modelL(), oldAccount, std::string(“Toyota”));
std::function<std::string(std::string)> modifier = [](int old) { return old + 6; };
Account newAccount2 = over(toCarL to numberL(), newAccount1, modifier);
traversed + traversed!
struct Account { Person person; };
struct Person { std::vector<Car> cars; };
struct Car { std::string model;
int number;
std::list<std::string> accessories; };
auto toAccessoryL = personL() to carsL() to traversed<Car>()
to accessoriesL() to traversed<std::string>();
cpp_lenses library
● Highly experimental
● Done: composing; set, view, over, traverse
● TODO: filter, traverse++, fold, prisms, fusion…
● TODO: clean it, make it wise, short and robust
● github.com/graninas/cpp_lenses
● Complex structures processing
● Test data preparation
● Some XPath, LINQ analogue
● Functional approach
● Much better than just <algorithm>
● ...Why not? Functional C++ is reality coming now
Why lenses in C++?
Thank you!
Alexander Granin
graninas@gmail.com
Any questions?
C++ Siberia, Novosibirsk
Rerolling LensStack
template<typename L1, typename... Tail>
struct LS<L1, Tail...> : LS<Tail...>
{
template <typename Reroll, typename Lx>
void reroll_(Reroll& rerolled, const Lx& lx) const
{
rerolled.m_lens = m_lens;
base.reroll_(rerolled.base, lx);
}
template <typename Lx>
LensStack<L1, Tail..., Lx> reroll(const Lx& lx) const
{
LensStack<L1, Tail..., Lx> rerolled;
rerolled.m_lens = m_lens;
base.reroll_(rerolled.base, lx);
return rerolled;
}
}
// Recursion base
template <typename... Tail>
struct LensStack
{
template <typename Reroll, typename Lx>
void reroll_(Reroll& rerolled, const Lx& lx)
{
rerolled.m_lens = lx;
}
};

More Related Content

What's hot

пасічник о.г. , пасічник о.в. , стеценко і.в. основи веб дизайну (2009)2
пасічник о.г. , пасічник о.в. , стеценко і.в. основи веб дизайну (2009)2пасічник о.г. , пасічник о.в. , стеценко і.в. основи веб дизайну (2009)2
пасічник о.г. , пасічник о.в. , стеценко і.в. основи веб дизайну (2009)2Vova Dudnik
 
положення про шкільну методичну комісію
положення про шкільну методичну комісіюположення про шкільну методичну комісію
положення про шкільну методичну комісіюSchool
 
Енцефаліти,менінгіти.Кричун.pdf
Енцефаліти,менінгіти.Кричун.pdfЕнцефаліти,менінгіти.Кричун.pdf
Енцефаліти,менінгіти.Кричун.pdfssuser1d08181
 
укуси отруйних змій та комах тютюнник на
укуси отруйних змій та комах   тютюнник наукуси отруйних змій та комах   тютюнник на
укуси отруйних змій та комах тютюнник наsansanych86
 
Наказ про організацію весняних канікул
Наказ про організацію весняних канікулНаказ про організацію весняних канікул
Наказ про організацію весняних канікулВолодимир Бондаренко
 
Skvortsova Svetlana Alekseevna
Skvortsova Svetlana Alekseevna Skvortsova Svetlana Alekseevna
Skvortsova Svetlana Alekseevna e-ranok e-ranok
 
система методів і методичних прийомів шкільного навчання історії
система методів і методичних прийомів шкільного навчання історіїсистема методів і методичних прийомів шкільного навчання історії
система методів і методичних прийомів шкільного навчання історіїgavronnatalia
 
презентація до теми 3
презентація до теми 3презентація до теми 3
презентація до теми 3cdecit
 
Ha active active bang gfs2
Ha active  active bang gfs2Ha active  active bang gfs2
Ha active active bang gfs2laonap166
 
лекція 1, 2
лекція 1, 2лекція 1, 2
лекція 1, 2cit-cit
 
тема 10
тема 10тема 10
тема 10Nata_iv
 
ндр, її створення
ндр, її створенняндр, її створення
ндр, її створенняdolidn
 
презентація до теми 4
презентація до теми 4презентація до теми 4
презентація до теми 4cdecit
 
Презент. проекту "Корисна та шкідлива їжа"
Презент. проекту "Корисна та шкідлива їжа"Презент. проекту "Корисна та шкідлива їжа"
Презент. проекту "Корисна та шкідлива їжа"ZHOIPPO
 
презентація до теми 7
презентація до теми 7презентація до теми 7
презентація до теми 7cdecit
 
презентація до дня студента
презентація до дня студентапрезентація до дня студента
презентація до дня студентаssusere60f00
 
пізні гестози
пізні гестозипізні гестози
пізні гестозиagusya
 
Рада профілактики, 2022-2023.pdf
Рада профілактики, 2022-2023.pdfРада профілактики, 2022-2023.pdf
Рада профілактики, 2022-2023.pdfssuserac8ec11
 
Особливості організації гурткової роботи в світлі викликів ХХІ століття
Особливості організації гурткової роботи в світлі викликів ХХІ століттяОсобливості організації гурткової роботи в світлі викликів ХХІ століття
Особливості організації гурткової роботи в світлі викликів ХХІ століттяЄгор Пилипенко
 

What's hot (20)

пасічник о.г. , пасічник о.в. , стеценко і.в. основи веб дизайну (2009)2
пасічник о.г. , пасічник о.в. , стеценко і.в. основи веб дизайну (2009)2пасічник о.г. , пасічник о.в. , стеценко і.в. основи веб дизайну (2009)2
пасічник о.г. , пасічник о.в. , стеценко і.в. основи веб дизайну (2009)2
 
положення про шкільну методичну комісію
положення про шкільну методичну комісіюположення про шкільну методичну комісію
положення про шкільну методичну комісію
 
Енцефаліти,менінгіти.Кричун.pdf
Енцефаліти,менінгіти.Кричун.pdfЕнцефаліти,менінгіти.Кричун.pdf
Енцефаліти,менінгіти.Кричун.pdf
 
укуси отруйних змій та комах тютюнник на
укуси отруйних змій та комах   тютюнник наукуси отруйних змій та комах   тютюнник на
укуси отруйних змій та комах тютюнник на
 
Наказ про організацію весняних канікул
Наказ про організацію весняних канікулНаказ про організацію весняних канікул
Наказ про організацію весняних канікул
 
Skvortsova Svetlana Alekseevna
Skvortsova Svetlana Alekseevna Skvortsova Svetlana Alekseevna
Skvortsova Svetlana Alekseevna
 
система методів і методичних прийомів шкільного навчання історії
система методів і методичних прийомів шкільного навчання історіїсистема методів і методичних прийомів шкільного навчання історії
система методів і методичних прийомів шкільного навчання історії
 
презентація до теми 3
презентація до теми 3презентація до теми 3
презентація до теми 3
 
Ha active active bang gfs2
Ha active  active bang gfs2Ha active  active bang gfs2
Ha active active bang gfs2
 
лекція 1, 2
лекція 1, 2лекція 1, 2
лекція 1, 2
 
тема 10
тема 10тема 10
тема 10
 
Опис досвіду роботи
Опис досвіду роботиОпис досвіду роботи
Опис досвіду роботи
 
ндр, її створення
ндр, її створенняндр, її створення
ндр, її створення
 
презентація до теми 4
презентація до теми 4презентація до теми 4
презентація до теми 4
 
Презент. проекту "Корисна та шкідлива їжа"
Презент. проекту "Корисна та шкідлива їжа"Презент. проекту "Корисна та шкідлива їжа"
Презент. проекту "Корисна та шкідлива їжа"
 
презентація до теми 7
презентація до теми 7презентація до теми 7
презентація до теми 7
 
презентація до дня студента
презентація до дня студентапрезентація до дня студента
презентація до дня студента
 
пізні гестози
пізні гестозипізні гестози
пізні гестози
 
Рада профілактики, 2022-2023.pdf
Рада профілактики, 2022-2023.pdfРада профілактики, 2022-2023.pdf
Рада профілактики, 2022-2023.pdf
 
Особливості організації гурткової роботи в світлі викликів ХХІ століття
Особливості організації гурткової роботи в світлі викликів ХХІ століттяОсобливості організації гурткової роботи в світлі викликів ХХІ століття
Особливості організації гурткової роботи в світлі викликів ХХІ століття
 

Similar to Functional microscope - Lenses in C++

Look Ma, “update DB to HTML5 using C++”, no hands! 
Look Ma, “update DB to HTML5 using C++”, no hands! Look Ma, “update DB to HTML5 using C++”, no hands! 
Look Ma, “update DB to HTML5 using C++”, no hands! aleks-f
 
Дмитрий Верескун «Синтаксический сахар C#»
Дмитрий Верескун «Синтаксический сахар C#»Дмитрий Верескун «Синтаксический сахар C#»
Дмитрий Верескун «Синтаксический сахар C#»SpbDotNet Community
 
GECon2017_Cpp a monster that no one likes but that will outlast them all _Ya...
GECon2017_Cpp  a monster that no one likes but that will outlast them all _Ya...GECon2017_Cpp  a monster that no one likes but that will outlast them all _Ya...
GECon2017_Cpp a monster that no one likes but that will outlast them all _Ya...GECon_Org Team
 
GECon 2017: C++ - a Monster that no one likes but that will outlast them all
GECon 2017: C++ - a Monster that no one likes but that will outlast them allGECon 2017: C++ - a Monster that no one likes but that will outlast them all
GECon 2017: C++ - a Monster that no one likes but that will outlast them allYauheni Akhotnikau
 
C++: Constructor, Copy Constructor and Assignment operator
C++: Constructor, Copy Constructor and Assignment operatorC++: Constructor, Copy Constructor and Assignment operator
C++: Constructor, Copy Constructor and Assignment operatorJussi Pohjolainen
 
CPP Language Basics - Reference
CPP Language Basics - ReferenceCPP Language Basics - Reference
CPP Language Basics - ReferenceMohammed Sikander
 
Dynamic C++ Silicon Valley Code Camp 2012
Dynamic C++ Silicon Valley Code Camp 2012Dynamic C++ Silicon Valley Code Camp 2012
Dynamic C++ Silicon Valley Code Camp 2012aleks-f
 
What's new in C# 6 - NetPonto Porto 20160116
What's new in C# 6  - NetPonto Porto 20160116What's new in C# 6  - NetPonto Porto 20160116
What's new in C# 6 - NetPonto Porto 20160116Paulo Morgado
 
I want help in the following C++ programming task. Please do coding .pdf
I want help in the following C++ programming task. Please do coding .pdfI want help in the following C++ programming task. Please do coding .pdf
I want help in the following C++ programming task. Please do coding .pdfbermanbeancolungak45
 
Getting started with ES6
Getting started with ES6Getting started with ES6
Getting started with ES6Nitay Neeman
 
Arquitetura Java em 2007 (Java Architecture in 2007)
Arquitetura Java em 2007 (Java Architecture in 2007)Arquitetura Java em 2007 (Java Architecture in 2007)
Arquitetura Java em 2007 (Java Architecture in 2007)Phil Calçado
 

Similar to Functional microscope - Lenses in C++ (20)

Look Ma, “update DB to HTML5 using C++”, no hands! 
Look Ma, “update DB to HTML5 using C++”, no hands! Look Ma, “update DB to HTML5 using C++”, no hands! 
Look Ma, “update DB to HTML5 using C++”, no hands! 
 
Дмитрий Верескун «Синтаксический сахар C#»
Дмитрий Верескун «Синтаксический сахар C#»Дмитрий Верескун «Синтаксический сахар C#»
Дмитрий Верескун «Синтаксический сахар C#»
 
Bind me if you can
Bind me if you canBind me if you can
Bind me if you can
 
GECon2017_Cpp a monster that no one likes but that will outlast them all _Ya...
GECon2017_Cpp  a monster that no one likes but that will outlast them all _Ya...GECon2017_Cpp  a monster that no one likes but that will outlast them all _Ya...
GECon2017_Cpp a monster that no one likes but that will outlast them all _Ya...
 
GECon 2017: C++ - a Monster that no one likes but that will outlast them all
GECon 2017: C++ - a Monster that no one likes but that will outlast them allGECon 2017: C++ - a Monster that no one likes but that will outlast them all
GECon 2017: C++ - a Monster that no one likes but that will outlast them all
 
C++: Constructor, Copy Constructor and Assignment operator
C++: Constructor, Copy Constructor and Assignment operatorC++: Constructor, Copy Constructor and Assignment operator
C++: Constructor, Copy Constructor and Assignment operator
 
New C# features
New C# featuresNew C# features
New C# features
 
greenDAO
greenDAOgreenDAO
greenDAO
 
C to perl binding
C to perl bindingC to perl binding
C to perl binding
 
CPP Language Basics - Reference
CPP Language Basics - ReferenceCPP Language Basics - Reference
CPP Language Basics - Reference
 
Day 1
Day 1Day 1
Day 1
 
Functional C++
Functional C++Functional C++
Functional C++
 
The STL
The STLThe STL
The STL
 
Dynamic C++ Silicon Valley Code Camp 2012
Dynamic C++ Silicon Valley Code Camp 2012Dynamic C++ Silicon Valley Code Camp 2012
Dynamic C++ Silicon Valley Code Camp 2012
 
What's new in C# 6 - NetPonto Porto 20160116
What's new in C# 6  - NetPonto Porto 20160116What's new in C# 6  - NetPonto Porto 20160116
What's new in C# 6 - NetPonto Porto 20160116
 
I want help in the following C++ programming task. Please do coding .pdf
I want help in the following C++ programming task. Please do coding .pdfI want help in the following C++ programming task. Please do coding .pdf
I want help in the following C++ programming task. Please do coding .pdf
 
ECMAScript 5: Новое в JavaScript
ECMAScript 5: Новое в JavaScriptECMAScript 5: Новое в JavaScript
ECMAScript 5: Новое в JavaScript
 
Oops presentation
Oops presentationOops presentation
Oops presentation
 
Getting started with ES6
Getting started with ES6Getting started with ES6
Getting started with ES6
 
Arquitetura Java em 2007 (Java Architecture in 2007)
Arquitetura Java em 2007 (Java Architecture in 2007)Arquitetura Java em 2007 (Java Architecture in 2007)
Arquitetura Java em 2007 (Java Architecture in 2007)
 

More from Alexander Granin

Concurrent applications with free monads and stm
Concurrent applications with free monads and stmConcurrent applications with free monads and stm
Concurrent applications with free monads and stmAlexander Granin
 
Hierarchical free monads and software design in fp
Hierarchical free monads and software design in fpHierarchical free monads and software design in fp
Hierarchical free monads and software design in fpAlexander Granin
 
Final tagless vs free monad
Final tagless vs free monadFinal tagless vs free monad
Final tagless vs free monadAlexander Granin
 
The present and the future of functional programming in c++
The present and the future of functional programming in c++The present and the future of functional programming in c++
The present and the future of functional programming in c++Alexander Granin
 
О разработке десктопных приложений / About desktop development
О разработке десктопных приложений / About desktop developmentО разработке десктопных приложений / About desktop development
О разработке десктопных приложений / About desktop developmentAlexander Granin
 
Принципы и практики разработки ПО 2 / Principles and practices of software de...
Принципы и практики разработки ПО 2 / Principles and practices of software de...Принципы и практики разработки ПО 2 / Principles and practices of software de...
Принципы и практики разработки ПО 2 / Principles and practices of software de...Alexander Granin
 
Принципы и практики разработки ПО / Principles and practices of software deve...
Принципы и практики разработки ПО / Principles and practices of software deve...Принципы и практики разработки ПО / Principles and practices of software deve...
Принципы и практики разработки ПО / Principles and practices of software deve...Alexander Granin
 
Закон Деметры / Demetra's law
Закон Деметры / Demetra's lawЗакон Деметры / Demetra's law
Закон Деметры / Demetra's lawAlexander Granin
 
Design of big applications in FP
Design of big applications in FPDesign of big applications in FP
Design of big applications in FPAlexander Granin
 
GitHub - зеркало разработчика
GitHub - зеркало разработчикаGitHub - зеркало разработчика
GitHub - зеркало разработчикаAlexander Granin
 
The Present and The Future of Functional Programming in C++
The Present and The Future of Functional Programming in C++The Present and The Future of Functional Programming in C++
The Present and The Future of Functional Programming in C++Alexander Granin
 
Functional programming in C++ LambdaNsk
Functional programming in C++ LambdaNskFunctional programming in C++ LambdaNsk
Functional programming in C++ LambdaNskAlexander Granin
 
Transition graph using free monads and existentials
Transition graph using free monads and existentialsTransition graph using free monads and existentials
Transition graph using free monads and existentialsAlexander Granin
 
Software transactional memory. pure functional approach
Software transactional memory. pure functional approachSoftware transactional memory. pure functional approach
Software transactional memory. pure functional approachAlexander Granin
 
Вы не понимаете ФП / You don't understand FP
Вы не понимаете ФП / You don't understand FPВы не понимаете ФП / You don't understand FP
Вы не понимаете ФП / You don't understand FPAlexander Granin
 
Functional "Life": parallel cellular automata and comonads
Functional "Life": parallel cellular automata and comonadsFunctional "Life": parallel cellular automata and comonads
Functional "Life": parallel cellular automata and comonadsAlexander Granin
 
Дизайн больших приложений в ФП
Дизайн больших приложений в ФПДизайн больших приложений в ФП
Дизайн больших приложений в ФПAlexander Granin
 
Линзы - комбинаторная манипуляция данными
Линзы - комбинаторная манипуляция даннымиЛинзы - комбинаторная манипуляция данными
Линзы - комбинаторная манипуляция даннымиAlexander Granin
 
Линзы - комбинаторная манипуляция данными (Dev2Dev)
Линзы - комбинаторная манипуляция данными (Dev2Dev)Линзы - комбинаторная манипуляция данными (Dev2Dev)
Линзы - комбинаторная манипуляция данными (Dev2Dev)Alexander Granin
 

More from Alexander Granin (20)

Concurrent applications with free monads and stm
Concurrent applications with free monads and stmConcurrent applications with free monads and stm
Concurrent applications with free monads and stm
 
Hierarchical free monads and software design in fp
Hierarchical free monads and software design in fpHierarchical free monads and software design in fp
Hierarchical free monads and software design in fp
 
Final tagless vs free monad
Final tagless vs free monadFinal tagless vs free monad
Final tagless vs free monad
 
Monadic parsers in C++
Monadic parsers in C++Monadic parsers in C++
Monadic parsers in C++
 
The present and the future of functional programming in c++
The present and the future of functional programming in c++The present and the future of functional programming in c++
The present and the future of functional programming in c++
 
О разработке десктопных приложений / About desktop development
О разработке десктопных приложений / About desktop developmentО разработке десктопных приложений / About desktop development
О разработке десктопных приложений / About desktop development
 
Принципы и практики разработки ПО 2 / Principles and practices of software de...
Принципы и практики разработки ПО 2 / Principles and practices of software de...Принципы и практики разработки ПО 2 / Principles and practices of software de...
Принципы и практики разработки ПО 2 / Principles and practices of software de...
 
Принципы и практики разработки ПО / Principles and practices of software deve...
Принципы и практики разработки ПО / Principles and practices of software deve...Принципы и практики разработки ПО / Principles and practices of software deve...
Принципы и практики разработки ПО / Principles and practices of software deve...
 
Закон Деметры / Demetra's law
Закон Деметры / Demetra's lawЗакон Деметры / Demetra's law
Закон Деметры / Demetra's law
 
Design of big applications in FP
Design of big applications in FPDesign of big applications in FP
Design of big applications in FP
 
GitHub - зеркало разработчика
GitHub - зеркало разработчикаGitHub - зеркало разработчика
GitHub - зеркало разработчика
 
The Present and The Future of Functional Programming in C++
The Present and The Future of Functional Programming in C++The Present and The Future of Functional Programming in C++
The Present and The Future of Functional Programming in C++
 
Functional programming in C++ LambdaNsk
Functional programming in C++ LambdaNskFunctional programming in C++ LambdaNsk
Functional programming in C++ LambdaNsk
 
Transition graph using free monads and existentials
Transition graph using free monads and existentialsTransition graph using free monads and existentials
Transition graph using free monads and existentials
 
Software transactional memory. pure functional approach
Software transactional memory. pure functional approachSoftware transactional memory. pure functional approach
Software transactional memory. pure functional approach
 
Вы не понимаете ФП / You don't understand FP
Вы не понимаете ФП / You don't understand FPВы не понимаете ФП / You don't understand FP
Вы не понимаете ФП / You don't understand FP
 
Functional "Life": parallel cellular automata and comonads
Functional "Life": parallel cellular automata and comonadsFunctional "Life": parallel cellular automata and comonads
Functional "Life": parallel cellular automata and comonads
 
Дизайн больших приложений в ФП
Дизайн больших приложений в ФПДизайн больших приложений в ФП
Дизайн больших приложений в ФП
 
Линзы - комбинаторная манипуляция данными
Линзы - комбинаторная манипуляция даннымиЛинзы - комбинаторная манипуляция данными
Линзы - комбинаторная манипуляция данными
 
Линзы - комбинаторная манипуляция данными (Dev2Dev)
Линзы - комбинаторная манипуляция данными (Dev2Dev)Линзы - комбинаторная манипуляция данными (Dev2Dev)
Линзы - комбинаторная манипуляция данными (Dev2Dev)
 

Recently uploaded

Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...panagenda
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionSolGuruz
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxComplianceQuest1
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsJhone kinadey
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...Health
 
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceCALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceanilsa9823
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...kellynguyen01
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsAndolasoft Inc
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AIABDERRAOUF MEHENNI
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 

Recently uploaded (20)

Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceCALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 

Functional microscope - Lenses in C++

  • 1. Functional Microscope: Lenses in С++ Alexander Granin graninas@gmail.com C++ Siberia, Novosibirsk
  • 2. Me? ● C++, Haskell, C# ● C++ User Group Novosibirsk, 2014 ● Talks, articles, FP evangelism... ● LambdaNsk - Novosibirsk FP-community ● Kaspersky Lab
  • 3. struct Presentation { FP in C++?.. Functional Lenses cpp_lenses library };
  • 5. С++ User Group Novosibirsk, 2014
  • 6. FP concepts in C++ ● Lambdas, closures, functions (almost pure) ● Immutability, POD-types ● Templates - pure functional language ● FTL - Functional Template Library ● Initialization lists ● for_each(), recursion
  • 8. 8 Matryoshka struct Account { Person person; }; struct Person { Address address; }; struct Address { std::string street; int house; int flat; };
  • 9. 9 Mutable variables... void setStreet(Account& account, const std::string& newStreet) { account.person.address.street = newStreet; }
  • 10. 10 void setStreet(Account& account, const std::string& newStreet) { account.person.address.street = newStreet; } Mutable variables... ● Easy to break the client code ● Demetra law is violated ● Highly specific code ● Boilerplate
  • 11. 11 Mutable state... void Account::setStreet(const std::string& newStreet) { this->person.address.street = newStreet; }
  • 12. 12 Mutable state... void Account::setStreet(const std::string& newStreet) { this->person.address.street = newStreet; } ● Demetra law is violated ● Highly specific code ● Mixing of different layers ● SRP is violated ● Not a POD type
  • 13. 13 Account setStreet(Account account, const std::string& newStreet) { account.person.address.street = newStreet; return account; } Immutable approach…
  • 14. 14 Account setStreet(Account account, const std::string& newStreet) { account.person.address.street = newStreet; return account; } Immutable approach… Not so good. ● Easy to break the client code ● Demetra law is violated ● Highly specific code ● Boilerplate
  • 15. Ok, Lenses! auto lens = zoom(personLens, addressLens, streetLens); auto newAccount = set(lens, oldAccount, std::string("New street")); ● “Focused” internal element of the structure ● Do something with the element from outside ● Hiding data structure realization ● Fully immutable, composable and reusable
  • 16. Ok, Lenses! auto lens = zoom(personLens, addressLens, streetLens); auto newAccount = set(lens, oldAccount, std::string("New street")); So, how does this work?
  • 17. Open matryoshka, pull out matryoshka... Account account = {...}; Person person = getPerson(account); Address address = getAddress(person); std::string street = getStreet(address); std::string newStreet = "Churchill's " + street; Address newAddress = setStreet(address, newStreet); Person newPerson = setAddress(person, newAddress); Account newAccount = setPerson(account, newPerson);
  • 18. Person getPerson(const Account& account) { return account.person; } Account setPerson(Account account, const Person& person) { account.person = person; return account; } getA(), setA()
  • 19. auto getPerson = [](const Account& account) { return account.person; }; auto setPerson = [](Account account, const Person& person) { account.person = person; return account; }; Getter, Setter
  • 20. auto getPerson = [](const Account& account) { return account.person; }; auto setPerson = [](Account account, const Person& person) { account.person = person; return account; }; Getter, Setter std::function<Focus(Value)> getter; std::function<Value(Value, Focus)> setter;
  • 21. template <typename Value, typename Focus> struct Lens { std::function<Focus(Value)> getter; std::function<Value(Value, Focus)> setter; }; Lens<Account, Person> personLens = { getPerson, setPerson }; Lens = Getter + Setter
  • 22. view template <typename Value, typename Focus> Focus view(const Lens<Value, Focus>& lens, const Value& value) { return lens.getter(value); } Lens<Account, Person> personLens = { getPerson, setPerson }; Person person = view(personLens, someAccount);
  • 23. set template <typename Value, typename Focus> Value set(const Lens<Value, Focus>& lens, const Value& value, const Focus& newFocus) { return l.setter(value, newFocus); } Lens<Account, Person> personLens = { getPerson, setPerson }; Person person = view(personLens, someAccount); Account newAccount = set(personLens, account, Person(”Santa”, ”Claus”));
  • 24. Lens composition is Lens too Lens<Account, Person> personLens = { getPerson, setPerson }; Lens<Person, Address> addressLens = { getAddress, setAddress }; Lens<Address, std::string> streetLens = { getStreet, setStreet }; auto lens = zoom(personLens, addressLens, streetLens); // Magic zoom! Account newAccount = set(lens, someAccount, std::string(”Churchill's”));
  • 25. Lens composition is Lens too Lens<Account, Person> personLens = { getPerson, setPerson }; Lens<Person, Address> addressLens = { getAddress, setAddress }; Lens<Address, std::string> streetLens = { getStreet, setStreet }; auto lens = zoom(personLens, addressLens, streetLens); // Magic zoom! // getPerson, getAddress, setStreet, setAddress, setPerson Account newAccount = set(lens, someAccount, std::string(”Churchill's”));
  • 27. Manual lenses template <typename Value, typename Focus> Lens<Value, Focus> lens(const std::function<Focus(Value)>& getter, const std::function<Value(Value, Focus)>& setter) { Lens<Value, Focus> l; l.getter = getter; l.setter = setter; return l; } auto personL = lens<Account, Person>( [](const Account& a) { return a.person; }, [](Account a, const Person& p) { a.person = p; return a; });
  • 28. Autolenses struct Account { Person person; std::string login; std::string password; }; #define MK_LENS(A, B, member) Lens<A, B> member##L() { return lens<A, B> ( GETTER(A, member), SETTER(A, B, member)); } MK_LENS(Account, Person, person) // personL() MK_LENS(Account, std::string, login) // loginL() MK_LENS(Account, std::string, password) // passwordL()
  • 29. zoom Lens<A, B> lens = aToB; ???<A, B, C> lens = zoom(aToB, bToC); ???<A, B, C, D> lens = zoom(aToB, bToC, cToD);
  • 30. zoom (not generic) -> LensStack Lens<A, B> lens = aToB; LensStack<A, B, C> lens = zoom(aToB, bToC); LensStack<A, B, C, D> lens = zoom(aToB, bToC, cToD); template <typename A, typename B, typename C> LensStack<A, B, C> zoom(...) { … } template <typename A, typename B, typename C, typename D> LensStack<A, B, C, D> zoom(...) { ... }
  • 31. LensStack (not generic) template <typename A, typename B, typename C = Id, typename D = Id> struct LensStack { Lens<A, B> lens1; Lens<B, C> lens2; Lens<C, D> lens3; }; LensStack<A, B, C> lens = zoom(aToB, bToC); // OK LensStack<A, B, C, D> lens = zoom(aToB, bToC, cToD); // OK LensStack<A, B, C, D, E> lens = zoom(aToB, bToC, cToD, dToE); // Ooops!
  • 32. LensStack: Variadic Templates + magic template<typename L, typename... Tail> struct LensStack<L, Tail...> : LensStack<Tail...> { typedef LensStack<Tail...> base_type; LensStack(L lens, Tail... tail) : LensStack<Tail...>(tail...) , m_lens(lens) {} base_type& m_base = static_cast<base_type&>(*this); L m_lens; };
  • 33. Infix literal `to` combinator! auto lens1 = addressL to houseL; auto lens2 = personL to lens1; auto lens3 = aL to bL to cL to dL to … to theLastOneLens; auto lens = (a to b) to c; // OK, left-associative auto lens = a to (b to c); // Error
  • 34. `to`: proxy + overloading + reroll stack struct Proxy {...} proxy; template <typename L1, typename L2> LensStack<Lens<L1, L2>> operator<(const Lens<L1, L2>& lens, const Proxy&) { return LensStack<Lens<L1, L2>>(lens); } template <typename LS, typename L> typename LS::template reroll_type<L> operator>(const LS& stack, const L& lens) { return stack.reroll(lens); } // `Infix literal operator` trick #define to < proxy >
  • 35. set auto lens = personL() to addressL() to houseL(); Account account1 = {...}; Account account2 = set(lens, account1, 20); // house == 20
  • 36. set, over auto lens = personL() to addressL() to houseL(); Account account1 = {...}; Account account2 = set(lens, account1, 20); // house == 20 std::function<int(int)> modifier = [](int old) { return old + 6; }; Account account3 = over(lens, account2, modifier); // house == 26
  • 37. What about containers? struct Car { std::string model; }; std::vector<Car> cars = { Car{"Ford Focus"}, Car{"Toyota Corolla"} };
  • 38. toListOf * struct Car { std::string model; }; std::vector<Car> cars = { Car{"Ford Focus"}, Car{"Toyota Corolla"} }; std::list<std::string> result = toListOf(folded<Car>() to modelL(), cars); // result: {"Ford Focus", "Toyota Corolla"} * toListOf() and folded<T>() is a hack now, sorry...
  • 39. traversed struct Account { Person person; }; struct Person { std::vector<Car> cars; }; struct Car { std::string model; int number; }; auto toCarL = personL() to carsL() to traversed<Car>();
  • 40. traversed + set struct Account { Person person; }; struct Person { std::vector<Car> cars; }; struct Car { std::string model; int number; }; auto toCarL = personL() to carsL() to traversed<Car>(); Account newAccount1 = set(toCarL to modelL(), oldAccount, std::string(“Toyota”));
  • 41. traversed + over struct Account { Person person; }; struct Person { std::vector<Car> cars; }; struct Car { std::string model; int number; }; auto toCarL = personL() to carsL() to traversed<Car>(); Account newAccount1 = set(toCarL to modelL(), oldAccount, std::string(“Toyota”)); std::function<std::string(std::string)> modifier = [](int old) { return old + 6; }; Account newAccount2 = over(toCarL to numberL(), newAccount1, modifier);
  • 42. traversed + traversed! struct Account { Person person; }; struct Person { std::vector<Car> cars; }; struct Car { std::string model; int number; std::list<std::string> accessories; }; auto toAccessoryL = personL() to carsL() to traversed<Car>() to accessoriesL() to traversed<std::string>();
  • 43. cpp_lenses library ● Highly experimental ● Done: composing; set, view, over, traverse ● TODO: filter, traverse++, fold, prisms, fusion… ● TODO: clean it, make it wise, short and robust ● github.com/graninas/cpp_lenses
  • 44. ● Complex structures processing ● Test data preparation ● Some XPath, LINQ analogue ● Functional approach ● Much better than just <algorithm> ● ...Why not? Functional C++ is reality coming now Why lenses in C++?
  • 45. Thank you! Alexander Granin graninas@gmail.com Any questions? C++ Siberia, Novosibirsk
  • 46. Rerolling LensStack template<typename L1, typename... Tail> struct LS<L1, Tail...> : LS<Tail...> { template <typename Reroll, typename Lx> void reroll_(Reroll& rerolled, const Lx& lx) const { rerolled.m_lens = m_lens; base.reroll_(rerolled.base, lx); } template <typename Lx> LensStack<L1, Tail..., Lx> reroll(const Lx& lx) const { LensStack<L1, Tail..., Lx> rerolled; rerolled.m_lens = m_lens; base.reroll_(rerolled.base, lx); return rerolled; } } // Recursion base template <typename... Tail> struct LensStack { template <typename Reroll, typename Lx> void reroll_(Reroll& rerolled, const Lx& lx) { rerolled.m_lens = lx; } };