www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - lambdas with types

reply jmh530 <john.michael.hall gmail.com> writes:
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);
}
Nov 20 2020
next sibling parent reply Paul Backus <snarwin gmail.com> writes:
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
Nov 20 2020
next sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
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.
Nov 20 2020
parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
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
Nov 20 2020
parent Adam D. Ruppe <destructionator gmail.com> writes:
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...)
Nov 20 2020
prev sibling parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
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.
Nov 20 2020
parent jmh530 <john.michael.hall gmail.com> writes:
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.
Nov 20 2020
prev sibling parent Stefan Koch <uplink.coder googlemail.com> writes:
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.
Nov 21 2020