[] (a) {}
Is `a` an automatically-typed variable or an unnamed argument with the type `a`?
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3418.pdf
Where it specifically says that auto is NOT allowed (not just not
required), which necessarily disallows unnamed parameters precisely to
avoid the ambiguity.
Has this changed? I like it better without auto FWIW
Note that this proposal is still in progress, and is changing based on EWG input.
In particular, in Portland there was considerable concern from Bjarne in particular about the “overly terse” form, such as []( &a ) as a synonym for []( auto& a ), mainly on the grounds that:
· If we adopt concept-like template constraints in the future we want to write things like []( iterator a ) and allowing dropping the ‘auto’ now potentially could make people lazy and disincentivized to insert the concept/constraint name in the future.
· As noted, it means we can’t have unnamed parameters for lambdas, which for better or worse are allowed everywhere else and so would be inconsistent with the rest of the language.
I still think there’s real demand for the terse form that doesn’t require ‘auto’, but there is a design tension here that we’re still working out.
Herb
--
auto compose = []( auto f, auto g )
[=]( auto x ) f( g(x) );
auto curry3 =
[]( auto f )
[=](auto x) [=](auto y) [=](auto z)
f(x,y,z);
And variadic lambdas, too! Very nice.
But I wonder why we couldn't...
auto f = []( auto _f ) [](auto ...x) _f(x...);
I wrote some tests. A few lines caused the compiler to crash so I commented them out and labelled them "Crash!".
https://gist.github.com/4347130
f(a, b, c, d)
i.e., the auto keyword doesn't really add any information, and that I
preferred something like
f( T a, T b, U c, X d );
IMO, requiring, or even allowing auto is like having case (a) but
looking like case (b), which IMHO would be a mistake and would add
nothing.
(FWIW, I would prefer a simpler syntax where you can say (T a) instead
of <class T>(T a), but that's a lot more difficult given the current
language definition)
> Not putting auto in *already* has a meaning; it is perfectly legal to write:OK.
>
> [](string){}
>
> Changing string to mean "parameter" instead of "type" is a breaking change
> from C++11 and inconsistent with the rest of the language.
>
Now this is a different argument. You have a point, but, I would say
that the solution is simple: disallow unnamed parameters (like they do
in the proposal)
>> (FWIW, I would prefer a simpler syntax where you can say (T a) instead>> of <class T>(T a), but that's a lot more difficult given the currentAre you referring to the case when you'd use <class T>?
>> language definition)
>
>
> Again, I think that is incredibly error prone, because its meaning changes
> based on whether or not T is a lexically available type.
Composition and currying are cool.
Those who don’t like the terse syntax may object that it’s only slightly worse with the current syntax, though, right?
auto compose = []( auto f, auto g ) { return
[=]( auto x ) f( g(x) ); };
auto curry3 =
[]( auto f ) { return
[=](auto x) { return [=](auto y) { return [=](auto z) { return
f(x,y,z); }; }; }; };
Though you do have to be a little careful to balance the {‘s and };’s.
Herb
--
The second point is for those of us unfortunate enough to get
occasional exposure to
shell scripts, perl, and ruby. Replacing auto with @ is utterly
unconvincing to me,
and is just a foolish hack that has negative value. I don't think
maximum tersity
is a valuable goal, I prefer having a short but readable syntax, and
that's at odds
with maximum tersity.
--
I still think there’s real demand for the terse form that doesn’t require ‘auto’, but there is a design tension here that we’re still working out.
Where it specifically says that auto is NOT allowed (not just not
required), which necessarily disallows unnamed parameters precisely to
avoid the ambiguity.
Has this changed?
There was a very strong preference in the Evolution Room of the
Portland Meeting for auto to be mandatory. I believe either option
can be reasonably implemented.
The `auto` is required is disambiguate this:
[] (a) {}
Is `a` an automatically-typed variable or an unnamed argument with the type `a`?
On Monday, December 17, 2012 3:38:25 PM UTC-7, dain...@gmail.com wrote:Cool :)Why is "auto" required though? It seems like it would work fine without the keyword..?
so, maybe it'd make sense to introduce some special keyword to disambiguate these cases?
On Tuesday, December 18, 2012 5:50:50 PM UTC+2, tra...@solidfire.com wrote:The `auto` is required is disambiguate this:
[] (a) {}
Is `a` an automatically-typed variable or an unnamed argument with the type `a`?
On Tuesday, December 18, 2012 5:50:50 PM UTC+2, tra...@solidfire.com wrote:The `auto` is required is disambiguate this:
[] (a) {}
Is `a` an automatically-typed variable or an unnamed argument with the type `a`?It's an automatically-typed variable. Having an unnamed argument in a lambda in senseless. You can't overload it, so using it to force the compiler to choose some version of a function isn't possible. You can't refer to it. It is therefore silly to create problem which does not, in practice, exist.
It's an automatically-typed variable. Having an unnamed argument in a lambda in senseless. You can't overload it, so using it to force the compiler to choose some version of a function isn't possible. You can't refer to it. It is therefore silly to create problem which does not, in practice, exist.
[]a(var1, var2, var3) {...}
[]a(var1, var2, var3) {...}
Besides, there are legitimate use cases for unnamed arguments in lambda functions:void foo(void (*)(Info, Extra));foo([] (Info x, Extra) { ... });
On Fri, Jan 11, 2013 at 1:08 PM, <nadias...@gmail.com> wrote:It's an automatically-typed variable. Having an unnamed argument in a lambda in senseless. You can't overload it, so using it to force the compiler to choose some version of a function isn't possible. You can't refer to it. It is therefore silly to create problem which does not, in practice, exist.
I agree that's how I would have written the rule if I was starting from scratch -- the issue is that there is already a C++11 standard which unambiguously requires [] (a) {} to be parsed as an unnamed argument. It will be a very tough fight to get the committee to approve a breaking change.
class A{}; class B{}; class C{};
typedef void (*callback1)(A /*required*/, B /*optional*/);
typedef void (*callback2)(A /*required*/, C /*optional*/
);
void func(callback1);
void func(callback2);
void foo() {
func([](A a, B){ /*Do stuff with only a
*/});
}
On 11 January 2013 14:36, Nicol Bolas <jmck...@gmail.com> wrote:
[]a(var1, var2, var3) {...}
Ultimately, people are going to want to mix concrete types and templated types, as they do with templated functions now.
Part of the charter of EWG is to look at the language "as a whole". Making the declarations work in a way that is inconsistent with the rest of the language goes against this, IMHO.
Also, the more complicated this proposal gets, the less likely it'll make it into C++14 (whose charter is to "Complete C++11", not invent a whole bunch of new things). Are polymorphic lambdas a feature you'd rather see sooner than later?
On Fri, Jan 11, 2013 at 2:23 PM, Travis Gockel <tra...@gockelhut.com> wrote:
> Besides, there are legitimate use cases for unnamed arguments in lambda
> functions:
>
> void foo(void (*)(Info, Extra));
> foo([] (Info x, Extra) { ... });
A single name is ambiguous here, however, I noticed that a reference
without a type-specifier is not, like
[] (&a) { ... }
So, how about enforce a special prefix to non-reference parameters? Like:
[] (=a) { ... }
Thus, the two grammars above are two generic lambda parameters.
> I agree that's how I would have written the rule if I was starting from
> scratch -- the issue is that there is already a C++11 standard which
> unambiguously requires [] (a) {} to be parsed as an unnamed argument. It
> will be a very tough fight to get the committee to approve a breaking
> change.
I'm not sure that's the case, and it seems worthwhile to put it to the
committee rather than assuming they would oppose it.
Part of the charter of EWG is to look at the language "as a whole". Making the declarations work in a way that is inconsistent with the rest of the language goes against this, IMHO.
This will be neither the first nor the last time that changes enter the standard that are "inconsistent with the rest of the language".
Also, the more complicated this proposal gets, the less likely it'll make it into C++14 (whose charter is to "Complete C++11", not invent a whole bunch of new things). Are polymorphic lambdas a feature you'd rather see sooner than later?
No. I would much rather have to wait until C++17 to get polymorphic lambdas correctly than to have a long-winded, broken version forever in the language, with no possibilities of ever correcting the syntax.
On Friday, January 11, 2013 3:23:03 PM UTC-5, Travis Gockel wrote:
I agree that's how I would have written the rule if I was starting from scratch -- the issue is that there is already a C++11 standard which unambiguously requires [] (a) {} to be parsed as an unnamed argument. It will be a very tough fight to get the committee to approve a breaking change.That may be social reason for the sad "auto" requirement rule, but it is not a satisfying one.
Users will gasp in horror,
For the example
auto f = [] @a x @b; // maximum tersity
the idea would be to have the expression directly, with just markers to the names which are arguments objects, letting the compiler do the rest.
This is a wild idea coming from reading this discussion so it might be stupid...
What do you think?
- Daniel
--
- Daniel
--
[] (a) {}
Is `a` an automatically-typed variable or an unnamed argument with the type `a`?
Isn't this another case of - if it can be a typename it is a typename?