From 5cd71544b876818db2db58f7fb0344995aa33669 Mon Sep 17 00:00:00 2001 From: Robert Douglas Date: Tue, 5 Dec 2023 13:52:05 -0600 Subject: [PATCH] WIP --- sources/modules/functions/lambdas.md | 78 ++++++++++++++++++++++++---- 1 file changed, 67 insertions(+), 11 deletions(-) diff --git a/sources/modules/functions/lambdas.md b/sources/modules/functions/lambdas.md index d74b1aa..9516b8e 100644 --- a/sources/modules/functions/lambdas.md +++ b/sources/modules/functions/lambdas.md @@ -54,11 +54,13 @@ _Max 5 items._ A student should be able to: -1. Use a lambda taking a concrete type as a parameter and return a value in response -2. -3. -4. -5. +1. Use a lambda taking a concrete type as a parameter and return a value +2. transform a function definition into a lambda and use it +3. enumerate trade-offs of code-locality using lambdas vs code reuse with free-functions +4. assign a lambda to a variable for multiple calls +5. named lambdas to increase code readability + + #### Caveats @@ -79,14 +81,62 @@ _This section lists important details for each point._ A student should be able to: -1. Utilize std::function as a means to hold and transfer lambdas +1. Utilize `std::function` as a means to hold and transfer lambdas 2. Define a function-template taking a lambda as a template parameter -3. Use captures to change +3. specify, per parameter, whether to capture by reference or value +4. specify the default capture type for a lambda +5. use a lambda in a class, capturing and utilizing class data via `this` + +#### Caveats + +#### Points to cover + +motivation: +1. how to write library code to call user code? --- callbacks +2. root finding using lambdas +3. "customizing" generic algorithms + +### Advanced +Explain why they can't write out the type of a lambda? +_These are important topics that are not expected to be covered but provide +guidance where one can continue to investigate this topic in more depth._ + + +#### Background/Required Knowledge + +* All of the above. +#### Student outcomes + +A student should be able to: + +1. Use a lambda to introduce a new identifier for use within the body of the lambda +2. explain the relationships between generic lambdas and templates +3. construct an object with choice between 2 identifiers, using immediately-dispathced lambda +4. utilize an immediately dispatched lambda to encode multiple statements where the language requires an expression +5. use the `mutable` keyword to allow changing a captured-by-value or lambda-local value within the lambda body +6. explicitly specify the return type for a lambda +7. explain under what conditions an explicit return type is necessary + #### Caveats #### Points to cover +Construct an object with choice between 2 identifiers: +``` +class X; +bool b; +X x = [c = b](){ if (c) return X(5, 10) else X("a", "b"); }(); +``` + +multiple statements in a single expression +``` +assert([](){ + std::vector v{1, 2, 3, 4, 5}; + for (auto x: v) std::cout << v << std::endl; +}()); +``` + Capture can introduce new names ``` char const* const s = "5"; @@ -96,6 +146,9 @@ char const* const s = "5"; ``` std::ranges::for_each( std::vector{1,2,3,4,5}, + // introducing new identifier + // generic lambda + // mutable allows changing "init" [init = true] (auto&& x) mutable { if (init) { std::cout << x; init = false}; @@ -104,7 +157,10 @@ std::ranges::for_each( }); ``` -### Advanced -Explain why they can't write out the type of a lambda? -_These are important topics that are not expected to be covered but provide -guidance where one can continue to investigate this topic in more depth._ +When to use lambdas or not: +forcing code into a lambda can prevent some features +``` +std::for_each(std::par_sec, v, [](){/* can't utilize OpenMP here */}}; +for(auto i : v){ /* OpenMP can be utilized here */ } +``` +