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