Date: Wed, 13 Jan 2021 14:49:46 -0500
On Mon, Jan 11, 2021 at 11:55 PM Andrew Tomazos via Std-Proposals
<std-proposals_at_[hidden]> wrote:
>
> I have an idea for a language feature we'll call Lambda Classes.
>
> As placeholder syntax let's say like:
>
> lambda-class:
> lambda-introducer : base-specifier-list_opt { member-specification_opt }
>
> So for example:
>
> auto my_lambda_class = [cap1,cap2]: {
> void f() { /*...*/; }
> void g() { /*...*/; }
> };
>
> A lambda class is to a normal class object as a lambda function is to a normal function.
>
> A lambda class is an expression that is introduced with the usual capture sequence, but is followed by a colon, a (possibly empty) base class list, and then a class definition body.
>
> It constructs a new anonymous class type in the same fashion as a normal lambda, capturing any variables as specified in the lambda-introducer, derives the new class type from any bases in the base-specifier-list, and adds any members given in the member-specification, and the value of the expression is the (singular) object of that new class type.
>
> The motivation is that there are many use cases where an API asks for an object of a class type that implements some interface - either implementing a (virtual) polymorphic interface (run-time polymorphism) in traditional OOP, or that models a certain concept (compile-time polymorphism) in template meta-programming - and in many of both of those use case families, the response is to create a single-use class is created just to adapt to that API. Like lambda functions, lambda classes help remove a lot of the boilerplate and indirection in such use cases.
My main issue is that this adds complication to the language in a way
that I'm not sure is common enough to be worth the language cost. In
order for this to be a reasonable thing to do, you would have to be in
a situation where all of the following are true:
1: You need to declare a struct containing specific member functions.
2: There's no reason to use this struct outside of a specific context
(ie: this is why you're not declaring it outside of the function).
3: The struct needs to access local data essentially as-is (ie: you're
just copying or referencing local variables).
4: The object has *no other* special constructor needs (ie: you don't
need to call particular base class constructors).
I'm not sure how often this particular combination of factors comes
up. Lambdas are useful because there are many interfaces that just
call a function, and the stuff this function is doing makes sense
locally. The more complicated that object becomes (multiple member
functions, etc), the less likely it is that said type remains purely
local.
Also, the more functions you have, the less readable the local code
becomes. Lambdas having one function is far more readable than a
"lambda" with 4 functions, in terms of following what is going on in
the local code.
<std-proposals_at_[hidden]> wrote:
>
> I have an idea for a language feature we'll call Lambda Classes.
>
> As placeholder syntax let's say like:
>
> lambda-class:
> lambda-introducer : base-specifier-list_opt { member-specification_opt }
>
> So for example:
>
> auto my_lambda_class = [cap1,cap2]: {
> void f() { /*...*/; }
> void g() { /*...*/; }
> };
>
> A lambda class is to a normal class object as a lambda function is to a normal function.
>
> A lambda class is an expression that is introduced with the usual capture sequence, but is followed by a colon, a (possibly empty) base class list, and then a class definition body.
>
> It constructs a new anonymous class type in the same fashion as a normal lambda, capturing any variables as specified in the lambda-introducer, derives the new class type from any bases in the base-specifier-list, and adds any members given in the member-specification, and the value of the expression is the (singular) object of that new class type.
>
> The motivation is that there are many use cases where an API asks for an object of a class type that implements some interface - either implementing a (virtual) polymorphic interface (run-time polymorphism) in traditional OOP, or that models a certain concept (compile-time polymorphism) in template meta-programming - and in many of both of those use case families, the response is to create a single-use class is created just to adapt to that API. Like lambda functions, lambda classes help remove a lot of the boilerplate and indirection in such use cases.
My main issue is that this adds complication to the language in a way
that I'm not sure is common enough to be worth the language cost. In
order for this to be a reasonable thing to do, you would have to be in
a situation where all of the following are true:
1: You need to declare a struct containing specific member functions.
2: There's no reason to use this struct outside of a specific context
(ie: this is why you're not declaring it outside of the function).
3: The struct needs to access local data essentially as-is (ie: you're
just copying or referencing local variables).
4: The object has *no other* special constructor needs (ie: you don't
need to call particular base class constructors).
I'm not sure how often this particular combination of factors comes
up. Lambdas are useful because there are many interfaces that just
call a function, and the stuff this function is doing makes sense
locally. The more complicated that object becomes (multiple member
functions, etc), the less likely it is that said type remains purely
local.
Also, the more functions you have, the less readable the local code
becomes. Lambdas having one function is far more readable than a
"lambda" with 4 functions, in terms of following what is going on in
the local code.
Received on 2021-01-13 13:50:04