What is :-) ?

Antonio antoniocabreraperez at gmail.com
Mon Nov 20 16:09:33 UTC 2023


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++;
```






More information about the Digitalmars-d-learn mailing list