-
Notifications
You must be signed in to change notification settings - Fork 15
Introduction to lambdas #25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
A tutorial explaining lambdas.
src/resources/cpp/lambdas.md
Outdated
|
||
## What is a lambda? | ||
|
||
Lambdas are similar to function, however they are not identical they specifically are [closures](https://en.wikipedia.org/wiki/Closure_(computer_programming)) what might be a term you are familiar with from other languages. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"function" should be plural, and there are a few English mistakes here.
src/resources/cpp/lambdas.md
Outdated
|
||
Lambdas are similar to function, however they are not identical they specifically are [closures](https://en.wikipedia.org/wiki/Closure_(computer_programming)) what might be a term you are familiar with from other languages. | ||
|
||
if they are similar to functions one might ask why would I ever need a lambda? They have multiple usages but the simplest and most common one is for predicates in algorithms. Algorithms are nice and generic and you want their behavior to be slightly different depending on your specific use case. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Name-dropping "predicates" may be a bit demanding. This is mathematical lingo.
In general, I think this article needs a strong motivating example as early as possible, prior to any lingo. Something like:
For example, algorithms in the standard library can often have their behavior changed using something callable. Creating a whole function is often excessive, and we use lambdas instead:
int non_a_amount = std::ranges::count_if("abcaabbac", [](char c) { return c != 'a'; });
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm, I think that could indeed be reworded with less complicated wording.
I did try to make a motivator immediately after this as well, but I agree it could definitely pull a stronger example forward at the very start.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Allright I tried to update a bit, and hopefully this should be a bit better now.
Co-authored-by: Jan Schultke <[email protected]>
Co-authored-by: Jan Schultke <[email protected]>
…o lambda_tutorial
…o lambda_tutorial
As per Eisenwave's suggestion, an attempt to create a stronger use case at the start.
src/resources/cpp/lambdas.md
Outdated
Lambdas are similar to functions, however they are not identical they specifically are | ||
[closures](<https://en.wikipedia.org/wiki/Closure_(computer_programming)>). | ||
|
||
if they are similar to functions one might ask why would I ever need a lambda? For example, algorithms in the standard |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should leave discussion on "when to use lambdas" to after they have been discussed more thoroughly. I also don't like the voice of "why would I ever need a lambda?". I would rather see a direct discussion of when to use lambdas versus when to use functions without "I" or "you" pronouns.
src/resources/cpp/lambdas.md
Outdated
|
||
`int non_a_amount = std::ranges::count_if("abcaabbac", [](char c) { return c != 'a'; });` | ||
|
||
This counts all results where the lambda returns true, in this case if the latter is not 'a'. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would suggest focusing more on the lambda first, then bringing in things like ranges/algorithms. Here, you're introducing two new concepts: lambdas and a range algorithm. I would just provide a name lambda, discuss what the lambda is, then pass it to the range algo and describe how the two interact.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I updated this code sample a bit and introduced a simpler code example first. @nickclark2016 is this better for you?
src/resources/cpp/lambdas.md
Outdated
|
||
### Capture list | ||
|
||
As the name implies, the capture list allows us to capture values into the lambda as it's constructed. Unlike the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tweak on wording: "capture value into the lambda where it is defined". Constructed feels a bit weird in the context of a lambda.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As the name implies, the capture list allows us to capture values as the lambda is constructed.
Hopefully that's better.
src/resources/cpp/lambdas.md
Outdated
|
||
### body `{}` | ||
|
||
The lambda body is the exact same as the body of the function. It's hold the code that the lambda will execute when it's |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reword: It holds the code code that the lambda will execute when it is invoked.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The body contains all the code that will be executed when the lambda is invoked.
Is that better?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
General voice comment: Consider moving "we" and "you" to the specific part of the code whenever possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I took a closer look at this, and wow, do I use this pattern a lot. I looked at the entire file and tried to address the wording a lot to use a more passive style. This should also be more fitting for the intended purpose, I feel.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please check spelling, capitalization, and contractions across the whole file.
* update article on UB * Avoid wrapping without sacrificing formatting --------- Co-authored-by: Jeremy Rifkin <[email protected]>
// A lambda that checks if the passed in letter is not equal to a. | ||
auto a_checker = [](char c) { | ||
return c != 'a'; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consistency: };
should not be indented
} | ||
``` | ||
|
||
As is visible above have noticed that the lambda uses the same variable name inside the lambda as declared in main. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reword this sentence please. It does not flow well.
}; | ||
``` | ||
|
||
Here a copy is made of multiply_number called num. The type does not need to be specified here. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggested Reword:
Here, a copy of multiply_number is made and assigned to num. Notice that the type is not specified here.
|
||
Here a copy is made of multiply_number called num. The type does not need to be specified here. | ||
|
||
Making a copy of a value might be undesirable and thus it's also possible to capture the variable as a reference. Now no |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reword second sentence to say "Now, multiply_number
is being taken by reference instead of by copy."
return n * multiply_number; | ||
}; | ||
``` | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a question (no action needed necessarily) - Should we talk about capture by reference and note how people need to be careful when using capture by reference/be aware of the lifetime implications (i.e. your lambda may have an invalid reference if the original object has its lifetime end before the lambda's lifetime ends)
```cpp | ||
#include <iostream> | ||
|
||
void say_a() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consistency: Braces are same line, single space between ()
and {
. Please fix across the entire document.
Converting to draft until ready |
A tutorial explaining lambdas. This touches upon what a lambda is and what the structure is like.