Question? Leave a message!




THE WAYS TO AVOID COMPLEXITY IN MODERN C++

THE WAYS TO AVOID COMPLEXITY IN MODERN C++ 33
DannyConnolly Profile Pic
DannyConnolly,Switzerland,Professional
Published Date:14-07-2017
Website URL
Comment
1 VICTOR A. LASKIN, 2015 THE WAYS TO AVOID COMPLEXITY IN MODERN C++2 INTRO PERFECTION IS ACHIEVED NOT WHEN THERE IS NOTHING MORE TO ADD, BUT WHEN THERE IS NOTHING MORE TO TAKE AWAY. -Antoine de Saint Exupery3 INTRO WHAT THE PROBLEM? Programmers tend to write ▸ complicated solutions as they see it as part of creativity. C++ is so flexible… ▸ It’s actually easy to produce ▸ ‘complex’ spaghetti architecture.4 INTRO WHAT THE PROBLEM - PART 2 During developer’s life we get used to apply same ‘not perfect’ solutions over ▸ and over so they start to seem simple to us. We use libs. As libs often want to cover wide range of cases - their interfaces ▸ become not so simple as they could be. Copy-paste does not simplify things. ▸5 OVER TIME ENTROPY OF PROJECT IS GROWING…6 INTRO OBVIOUS WAY - TRY TO MAKE IT “SIMPLE” “Fighting complexity” as true way of ▸ experienced developer “make simple things simple” Bjarn ▸ So this presentation is about the ways to do it ▸7 IDEA SO THE IDEA IS TO GATHER C++11/14’S POWER TO CREATE NEW WAYS / FUNCTIONAL INSTRUMENTS / TOOLS, ETC TO PRODUCE MORE PERFECT CODE8 INTRO PRINCIPLE WAYS TO ACHIVE SIMPLICITY Organize (classifications, patterns, GOF, etc) ▸ Hide/encapsulate (OOP - Hide complexity) ▸ Divide (factorization) ▸ Reduce/Eliminate (Occam’s razor) ▸ Speed up ▸ Combine, reuse (create tools). Extract functionality. ▸9 SIMPLE RULES THIS LINE IS ENOUGH REASON TO SWITCH TO C++11 for(auto item : list) ... Avoid non-ranged cycles - use them only at low algorithmic layer ▸10 SIMPLE RULES DONT USE NEW/DELETE - ONLY RAII & SMART POINTERS Use RAII where it’s possible ▸ Use smart-pointers where you absolutely can’t use RAII ▸ DON’T USE new/delete ▸ Use make_shared to allocate shared_ptr ▸11 SIMPLE RULES USE CONST WHERE ITS POSSIBLE Less chance to make logic mistake, complex workflow or produce corrupted ▸ state Not only data: mark methods as const ▸ Immutable data paradigm from functional programming will be discussed ▸ further12 SIMPLE RULES AUTO Auto gives a way to save A LOT OF SPACE ▸ Places where a lot of autos decreases readability are rare ▸ Avoid type casting mistakes ▸ Return type detection (C++14) - saves a lot of space ▸ Polymorfic lambdas ▸13 SIMPLE RULES USE LAMBDAS / STD::FUNCTION Every non trivial system has need for event handlers, etc - C++11 has not so bad ▸ syntax to live with Don’t be afraid of unreadable lambda hell (JS) ▸ Use structured approach to work with lamdas ▸ Everywhere when you want to create new class: think - may be it’s just simple ▸ function? Messaging architectures, Distributed systems - place code where it should be ▸ located, not where you forced to write it14 FUNCTIONAL PROGRAMMING WHY FUNCTIONAL PROGRAMMING? Where is simplicity here? ▸ Pure functions ARE SIMPLE ▸ Immutable state is simple ▸ Math-like data processing is easy write and read ▸ Easy to build concurrent/distributed systems ▸ C++11/14 is functional enough ▸15 IMMUTABLE DATA IMMUTABLE DATA Immutable data concept is SIMPLE ▸ Stateless - no errors ▸ No problem of inconsistent data (requires full construction) ▸ Perfect for data processing, especially inside pure functions: y = f(x) ▸ Perfect for concurrency, distributed systems ▸ Share same data over std::shared_ptr ▸16 IMMUTABLE DATA POSSIBLE IMPLEMENTATION True CONSTs ▸ JSON serialization ▸ class EventData : public IImmutable public: const int id; const string title; const double rating; SERIALIZE_JSON(EventData, id, title, rating); ; using Event = EventData::Ptr; 17 IMMUTABLE DATA MORE REALISTIC DATA - NESTED JSON SERIALIZATION class ScheduleItemData : public IImmutable public: const time_t start; const time_t finish; SERIALIZE_JSON(ScheduleItemData, start, finish); ; using ScheduleItem = ScheduleItemData::Ptr; class EventData : public IImmutable public: const int id; const string title; const double rating; const vectorScheduleItem schedule; const vectorint tags; SERIALIZE_JSON(EventData, id, title, rating, schedule, tags); ; using Event = EventData::Ptr;18 IMMUTABLE DATA SIMPLE USAGE Event event = EventData(136, "Nice event", 4.88, ScheduleItemData(1111,2222), ScheduleItemData(3333,4444), 45,323,55); // serialisation string json = event-toJSON(); // deserialisation Event eventCopy = EventData::fromJSON(json); // How to "set" fields Event anotherEvent = event-set_rating(3.56); Implementation details - http://vitiy.info/immutable-data-and-serialisation-in-cpp11/19 FUNCTIONAL DATA PROCESSING DATA PROCESSING Filter, map, reduce - simple blocks to build functional data processing ▸ Factorisation Gives ability to extract iterations into utility functors ▸ Using C++11 it’s easy to implement such functional utils ▸ More compact code ▸ Easy to write ▸ Easy to read ▸20 FUNCTIONAL DATA PROCESSING CHANGE THE WAY OF THINKING - PART 1 Let’s say we want to compute y=f(a,b) ▸ f b C a C - accumulator of parts - f,a,b, which can come in any order ▸