
Syntax changes from C++11 to C++20 - joebaf
https://www.bfilipek.com/2020/08/lambda-syntax.html
======
Animats
The amusing thing is that C++ still doesn't have nested functions. (Although I
think that was a GCC feature at one point.)

As I point out now and then, there are two basic concepts here - closures and
anonymous functions. A lambda is both. All four combinations (functions
with/without closure, and with/without names) are possible. There's a tendency
to confuse the two. An anonymous function is syntactical sugar. A closure is a
run-time construct.

\- Python and Javascript have nested functions with inheritance, which are
closures. Most garbage collected languages have that, because it's easy to
implement. Python also has lambdas, which von Rossum didn't want to put in but
did to shut up the crowd that wanted them.

\- Rust has nested functions without inheritance. A nested function can't
access its outer scope. Rust also has lambdas, and they can inherit. C++ has
now gone the same route. Non-GC languages need compile-time work to implement
a closure, since something has to make a copy of what's inherited and worry
about its lifetime.

\- It's possible to have anonymous functions without inheritance. The classic
example is a sort key function, where a sort function is called with a
function that defines the test.

~~~
WalterBright
D has nested functions that can access the enclosing function's variables (and
it's enclosing function's variables, on up the call stack!).

It's a feature I first encountered with Pascal.

It's simple to implement. After using them extensively for years now, they're
a big improvement.

~~~
ridiculous_fish
Are D's nested functions truly functions - for example are they ABI-compatible
with a top-level function? If so, how do they get access to the stack frame?

gcc has this feature, it is implemented by constructing a trampoline-style
function on the stack. This requires an executable stack, so isn't really a
thing any more.

~~~
WalterBright
> Are D's nested functions truly functions

Yes. They're even inlinable!

> for example are they ABI-compatible with a top-level function?

If they are annotated with `static`, yes. If they are not so annotated, they
are ABI-compatible with non-static member functions. In fact, in D, a pointer
to a non-static member is interchangeable with a pointer to a non-static
nested function. This makes for much convenience when dealing with algorithms
that accept such pointers (called "delegates" in D):

> how do they get access to the stack frame?

And extra argument is passed to the function which is the frame pointer to the
calling function. (This is called a "static link". The "dynamic link" is the
return address.) This can be thought of as the "this" pointer to the "struct"
that represents the caller's stack frame, hence the binary compatibility with
member functions.

To go back to the enclosing enclosing enclosing function's stack frame, you
dereference the static link 3 times. The tricky part is optimizing these
dereferences away when there are no captured variables in a stack frame.

------
ping_pong
I was a C/C++ programmer from 1995 to 2012, almost 20 years. I moved on to
more SaaS-friendly languages, but when I look at C++ now, it's
incomprehensible to me. It's an entirely different language. I _think_ I could
get back into it, but it's been so long and the gap between where I left it
and where it is now is so vast, coupled with the dearth of jobs compared to
Python or Go, that it doesn't feel worth it anymore. It's weird knowing that a
language that I spend so much time on is relegated to the past.

~~~
boring_twenties
I've been out of the game for a while, so I could be way off here, but my
experience during my brief (15-20 year) career was one could always get paid
significantly more for doing C++ than Python.

Which makes intuitive sense to me since it's a lot harder to master C++.

~~~
ping_pong
This isn't true. Go/Python/non-C++ can get you dozens of jobs with very high
total comp, well over anything for C++. A Senior Software Engineer at any FANG
will get you over 400k/yr TC. Getting an equivalent job with C++ would be much
harder.

~~~
brandmeyer
Hate to break it to you, but GOOG is mostly a C++ and Java shop with some Go
presence.

~~~
ping_pong
Google is most definitely not "mostly C++". Java I can believe is a majority,
but there's a plethora of languages used there.

~~~
brandmeyer
You misunderstand me: I'm not claiming its "mostly C++", I'm claiming that its
"mostly C++ and Java". Python isn't zero, but its very far down the list, both
in lines of code and machine cycles spent.

~~~
joshuamorton
Certainly, although you can work there using almost entirely python (I did for
two years, although I'm now having to use more and more c++ and java as my
work shifts to be infra that involves products instead of just raw infra)

