Thread overview
lambdas with types
Nov 20
jmh530
Nov 20
jmh530
November 20
Doing something like below fails because I don't seem to be able to make a templated lambda that just takes types. Is the only way to do something similar to create a separate function to handle the condition, or is there some other way to do something with similar flexibility?

import std.stdio: writeln;
import std.meta: allSatisfy;

void foo(Args...)(Args args)
    if (allSatisfy!(x => is(x == double), Args))
{
    writeln("works");
}

void main() {
    foo(1.0, 2.0);
}
November 20
On Friday, 20 November 2020 at 14:08:23 UTC, jmh530 wrote:
> Doing something like below fails because I don't seem to be able to make a templated lambda that just takes types. Is the only way to do something similar to create a separate function to handle the condition, or is there some other way to do something with similar flexibility?
>
> import std.stdio: writeln;
> import std.meta: allSatisfy;
>
> void foo(Args...)(Args args)
>     if (allSatisfy!(x => is(x == double), Args))
> {
>     writeln("works");
> }
>
> void main() {
>     foo(1.0, 2.0);
> }

There is no way to create an anonymous template in D. You will have to declare a separate helper template:

    private enum isDouble(T) = is(T == double);

    void foo(Args...)(Args args)
        if (allSatisfy!(isDouble, Args))
    {
        // ...
    }

In this specific case, you could also make `foo` a type-safe variadic function [1], which would eliminate the need for `allSatisfy`:

    void foo(double[] args...)
    {
        // ...
    }

[1] https://dlang.org/spec/function.html#typesafe_variadic_functions
November 20
On Friday, 20 November 2020 at 14:47:52 UTC, Paul Backus wrote:
> There is no way to create an anonymous template in D.

I wish there was, maybe some day we can think of a way to add it to the language.
November 20
On Fri, Nov 20, 2020 at 02:47:52PM +0000, Paul Backus via Digitalmars-d-learn wrote: [...]
> In this specific case, you could also make `foo` a type-safe variadic function [1], which would eliminate the need for `allSatisfy`:
> 
>     void foo(double[] args...)
>     {
>         // ...
>     }
[...]

Yes, and this will also eliminate the template bloat associated with .foo, which would have been instantiated once per call with a different number of arguments.  But of course, this only works if all arguments are of the same type, and if the function body does not depend on accessing the number of arguments at compile-time.


T

-- 
What do you get if you drop a piano down a mineshaft? A flat minor.
November 20
On Friday, 20 November 2020 at 14:57:42 UTC, H. S. Teoh wrote:
> On Fri, Nov 20, 2020 at 02:47:52PM +0000, Paul Backus via Digitalmars-d-learn wrote: [...]
>> In this specific case, you could also make `foo` a type-safe variadic function [1], which would eliminate the need for `allSatisfy`:
>> 
>>     void foo(double[] args...)
>>     {
>>         // ...
>>     }
> [...]
>
> Yes, and this will also eliminate the template bloat associated with .foo, which would have been instantiated once per call with a different number of arguments.  But of course, this only works if all arguments are of the same type, and if the function body does not depend on accessing the number of arguments at compile-time.
>
>
> T

Thanks all.

The template conditions I'm working on are complicated enough that this approach might work for some but not all. However, if I split out the function I'm working on into a separate one, then I might be able to take advantage of that.
November 20
On Fri, Nov 20, 2020 at 02:52:41PM +0000, Adam D. Ruppe via Digitalmars-d-learn wrote:
> On Friday, 20 November 2020 at 14:47:52 UTC, Paul Backus wrote:
> > There is no way to create an anonymous template in D.
> 
> I wish there was, maybe some day we can think of a way to add it to the language.

Wouldn't it be just syntactic sugar for a manually-declared helper template?  We could just adapt the syntax for anonymous classes and combine it with the syntax for lambdas, something like this:

	template(T) => ... /* compile-time expression */

So for example:

	auto myFunc(Args...)(Args args)
		if (allSatisfy!(template(T) => is(T : double)))
	{ ... }

The template keyword is to differentiate between an actual lambda vs. a "template lambda".  Not sure if we can leave out the (), it may be necessary to diambiguate it from a named template declaration?

Implementation-wise, it would of course just lower to an injected helper template declaration.


T

-- 
It is impossible to make anything foolproof because fools are so ingenious. -- Sammy
November 20
On Friday, 20 November 2020 at 15:07:09 UTC, H. S. Teoh wrote:
> Wouldn't it be just syntactic sugar for a manually-declared helper template?

Yeah, there's just both alias and enum helper templates that can both be useful at times so you might have to use those keywords in there somewhere too. (isInputRange is prolly an enum, but like ElementTypeOf is an alias...)
November 21
On Friday, 20 November 2020 at 14:08:23 UTC, jmh530 wrote:
> Doing something like below fails because I don't seem to be able to make a templated lambda that just takes types. Is the only way to do something similar to create a separate function to handle the condition, or is there some other way to do something with similar flexibility?
>
> import std.stdio: writeln;
> import std.meta: allSatisfy;
>
> void foo(Args...)(Args args)
>     if (allSatisfy!(x => is(x == double), Args))
> {
>     writeln("works");
> }
>
> void main() {
>     foo(1.0, 2.0);
> }

with type functions this syntax should work.