www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Is there a plan to add support for closures in CTFE?

reply Andrey Zherikov <andrey.zherikov gmail.com> writes:
I want to do string processing pipeline is a way that one 
delegate calls another one and so on. This works perfectly except 
the case when I want to get a result at compile time.
So I wonder is there a plan to add support for closures at 
compile time in foreseeable future?

Here is a simple example:
```d
string delegate(string) f1()
{
     return str => "f1 " ~ str;
}

string delegate(string) f2(string delegate(string) dg)
{
     return str => dg("f2 " ~ str);
}

string f3(string delegate(string) dg, string str)
{
     return dg("f3 " ~ str);
}

void main()
{
     import std.stdio;
     writeln(f1.f2.f3("text"));    // works perfectly

     enum s = f1.f2.f3("text");    // Error: closures are not yet 
supported in CTFE
}
```

Note: I'm not asking for workarounds (I know how to do that), I'm 
asking about the plan to fix this.
Aug 12 2022
next sibling parent reply Salih Dincer <salihdb hotmail.com> writes:
On Saturday, 13 August 2022 at 01:55:28 UTC, Andrey Zherikov 
wrote:
 [..] I wonder is there a plan to add support for closures at 
 compile time in foreseeable future?
The problem is on f2... That works: ```d enum s = f1.f3("text"); ``` SDB 79
Aug 12 2022
parent Salih Dincer <salihdb hotmail.com> writes:
On Saturday, 13 August 2022 at 06:30:13 UTC, Salih Dincer wrote:
 That works:
 ```d

     enum s = f1.f3("text");

 ```
Sorry for my quick reply. When I tried it with my own codes, I understood what you meant better; during compile time you want to take a delegate and give the delegate... ```d enum { f1 = "1: ", f2 = "2, ", f3 = "3, " } alias dstr = string delegate(string); auto fun1(dstr dg, string start) { return dg(f1 ~ start); } dstr fun2(dstr dg) { return str => dg(f2 ~ str); } dstr fun3() { return str => f3 ~ str; } auto funS(string s) { return f2 ~ s; } enum s = fun3.fun1("Start").funS; void main() { import std.stdio; s.writeln(": ", typeid(s)); fun3.fun2.fun1("Start").writeln; writeln(fun1(fun2(fun3()), "Start")); } /* Prints: 2, 3, 1: Start: immutable(char)[] 3, 2, 1: Start 3, 2, 1: Start */ ``` SDB 79
Aug 13 2022
prev sibling parent Stefan Koch <uplink.coder googlemail.com> writes:
On Saturday, 13 August 2022 at 01:55:28 UTC, Andrey Zherikov 
wrote:
 I want to do string processing pipeline is a way that one 
 delegate calls another one and so on. This works perfectly 
 except the case when I want to get a result at compile time.
 So I wonder is there a plan to add support for closures at 
 compile time in foreseeable future?
 [ ... ]

 Note: I'm not asking for workarounds (I know how to do that), 
 I'm asking about the plan to fix this.
I am not clued in the official position on this, but I can tell you that it is not a trivial fix. Due to the design of the interpreter at the moment. That said it is also not impossible to do. What one would have to do is to allocate a pointer on the ctfe-entry and fill it with a closure chain once a closure is created. when you then encounter the a usage of a closure variable you look up the frame in the closure chain and use the values from there. It might be that I am missing something but that should be the basic flow of action. I remember looking at that issue years ago but at the time I lacked the experience to fix it, and I was also focusing on the newCTFE interpreter. Cheers, Stefan
Aug 16 2022