------
cheez
Great survey but why on earth does there need to be a book about lambdas in
C++???

~~~
rightbyte
I just wish there was nested functions instead of these lambda classes.

~~~
cheez
eh.... having to deal with Python's stupid lambdas, C++ lambdas are far
superior. You can always do:

auto func = [](...){....}

for nested funcs

~~~
rightbyte
Ye but I would just want the possibility for the simpler syntax like the GCC
extension for C where you can do:

    
    
        typedef void fp_t();
        void foo(fp_t fp)
        {
            fp();
        }
    
        int square(int num) {
    
            void square_nested() 
            {
                num = num * num;
            }
    
            foo(square_nested);
    
            return num;
        }
    

That would work as long as you don't need copy capture.

~~~
cheez
I really don't see how that is so much better than the alternative that it
would warrant a language change:

    
    
      int square(int num) {
        auto nested = [&num](){ 
           num *= num; 
        };
        nested(num);
        return num;
      }

~~~
cmeacham98
Slight mistake: should be

    
    
        auto nested = [](int& num){
    

(or switch calling nested to have no params)

~~~
cheez
The HN C++ compiler ;-)

------
tobz1000
I'm only mildly familiar with C++, but the support for template arguments in
lambdas looks like an analogue for generic closures, which are absent from
Rust, but would be really handy at times.

~~~
gpderetta
Note that C++ has had generic closures since C++14, with auto parameters.
Template arguments are just a refinement for that.

------
im3w1l
So that ForwardToTestFunc right? At what time are the template arguments
filled in? Could you call it first with an int and then later with a string,
each call forwarding to a different overload?

~~~
gumby
Yes, that’s precisely the use case. The compiler synthesizes two functions,
one for each case, then optimizes them separately.

------
verytrivial
I've been a C++ programmer for 20 years. Having just seen the example of
template arguments in lambda functions:

1) I am reminded of this Larson cartoon:
[https://imgur.com/gallery/4gR7tX7](https://imgur.com/gallery/4gR7tX7)

2) I have a palpable urge to learn Go.

~~~
doorstar
The more I program in Go, the more retroactively irritated I get at C++. A
buddy of mine did a few 'brown bag' sessions on advanced C++ templating and my
jaw just dropped further and further at each one. Who has the energy for this?
It's hard to write, it's hard to read, it's hard to debug.

For someone who a) knows what they're doing and b) really needs to squeeze
every last millisecond out of the code I suppose they could be useful. It made
me want to send Rob Pike a thank you card.

~~~
jfkebwjsbx
C++ and Go are different languages with different goals.

Why would a C++ programmer learn Go? They should learn Rust since it is pretty
much a cleaned up, modernized C++.

~~~
supergirl
rust is just new, not too bloated, YET. long way to go until it can be seen as
a "better C++".

~~~
jfkebwjsbx
Agreed, it is lacking tooling support and many other things, but it is a
cleaner C++. That plus the borrow checker are its two major features.
Otherwise, nobody would use it and their designers would have done a pretty
bad job given the 30 years of experience they had from C++!

------
objektif
Can we make the beautiful C syntax insufferable? Yes sure just leave it to the
committee.

~~~
gumby
Well, these are features that don’t exist in C.

Plus the complex template syntax is mostly unnecessary in C++20

------
choeger
One of the worst design decisions in C++ (IMO, of course) is the template
syntax. Templates are proper macros, abstractions over code in the sense of
lisp. But C++ hides this fact by relying (mostly) on implicit template
application and very, very, indirect syntax for template abstraction.

For instance: who came up with the idea of templated lambdas? Yes, manually
managed closures are very C++, and yes, templated closures are also very much
C++. But now we have templated closures that capture local variables _IF THEY
EVER HAPPEN TO BE INSTANTIATED_. What the actual cluster eff?

~~~
gpderetta
Templated lambdas are extremely powerful. Think for example of (recursive)
visitations of etherogeneous containers.

~~~
ben509
I tried; the house began shaking, there was a sudden eclipse and blood started
trickling down the walls. Is that supposed to happen?

~~~
rumanator
Have you tried compiling with -O0 -g -Wstrict-exorcism ?

