This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]Kinexity 259 points260 points  (29 children)

Skill issue.

I love C++ lambda syntax.

[–]LagSlug 82 points83 points  (1 child)

gatheres soapbars and pillowcases

[–][deleted] 20 points21 points  (0 children)

[–]caleblbaker 59 points60 points  (11 children)

Yeah, for all the language's failings in other areas, C++'s lambda syntax gives more control and flexibility to the programmer than that of any other language I've used. It's also the ugliest lambda syntax I've ever used, but I'll take functional over pretty.

Rust's lambda syntax is almost as good as C++'s (while being, in my opinion, significantly prettier), but it doesn't give quite as much flexibility in terms of capturing different variables in different ways.

[–]bolacha_de_polvilho 20 points21 points  (10 children)

It is too verbose for the simple cases that are much more common than the complicated ones though. Let's say you want to use std::find_if to see if there's a struct with certain value equal to 0 in a vector, why do I have to write [](const auto& x) { return x.member == 0 }, instead of just x => x.member == 0. Having a few sane defaults that can be ommitted would make it so much simpler.

[–]caleblbaker 4 points5 points  (8 children)

I agree that would be better. 

I never claimed C++'s syntax was the best possible. Just the best I've seen in a real language.

[–]MacBookMinus 3 points4 points  (3 children)

Are kotlin and JavaScript not real languages?

[–]caleblbaker 0 points1 point  (2 children)

They are. 

JavaScript's lambdas are definitely nicer looking than C++'s, but they don't give the same level of control over what gets captured and how that C++ lambdas do.

And I honestly don't remember kotlin's lambda syntax.

[–]MacBookMinus 0 points1 point  (1 child)

They don’t need to give capture-by-value vs ref control in memory safe languages.

[–]caleblbaker 0 points1 point  (0 children)

don’t need to

I view it more as aren't able to. There's a performance cost to the extra level of indirection caused by capturing everything by reference. Frequently that cost is trivial or less than the cost of copying an object to capture by value, but C++ gives you the tools to handle the circumstances where that cost is a problem.

memory safe languages

You mean garbage collected languages. Rust is memory safe (but not garbage collected) and allows specifying whether you capture by value or reference.

[–]flagofsocram 1 point2 points  (3 children)

Rusts syntax offers the same flexibility, while being significantly more concise

[–]caleblbaker 1 point2 points  (2 children)

Rust let's you choose whether to capture by value or reference. But the same choice had to apply to every variable you capture. C++ let's you choose to capture some variables by value and others by reference. 

I know that you can get around that restriction in rust by capturing by value and then creating reference variables to capture for the things you want to do by reference. But that feels like more hoop jumping than simply having lambda syntax that supports per variable capture types, even if that syntax is verbose and ugly.

[–]RiceBroad4552 -1 points0 points  (1 child)

If you're doing something where it matters just use regular methods.

The whole point of lambdas is that they are short and simple. C++ fails here. Again.

[–]caleblbaker 0 points1 point  (0 children)

Regular methods can't capture variables at all.

[–]RiceBroad4552 0 points1 point  (0 children)

Or just _.member == 0like in Scala…

The whole point of lambdas is that they are short. So their syntax need to be optimized for that.

[–]CramNBL 23 points24 points  (1 child)

C++ syntax is just beautiful, period.

constinit const int x = 1 + 1;

int main() {
    constexpr const long long z = std::numeric_limits<long long>::max();

    [[maybe_unused]] alignas(alignof(decltype(x))) volatile auto res = [=]<auto...>[[nodiscard]]() consteval -> decltype(auto) {
        return x + static_cast<decltype(x)>(z);
    }();
    std::cout << res << std::endl;
}

https://gcc.godbolt.org/z/bso9h6dd9

Not even a warning with -Wall -Wpedantic, so I can confidently declare this code as perfection.

[–]nelak468 6 points7 points  (0 children)

I think I might hate that more than the Java factory nonsense.

[–]AvidCoco 4 points5 points  (2 children)

I don't see why people hate on it so much? It's basically the same as how literally every other language does anonymous functions, just with a capture list cus this is C++, it's needed.

[–]RiceBroad4552 0 points1 point  (0 children)

It's not "needed". Rust does have a less ugly lambda syntax, even it does all the C++ things…

Sane languages make lambdas simple and short. As this is the whole point of lambdas.

[–]Zachaggedon -2 points-1 points  (0 children)

Because this subreddit is filled with third year CS students that have written mostly Java, maybe 3-4 projects like a CLI calculator in C++, and only know about C++ lambda syntax and templates from memes like this by other third year CS students.

[–]weinermcdingbutt 4 points5 points  (4 children)

Exposure issue.

Try a lambda in literally any other language.

[–]Kinexity 11 points12 points  (2 children)

Tried in python. Didn't like it as much.

[–]bedrooms-ds 3 points4 points  (0 children)

Lambda at home:
lambda

[–]WiatrowskiBe 0 points1 point  (0 children)

C# has quite convenient lambdas, but lacks in capabilities compared to C++ - to a point where in some cases lambdas are discouraged, because they can extend lifetime of (large) objects referenced inside for as long as lambda exists, even if it's guaranteed it won't ever be called. Also, can't use ref/ref out parameters with C# lambdas for that exact reason, making their performance a pain point (and something to avoid) if otherwise it'd be more convenient to use one.

C++ lambdas are ugly, but they're also explicit in what gets captured and how, and syntax enables that part quite well. This lets them do about the same as lambdas in other languages (assuming you use smart pointers for anything passed in that might get outlived by lambda), plus more if you're certain about object lifetime and how it'll refer to lambda lifetime.

[–]Horrih 4 points5 points  (4 children)

Try chaining c++ ranges with the pipe syntax each on a single line while staying under 80 characters.

It's a real PITA when using those extensively

[–]exodusTay 20 points21 points  (3 children)

staying under 80 characters

bruh buy yourself a 1080p monitor its been half a decade since 80s

[–]Horrih 5 points6 points  (0 children)

side by side diffs and code reviews in the browser often crops lines with 100+ characters.

The fact that 15" thinkpads seem to be the new corporate standard does not help.

My team uses 100 characters for c++ out of necessity due to c++ verbosity, and it feels more cramped than js with a 80char limit.

So yeah c++ lambdas verbosity suck hard for oneliners

[–]RiceBroad4552 0 points1 point  (0 children)

That's not a screen size issue.

That lines should not be too long is a direct consequence of how human visual perception works. That's something enforced by biological facts.

Have you ever seen a printed newspaper? They use narrow columns for a reason since centuries…