Date: Tue, 11 Apr 2023 17:24:11 +0100
Frederick Virchanza Gotham wrote:
> So I thinking, what if we had a 'long return lamda'? The return
> statement from a 'long return lambda' is treated as a return statement
> from the enclosing function.
This is similar to the desire to be able to break, continue or return
from within a loop that takes a lambda.
For example, say I want to iterate over the edges of a polygon:
Polygon p = ....;
for (auto e: edges(p)) {
// In here I can use break and continue, and return
// will return from the function.
}
But what is edges(p) there? Maybe it is a generator coroutine;
maybe it is a function that returns a lazy range. It's probably
simpler to write a foreach function that takes a lambda, like this:
foreach_edge(p, [&](auto e) {
// In here, I can't use break or continue, and return
// just returns from the lambda.
});
(The different behaviour of return is perhaps dangerous, i.e. one
might write "return" imagining a return from the function, and not
get a warning or error.)
There have been suggestions that break and continue should be
extended to support nested loops:
outer: for (auto a: A) {
inner: for (auto b: B) {
if (....) continue outer;
}
}
Generally the response to these suggestions have been "just use
goto". So how about this:
foreach_edge(p, [&](auto e) {
if (....) goto break_outer;
});
break_outer: ....
Similarly, in Frederick's example, "just use goto":
bool Serial(char *const p) {
auto BAIL = [p](void)->void {
strcpy(p, "0000000000000000");
goto Serial_return;
};
........
Serial_return: ...
}
Currently goto can't exit a lambda. Though of course exceptions can
do that.
So here is my suggestion: make it possible to exit lambdas with goto,
with the same/similar semantics to throwing and catching an exception.
Can that be implemented with lower overhead than actually using an
exception?
Regards, Phil.
> So I thinking, what if we had a 'long return lamda'? The return
> statement from a 'long return lambda' is treated as a return statement
> from the enclosing function.
This is similar to the desire to be able to break, continue or return
from within a loop that takes a lambda.
For example, say I want to iterate over the edges of a polygon:
Polygon p = ....;
for (auto e: edges(p)) {
// In here I can use break and continue, and return
// will return from the function.
}
But what is edges(p) there? Maybe it is a generator coroutine;
maybe it is a function that returns a lazy range. It's probably
simpler to write a foreach function that takes a lambda, like this:
foreach_edge(p, [&](auto e) {
// In here, I can't use break or continue, and return
// just returns from the lambda.
});
(The different behaviour of return is perhaps dangerous, i.e. one
might write "return" imagining a return from the function, and not
get a warning or error.)
There have been suggestions that break and continue should be
extended to support nested loops:
outer: for (auto a: A) {
inner: for (auto b: B) {
if (....) continue outer;
}
}
Generally the response to these suggestions have been "just use
goto". So how about this:
foreach_edge(p, [&](auto e) {
if (....) goto break_outer;
});
break_outer: ....
Similarly, in Frederick's example, "just use goto":
bool Serial(char *const p) {
auto BAIL = [p](void)->void {
strcpy(p, "0000000000000000");
goto Serial_return;
};
........
Serial_return: ...
}
Currently goto can't exit a lambda. Though of course exceptions can
do that.
So here is my suggestion: make it possible to exit lambdas with goto,
with the same/similar semantics to throwing and catching an exception.
Can that be implemented with lower overhead than actually using an
exception?
Regards, Phil.
Received on 2023-04-11 16:24:13