On Monday, 20 November 2023 at 13:25:48 UTC, Paul Backus wrote:
On Monday, 20 November 2023 at 08:47:34 UTC, Antonio wrote:
- What is the way to do ```writeln``` work with ```Counter``` function the same way it works with ```next``` function?

`writeln(&Counter)` should do it.

It does not do the same: It shows an address, not the function signature.

Because I need to understand "why", I propose a second example (with some additional info based on @evilrat proposals :-) ):

```d
import std.stdio;

void main()
{
auto createCounter = (int nextValue) => (int dummy) => nextValue++;
  auto getNext = createCounter(10);

  writeln( "'getNext' is ", getNext );
  writeln( "'createCounter' is ", createCounter );

writeln( "'typeof(getNext).stringof' is ", typeof(getNext).stringof ); writeln( "'typeof(createCounter).string' is ", typeof(createCounter).stringof );
}
```

The output is

```
'next' is int delegate(int) pure nothrow @nogc @safe
'createCounter' is 557FFCC00968
'typeof(getNext).stringof' is int delegate(int dummy) pure nothrow @nogc @safe 'typeof(createCounter).string' is int delegate(int dummy) pure nothrow @nogc @safe function(int nextValue) pure nothrow @safe
 ```


**Why ```writeln``` doesn't treat the same way ```getNext``` and ```createCounter```?**

Because ```getNext``` is a delegate and ```createCounter``` is a function.

**Why this is a function and not a delegate?**

```auto createCounter = (int nextValue) => (int dummy) => nextValue++;```

Syntactically I dont see any difference:

```auto name = "expression returning a delegate"```

The reason is **D compiler takes the decision**.

If you make ```createCounter``` to depend on an external variable, it will be treated as delegate (because it has context information associated to the function: a closure)

```d
import std.stdio;

void main()
{
  int diff = 1;
auto createCounter = (int nextValue) => () { scope(exit) nextValue+=diff; return nextValue;}; writeln( "'typeof(createCounter).string' is ", typeof(createCounter).stringof );
}
```

Will output that createCounter is a delegate:

```
'typeof(createCounter).string' is int delegate() pure nothrow @nogc @safe delegate(int nextValue) pure nothrow @safe
```


What "breaks" my mind is that a compiler decision (treat a piece of code as function or delegate) is not completely transparent causing "side" effects on your code (writeln doesn't work the same way: it shows the delegate signature, but not the function signature).

But the decision of the compiler is predictable and you can argue different effects are not side effects: only something you should pay attention to.

**This long and winding road toke me to a third and crazzy question**

Is there any way to force D compiler to treat this "createCounter" declaration as **delegate** instead of **function**?

```d
  auto createCounter = (int nextValue) => () => nextValue++;
```




Reply via email to