On Writing Loops in PPL and Continuation-passing Style, Part 3 -- Raymond Chen

RaymondChen_5in-150x150.jpgIn our previous discussion, we optimized a task-based while loop by eliminating nested shared pointers, instead requiring all the state to reside inside a caller-provided shared_ptr, making the callable stateless. This approach simplifies the code and reduces redundancy in managing state.

On Writing Loops in PPL and Continuation-passing Style, Part 3

By Raymond Chen

From the article:

Last time, we wrote a task-based while loop using recursion, using a shared_ptr to pass state, and we noted a redundancy in that we created a shared_ptr to a lambda that in turn held a shared_ptr.

We can eliminate the nested shared pointers by requiring that all the state live inside a caller-provided shared_ptr, levaing the callable stateless.

template<typename State>
task<void> do_while_task(
    std::shared_ptr<State> const& state,
    bool (*f)(std::shared_ptr<State> const&)
{
    return f(state).then([state, f](bool loop) {
        return loop ? do_while_task(state, f) :
                      task_from_result();
    });
}

struct lambda_state
{
    lambda_state(Widgets* w) : widgets(w) {}
    Widgets* widgets;
    int i = 0;
};

auto state = std::make_shared<lambda_state>(widgets);

do_while_task(state, [](auto&& state)
{
    if (state->i >= 3) return task_from_result(false);
    return create_widget().then([state](auto widget)
    {
        state->widgets[state->i] = widget;
        state->i++;
        return true;
    }
}).then([] {
    printf("Done!\n");
});

We can get rid of all the state-> prefixes by making the state be invocable.

CopperSpice: Time to Sort Out std::chrono

New video on the CopperSpice YouTube Channel:

Time to Sort Out std::chrono

by Barbara Geller and Ansel Sermersheim

About the video:

We just posted a new video about std::chrono. It provides an overview of the functionality which was added in C++11, C++17, and C++20. Please watch to find out how much of std::chrono your compiler actually supports. We were pretty surprised at what we discovered.

Please take a look and remember to subscribe.

ACCU 2024 Call for Speakers -- ACCU

The ACCU is now putting together its program, and they want you to speak on C++. The ACCU conference has strong C++ tracks, though it is not a C++-only conference. If you have something to share, check out their

Call for Speakers

by ACCU 

About the conference:

The ACCU Conference is the annual conference of the ACCU membership, but is open to any and all who wish to attend. The tagline for the ACCU is "Professionalism in Programming", which captures the whole spectrum of programming languages, tools, techniques and processes involved in advancing our craft. While there remains a core of C and C++ - with many members participating in respective ISO standards bodies - the conference, like the organisation, embraces other language ecosystems and you should expect to see sessions on C#, D, F#, Go, Javascript, Haskell, Java, Kotlin, Lisp, Python, Ruby, Rust, Swift and more. There are always sessions on TDD, BDD, and how to do programming right.

The ACCU Conference is a conference by programmers for programmers about programming.

The Call For Speakers will remain open until midnight (GMT) on 17th November 2023.

WG21 Varna Trip Report -- David Sankel

David Sankel discusses about the developments at the June 2023 ISO C++ standardization meeting in Varna.

WG21 Varna Trip Report

by David Sankel

About the report:

In detail he speakes about std::simd, std::inplace_vector, and other developments.

Beautiful C++: 30 Core Guidelines... Book Review -- Bartlomiej Filipek

beautiful_cpp.jpgThis is a book review of “Beautiful C++,” written by two well-known C++ experts and educators: Kate Gregory and Guy Davidson. The book’s unique style gives us a valuable perspective on effective and safe C++ code.

Beautiful C++: 30 Core Guidelines... Book Review

By Bartlomiej Filipek

From the review:

The book is split into five parts, and each part has six guidelines to help us understand the material more easily.

  • Part one: Bikeshedding is bad - how to reduce the number of lines of your code and simplify it. For example, by using use in-class member initializers or avoiding getters and setters.
  • Part two: Don’t hurt yourself - how to avoid messy code and minimize complexity. For example, by limiting explicit sharing of variables, proper use of ABI and more.
  • Part three: Stop using that - some important bugs and bad C++ code style: singletons, casting away const or unsafe managing the ownership of resources.
  • Part four: Use this new thing properly - efficient use of modern C++ style: enum classes, constexpr, templates.
  • Part five: Write code well by default - good patterns for your code: type safety, immutable data structures avoiding uninitialized variables, and RAII.

In total, it’s around 300 pages + afterword and index.

If we look at a corresponding guideline like I.3: Avoid singletons you’ll see a short paragraph of introduction, some small example and a short discussion to alternatives. On the other hand, in the book, this guideline consists of 9 pages with unique examples, backstories, alternatives and discussions. The section shows things like:

  • Why global objects are bad
  • Singleton Design pattern overview
  • Static initialization order fiasco
  • Hiding singletons and making a namespace rather than a class
  • And even how to use constexpr in some cases (constexpr is also covered in other sections)

On Writing Loops in PPL and Continuation-passing Style, Part 2 -- Raymond Chen

RaymondChen_5in-150x150.jpgIn our previous discussion, we explored a task-based while loop employing custom callables that passed copies of themselves to the next iteration, which follows the continuation-passing style used in the Parallel Patterns Library (PPL). In this session, we will implement the same function using a more traditional recursive approach, aiming to simplify the sharing of state between lambda callables in PPL-style programming.

On Writing Loops in PPL and Continuation-passing Style, Part 2

By Raymond Chen

From the article:

Last time, we came up with task-based while loop that involved creating a custom callable that passed copies of itself to the next iteration.

This time, we’ll implement the function in terms of a more traditional recursion.

template<typename Callable>
task<void> do_while_task(
    std::shared_ptr<Callable> const& f)
{
    return (*f)().then([f](bool loop) {
        return loop ? do_while_task(f) :
                      task_from_result();
    });
}

template<typename Callable, typename =
    std::enable_if_t<std::is_invocable_v<Callable>>>
task<void> do_while_task(Callable&& callable)
{
    using Decayed = std::decay_t<Callable>;
    return do_while_task(
        std::make_shared<Decayed>(
            std::forward<Callable>(callable)));
}

The real work happens in the first overload, which takes a ready-made shared_ptr. The second overload is a convenience method that lets you pass a callable, and it will wrap it in a shared_ptr for you.

Meeting C++ 2023 is streaming all tracks from Berlin

Meeting C++ 2023 will stream all keynotes and talks from Berlin to the online world. After the conference all livestreams will be available in the online platform to all attendees.

Streaming all talks from Berlin

by Jens Weller

From the article:

Quickly announcing that you can see all the talks at Meeting C++ 2023!

You still have this and next week to get your tickets for Meeting C++ 2023, which enables you to either see the talks live in Berlin or watch online! This has been an important goal for this year: make all tracks available to the online conference once we return to be onsite again. Last year has shown that the online conference adds great value to the C++ community in giving folks access to talk that other wise would be only seen by a small group in Berlin.

On Writing Loops in PPL and Continuation-passing Style, Part 1 -- Raymond Chen

RaymondChen_5in-150x150.jpgThe Parallel Patterns Library (PPL) relies on a continuation-passing style for asynchronous programming, where tasks are invoked and then linked to callable objects that process their results. This approach was the primary method for handling asynchronous operations before the introduction of await and co_await keywords in C#, JavaScript, and C++, making it essential to understand for developers working with older code or scenarios that still employ this style.

On Writing Loops in PPL and Continuation-passing Style, Part 1

By Raymond Chen

From the article:

The Parallel Patterns Library (PPL) is based on a continuation-passing style, where you invoke a task, and then attach a callable object that will be given the result. Prior to the introduction of the await and co_await keywords to C#, JavaScript, and C++, this was your only real choice for asynchronous programming.

Sequential calculations are fairly straightforward in continuation-passing style because you just pass the next step as the continuation.

// Synchronous version
auto widget = find_widget(name);
auto success = widget.toggle();
if (!success) report_failure();

// Asynchronous version
find_widget(name).then([=](auto widget) {
    return widget.toggle();
}).then([=](auto success) {
    if (!success) report_failure();
});

Iteration is harder to convert to continuation-passing style because you need to restart the task chain, which means you have recursion.