C++ Logo

liaison

Advanced search

Re: [wg14/wg21 liaison] a common C/C++ core specification

From: Jens Gustedt <jens.gustedt_at_[hidden]>
Date: Tue, 10 Mar 2020 22:00:44 +0100
Martin,

on Tue, 10 Mar 2020 20:27:35 +0000 you ("Uecker, Martin"
<Martin.Uecker_at_[hidden]>) wrote:

> Am Dienstag, den 10.03.2020, 20:59 +0100 schrieb Jens Gustedt via
> Liaison:
> > Yes, with lambdas and "auto" we just would have a standardized
> > version of that as
> >
> > #define FOO(x) [](auto __x){ return _Generic(__x, ... ); }(x)
> >
> > which has several advantages: a clearly marked `return` statement
> > and encapsulation against inadvertedly reading state from the
> > surrounding code.
>
> I like the explicit return.
>
> I am less sure about the [] syntax and the fact that
> you can not simply access variables from enclosing
> scopes or only with restrictions. The power of lambdas
> comes exactly from accessing the variables of the
> enclosing state. Making this harder than necessary
> may not be ideal.

The `[]` syntax can be quite simple. You put a list of all the
variables (called captures) that you want to access and inside the
lambda these are then the frozen values of these variables.

Or you can have `[=]` then all variables of the surrounding scope are
visible, but you have to make that explicit by putting a `=` in there.

Both forms have their advantages and disadvantages, but the scheme is
quite flexible.

> type inference for parameters for lambdas is
> interesting, but somehow does not feel right.
> It can't work for regular functions, so it is
> another special rule that makes the language
> more complicated.

Not very, but yes, C++20 has now these forms of functions as-if
defined as templates, but without all the crufty template syntax.

And, if you don't like type inference for lambdas, you don't have to
use that, you can simply have normal parameter types, no problem with
that.

> I like simplicity. As a C person, I would simply
> lift existing syntactical restrictions and allow
> nested functions and lambdas using the syntax
> of compound literals:
>
> int foo(int x)
> {
> int bar(int y) { return x + y; }
>
> int (*fp)(int) = (int(int x)){ return x + y; }
> }
>
> We may need a new type for pointers to
> lambdas/nested functions.

Well yes, if you want to import `y` from the surrounding scope,
effectively classical function pointers wouldn't do it, unless you
want to create executable functions on the stack or so.

(And the syntax you are proposing is quite ambiguous. Is `y` taken as
life variable, that is evaluated each time the `fp` is called? What
happens when `fp` survives the scope of `foo`, is `y` kept alive?)

In my proposal your "new type for pointers" is called lambda value. It
would be

auto fp = [y](int x){ return x + y; };

Then `fp` can survive `foo` without problems. One possible use case is
e.g

auto fii(double x)
{
 double y = ...

 // do some complicated calculations to determine y

 return [y](double z){ return y × z; };

}

and then

  auto fp = fii(π);

  fp(1.9);
  ... /* as many calls as you like */

so this is an easy to write and control form of explicit constant
propagation.

Jens

-- 
:: INRIA Nancy Grand Est ::: Camus ::::::: ICube/ICPS :::
:: ::::::::::::::: office Strasbourg : +33 368854536   ::
:: :::::::::::::::::::::: gsm France : +33 651400183   ::
:: ::::::::::::::: gsm international : +49 15737185122 ::
:: http://icube-icps.unistra.fr/index.php/Jens_Gustedt ::

Received on 2020-03-10 16:03:35